mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
1285 Commits
v4.1.0
...
v6.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3346437be | ||
|
|
6de6d7f6c0 | ||
|
|
eb15be06e3 | ||
|
|
7748decc60 | ||
|
|
d75750ab01 | ||
|
|
152781226e | ||
|
|
7e3bbb6ace | ||
|
|
3c3eb2f65d | ||
|
|
5a83d9e64d | ||
|
|
97bec607fe | ||
|
|
b56ca98b72 | ||
|
|
eeccdc2d5c | ||
|
|
47827ed45c | ||
|
|
d3f7bdd0b3 | ||
|
|
438c50bf14 | ||
|
|
33d860bcea | ||
|
|
2401a2afe9 | ||
|
|
852f0be0b2 | ||
|
|
18ec438eaf | ||
|
|
f7042c8d1b | ||
|
|
bc73f93e6c | ||
|
|
7091508678 | ||
|
|
6d9d66b88a | ||
|
|
fc35b0f1be | ||
|
|
17f86b1223 | ||
|
|
271531f5ff | ||
|
|
9ef83cd8a0 | ||
|
|
f33517dfa7 | ||
|
|
c69f5d9366 | ||
|
|
7902c3ced4 | ||
|
|
21f033474d | ||
|
|
549ac1ed48 | ||
|
|
2dd8d1f150 | ||
|
|
26ee461c32 | ||
|
|
9905a4c328 | ||
|
|
09a22143d6 | ||
|
|
81e8f5c6c2 | ||
|
|
3c322b7349 | ||
|
|
b2ea1bc517 | ||
|
|
16250493b8 | ||
|
|
08887e016c | ||
|
|
aadcce0907 | ||
|
|
9b5353309d | ||
|
|
76303502a6 | ||
|
|
cf07904338 | ||
|
|
8f1e28b59c | ||
|
|
10d0268070 | ||
|
|
7871e18232 | ||
|
|
ceb3792f3c | ||
|
|
65a4bdd87a | ||
|
|
7094870a44 | ||
|
|
cee99b5f2d | ||
|
|
ac86d362ba | ||
|
|
2233a9eb5a | ||
|
|
af24a4f364 | ||
|
|
a78692f5b8 | ||
|
|
335178098d | ||
|
|
ddc0e8f7ba | ||
|
|
80fa2449a1 | ||
|
|
476abafefe | ||
|
|
f7d4d51261 | ||
|
|
7b08510075 | ||
|
|
14b62b28ce | ||
|
|
1c44ed0912 | ||
|
|
de1edf3f4d | ||
|
|
a21ffa027a | ||
|
|
899d42563c | ||
|
|
6eecbb5edd | ||
|
|
6a8e7a10ea | ||
|
|
85bb488732 | ||
|
|
c957215854 | ||
|
|
2ba3a26785 | ||
|
|
f0dc3bc79f | ||
|
|
28d3edcd92 | ||
|
|
8026dee591 | ||
|
|
197cda9e45 | ||
|
|
903fd4e5e9 | ||
|
|
621c86b4cf | ||
|
|
deda7c700f | ||
|
|
d225304370 | ||
|
|
fd22b7ec2a | ||
|
|
a2b1d394b5 | ||
|
|
7d4c78e73e | ||
|
|
b37ff2b822 | ||
|
|
5887f5aa4f | ||
|
|
a9176a2ac8 | ||
|
|
6ceb431942 | ||
|
|
508d131c95 | ||
|
|
ae36659f7a | ||
|
|
f970660766 | ||
|
|
43c5837cda | ||
|
|
a87e88df20 | ||
|
|
5a5d4b06b3 | ||
|
|
28ba88ba70 | ||
|
|
4f8ffe934e | ||
|
|
c5c0a7abc5 | ||
|
|
84b762f0b3 | ||
|
|
043838f9b6 | ||
|
|
a824e92628 | ||
|
|
1843411e79 | ||
|
|
da76c4d7c5 | ||
|
|
4468b86a81 | ||
|
|
8acbb9a3ad | ||
|
|
f5e28bc999 | ||
|
|
b45ad7f74e | ||
|
|
9e9238454e | ||
|
|
3f2aba69ee | ||
|
|
371e804c6b | ||
|
|
6131e89aa9 | ||
|
|
c54b67300e | ||
|
|
e847f048d7 | ||
|
|
b5955fa663 | ||
|
|
a648e6c06d | ||
|
|
e6216da031 | ||
|
|
5b7bd56367 | ||
|
|
01b1c0ca8b | ||
|
|
05ced19f9f | ||
|
|
b8ef669905 | ||
|
|
212ce1840f | ||
|
|
e090fa94d0 | ||
|
|
a431f1a663 | ||
|
|
ea6815c0f7 | ||
|
|
40e05eef23 | ||
|
|
a790e702f5 | ||
|
|
be16a195fb | ||
|
|
2f10c0fd6d | ||
|
|
276c07d3d7 | ||
|
|
57f7c8b6b9 | ||
|
|
2ce22ba0e9 | ||
|
|
7186c62a27 | ||
|
|
bf88a13f1e | ||
|
|
6e9c540baf | ||
|
|
24b14d55ef | ||
|
|
3b8eb6c061 | ||
|
|
f9b7f6389e | ||
|
|
8f30faacf8 | ||
|
|
f631890237 | ||
|
|
8982889a8d | ||
|
|
cd3539aaf8 | ||
|
|
275e277721 | ||
|
|
283b1241d5 | ||
|
|
7bdea26085 | ||
|
|
f1fa589779 | ||
|
|
7226ad1eba | ||
|
|
d92743f0f3 | ||
|
|
2c309efef4 | ||
|
|
0b418315a3 | ||
|
|
2f474867c7 | ||
|
|
0b5acd9569 | ||
|
|
3419c3c730 | ||
|
|
754200f1b1 | ||
|
|
37f4bd4dd0 | ||
|
|
ab009bba26 | ||
|
|
1249c6ebf4 | ||
|
|
eb9c4e3643 | ||
|
|
344197083e | ||
|
|
0749dc4cc1 | ||
|
|
841e31b7e6 | ||
|
|
ea6641afe5 | ||
|
|
11ac6800cc | ||
|
|
5e7c828c9e | ||
|
|
3c2ff97a16 | ||
|
|
f1ee35e281 | ||
|
|
829050daab | ||
|
|
81bf15877f | ||
|
|
1478bd36fd | ||
|
|
fdaa75354a | ||
|
|
f901170a4f | ||
|
|
33fd20047c | ||
|
|
78411db4b5 | ||
|
|
9c3315c416 | ||
|
|
b7b9efa875 | ||
|
|
be6fb7cb12 | ||
|
|
b3d8db6996 | ||
|
|
a7e22c78cf | ||
|
|
3bf71a363a | ||
|
|
82a076855b | ||
|
|
258d337cf8 | ||
|
|
748632d655 | ||
|
|
e7c48922e7 | ||
|
|
235eea6669 | ||
|
|
2b9bd0f56f | ||
|
|
c4020308c9 | ||
|
|
9c3cb55ef2 | ||
|
|
11699d8611 | ||
|
|
ac30185a04 | ||
|
|
77d59e99b6 | ||
|
|
127b87c713 | ||
|
|
5d45b59f7f | ||
|
|
cd8402fc9f | ||
|
|
a65f242dbd | ||
|
|
8c8eac88a4 | ||
|
|
59e3164206 | ||
|
|
76d584c81d | ||
|
|
dc4fe537ee | ||
|
|
53f6cbccbf | ||
|
|
63d6be0480 | ||
|
|
d1a7b42906 | ||
|
|
2fda0bdc89 | ||
|
|
a34c47b542 | ||
|
|
fe06784a3b | ||
|
|
7e9a271852 | ||
|
|
e352d735f6 | ||
|
|
43dc4e8a13 | ||
|
|
0fd0b3fb4b | ||
|
|
30448bb1b8 | ||
|
|
515c927b14 | ||
|
|
b965abfda8 | ||
|
|
90a738a4d4 | ||
|
|
ab66c4b7f9 | ||
|
|
04a8b9fe5c | ||
|
|
b429e6e2df | ||
|
|
126639875d | ||
|
|
158e41e578 | ||
|
|
7382c519c9 | ||
|
|
866cbb0147 | ||
|
|
7467e91880 | ||
|
|
74ac80e218 | ||
|
|
ab92cfd174 | ||
|
|
f95de3d6f3 | ||
|
|
2bf740d2fe | ||
|
|
406ceaabd1 | ||
|
|
50b9933705 | ||
|
|
e44b5263a1 | ||
|
|
47d5f9f901 | ||
|
|
9819433e88 | ||
|
|
e2f0852c30 | ||
|
|
9cc4cb2934 | ||
|
|
2dc422234a | ||
|
|
0f990c3bdd | ||
|
|
7116c108d7 | ||
|
|
5b696491db | ||
|
|
57dd192dcd | ||
|
|
0431997c8d | ||
|
|
d412582f72 | ||
|
|
d50e8a5c4c | ||
|
|
66473e19cb | ||
|
|
8ea33d69ac | ||
|
|
7c6cedb119 | ||
|
|
eb27e9b055 | ||
|
|
75442b794f | ||
|
|
d597a0e8b0 | ||
|
|
b8dbe4bc15 | ||
|
|
5045b0a962 | ||
|
|
953d1ea635 | ||
|
|
32c9597cbc | ||
|
|
808783a5e4 | ||
|
|
69d4c91895 | ||
|
|
7a47e64e65 | ||
|
|
3475cd168e | ||
|
|
7eaa57b116 | ||
|
|
8cf15cc931 | ||
|
|
3d307e5610 | ||
|
|
f4434763fe | ||
|
|
2188a6ea99 | ||
|
|
4e57a732a8 | ||
|
|
ec5e0ef06e | ||
|
|
75b4db60cf | ||
|
|
34eb5d0815 | ||
|
|
336db33d18 | ||
|
|
546466b209 | ||
|
|
9e26dfaa06 | ||
|
|
cbd884060e | ||
|
|
95df531b33 | ||
|
|
6c20c6e668 | ||
|
|
4ec2f8b67b | ||
|
|
a5febe392c | ||
|
|
49f13e38f9 | ||
|
|
d2ad8efef4 | ||
|
|
a16dc13f85 | ||
|
|
784f9742bc | ||
|
|
6555be2636 | ||
|
|
07b02653ba | ||
|
|
b25279df89 | ||
|
|
b140a82fe8 | ||
|
|
a82bbd010e | ||
|
|
1c7b3026a6 | ||
|
|
45d90e77b7 | ||
|
|
de1bacddd9 | ||
|
|
671533f7d2 | ||
|
|
1571461bae | ||
|
|
1d93bc76cd | ||
|
|
4c51fa93f5 | ||
|
|
4d8e024b6d | ||
|
|
9b359c6a75 | ||
|
|
7389dfca59 | ||
|
|
06a4594435 | ||
|
|
f4c3151815 | ||
|
|
ddd51525f1 | ||
|
|
879462af4b | ||
|
|
53f4af7722 | ||
|
|
2fb9085e5b | ||
|
|
38d75010c7 | ||
|
|
5025c991ee | ||
|
|
db29978fe0 | ||
|
|
f09f43a4a9 | ||
|
|
108545e416 | ||
|
|
3a091cdea4 | ||
|
|
b502c62111 | ||
|
|
984e77e470 | ||
|
|
43ef561d48 | ||
|
|
4b6b59cc82 | ||
|
|
961c9a88a8 | ||
|
|
6b326f7924 | ||
|
|
f15d0b1ed7 | ||
|
|
df57ac4ce7 | ||
|
|
cb4ede453f | ||
|
|
be60f93bd0 | ||
|
|
12b6a0f5b2 | ||
|
|
46e5767527 | ||
|
|
259bc3a918 | ||
|
|
a55d1ef305 | ||
|
|
6b65e3523e | ||
|
|
b967ae4c51 | ||
|
|
2023e32130 | ||
|
|
3656d12cba | ||
|
|
ca701bb9af | ||
|
|
2e89348541 | ||
|
|
878538f2e8 | ||
|
|
aa8b66aae1 | ||
|
|
c082b3964c | ||
|
|
d9234798d3 | ||
|
|
3e5a98b5f4 | ||
|
|
faabd0cc8b | ||
|
|
df7dc9396e | ||
|
|
90fcc574f4 | ||
|
|
86291236a0 | ||
|
|
14cc8a1808 | ||
|
|
5eb75e91b9 | ||
|
|
8991c0056e | ||
|
|
ea6a926494 | ||
|
|
48a95f9677 | ||
|
|
e77d065875 | ||
|
|
f943db7ad5 | ||
|
|
6072da239d | ||
|
|
a8698d092b | ||
|
|
188d31132b | ||
|
|
c7a453226d | ||
|
|
b43e4b8e0e | ||
|
|
a958eb9c44 | ||
|
|
7343a2f232 | ||
|
|
40af881844 | ||
|
|
a968f4f999 | ||
|
|
9ea6c01e02 | ||
|
|
58a9a81895 | ||
|
|
4728cebd9e | ||
|
|
699ef08e84 | ||
|
|
5c42f57197 | ||
|
|
8ee153dae1 | ||
|
|
b7fc50b7ca | ||
|
|
e185057ef9 | ||
|
|
a46b8efc8a | ||
|
|
d548c8c692 | ||
|
|
457ff0687c | ||
|
|
bf6fea3b59 | ||
|
|
0d534b3c52 | ||
|
|
47b92b6413 | ||
|
|
9c76ce38e3 | ||
|
|
2840e45920 | ||
|
|
38304be688 | ||
|
|
990ba15157 | ||
|
|
69bf9aa605 | ||
|
|
8043e2e278 | ||
|
|
e8f6f31fe4 | ||
|
|
0243b0ffc1 | ||
|
|
fb9d1bd83c | ||
|
|
c735116cc3 | ||
|
|
457abecad6 | ||
|
|
bfe876afcd | ||
|
|
3f4f774838 | ||
|
|
66128a7152 | ||
|
|
0bae707995 | ||
|
|
7245546274 | ||
|
|
1650ca3699 | ||
|
|
36abc0e547 | ||
|
|
ffc32d8130 | ||
|
|
43f909a9a3 | ||
|
|
8f15dc4ff9 | ||
|
|
38c3891337 | ||
|
|
d47ed72d17 | ||
|
|
014654e794 | ||
|
|
d04d11cfb5 | ||
|
|
03f9d40635 | ||
|
|
527e8f3a31 | ||
|
|
49f414b439 | ||
|
|
43361164e8 | ||
|
|
ccd4a3c80c | ||
|
|
a7e2856bf0 | ||
|
|
ac609a3d78 | ||
|
|
611b36719b | ||
|
|
59cb0ac32e | ||
|
|
6f14df039e | ||
|
|
4450c26206 | ||
|
|
7270a08f9c | ||
|
|
b99ff3448e | ||
|
|
00aeb8e5c5 | ||
|
|
59703c60ac | ||
|
|
04ad579e8f | ||
|
|
a3deae4491 | ||
|
|
9bc3888378 | ||
|
|
c13bf5692a | ||
|
|
fc10620082 | ||
|
|
652e232813 | ||
|
|
890f38e8fa | ||
|
|
2769e75b49 | ||
|
|
34fb6c2f35 | ||
|
|
5afb7dc715 | ||
|
|
e5e6aa207c | ||
|
|
9d8619f305 | ||
|
|
bbfa63fd9d | ||
|
|
d34f81972d | ||
|
|
17dab8f239 | ||
|
|
a4418a9014 | ||
|
|
61fc95417b | ||
|
|
2be62b1c33 | ||
|
|
42b7b25ac3 | ||
|
|
825e526456 | ||
|
|
ca2c345997 | ||
|
|
5791a2a9ec | ||
|
|
ac88b3ead5 | ||
|
|
f3fc4023cf | ||
|
|
8c6bf9c848 | ||
|
|
bb88a07a94 | ||
|
|
8ec304f32f | ||
|
|
5581990d78 | ||
|
|
8c4d6438de | ||
|
|
229934ec66 | ||
|
|
ab785e73ac | ||
|
|
d4d6b9862f | ||
|
|
b575631bb0 | ||
|
|
5422fd9941 | ||
|
|
2733697819 | ||
|
|
6cb7b8d3a4 | ||
|
|
92c9dbc179 | ||
|
|
5a88d9e6fc | ||
|
|
aa863f3246 | ||
|
|
e05985145b | ||
|
|
7936237677 | ||
|
|
ed31cfebc9 | ||
|
|
8dcb5662e3 | ||
|
|
f4169f3491 | ||
|
|
bbd1ae315a | ||
|
|
2adbc7836b | ||
|
|
59a7fa6927 | ||
|
|
676c02611d | ||
|
|
67f04c0370 | ||
|
|
544d8a423c | ||
|
|
6d55498cc7 | ||
|
|
64078324bf | ||
|
|
bfa07ec4be | ||
|
|
29ab74688d | ||
|
|
d4cfaaf047 | ||
|
|
5da89c3a2b | ||
|
|
e01c3615c4 | ||
|
|
1bbb47be5b | ||
|
|
a07cb2afd7 | ||
|
|
4e25dc3c3c | ||
|
|
5ecda17c7a | ||
|
|
08066581b0 | ||
|
|
42aa375497 | ||
|
|
5a99ea4c46 | ||
|
|
848d16525f | ||
|
|
7c78f11b82 | ||
|
|
28899c3885 | ||
|
|
be8f9bd597 | ||
|
|
d9c7735a04 | ||
|
|
7a7389ab1c | ||
|
|
30213089ae | ||
|
|
391f6dd663 | ||
|
|
7f007109c3 | ||
|
|
ddcebb096f | ||
|
|
6da939629b | ||
|
|
5e762d6a47 | ||
|
|
df5305d6a7 | ||
|
|
1674388028 | ||
|
|
944cdb4430 | ||
|
|
28b150f6dc | ||
|
|
5be93566ee | ||
|
|
32a4de4a68 | ||
|
|
a40d826b11 | ||
|
|
08f7d60da4 | ||
|
|
3edc497d3d | ||
|
|
cc5ed24e23 | ||
|
|
0a730e61f5 | ||
|
|
91f81b4b72 | ||
|
|
2223114f20 | ||
|
|
7e7abc28f5 | ||
|
|
3b74837020 | ||
|
|
ef2e7d95fe | ||
|
|
a04d9ef35b | ||
|
|
eaa0e28396 | ||
|
|
35c3a7e130 | ||
|
|
596acdcb91 | ||
|
|
6b3ff4f1f7 | ||
|
|
0a84c61074 | ||
|
|
71366e2a0d | ||
|
|
1e8ac79e6f | ||
|
|
31ff160431 | ||
|
|
6d005ff137 | ||
|
|
975a035d34 | ||
|
|
2498e8d1c2 | ||
|
|
5790869a3f | ||
|
|
4ccd6d5900 | ||
|
|
28638b0a6b | ||
|
|
5904544235 | ||
|
|
46a49b74a6 | ||
|
|
b927be9982 | ||
|
|
95386ef56f | ||
|
|
1d9170f1bb | ||
|
|
b6f7157910 | ||
|
|
2556d86c8a | ||
|
|
d7fea1b484 | ||
|
|
2ccf5904e0 | ||
|
|
d7557cb66a | ||
|
|
cece8bce0b | ||
|
|
66db627913 | ||
|
|
76fde58e27 | ||
|
|
8a51c9c2f6 | ||
|
|
e11589b5be | ||
|
|
3727982217 | ||
|
|
70bbbb84bb | ||
|
|
34d7e019ce | ||
|
|
a9ab4c5039 | ||
|
|
005b7d8099 | ||
|
|
510ca79ddd | ||
|
|
0545d47ca7 | ||
|
|
86a94126fb | ||
|
|
035eee5c03 | ||
|
|
1b982e200a | ||
|
|
10850808e9 | ||
|
|
c2be0846c2 | ||
|
|
1d21e9c35d | ||
|
|
315f8c0cc7 | ||
|
|
9b82e7d27b | ||
|
|
61c46c6313 | ||
|
|
e4cfc52c29 | ||
|
|
3898a44e88 | ||
|
|
547add94d0 | ||
|
|
dd4a31633f | ||
|
|
52ef6d9ae4 | ||
|
|
0e39ec688a | ||
|
|
606c84b302 | ||
|
|
2c282203b5 | ||
|
|
1c4241bff5 | ||
|
|
b2bd9ffd70 | ||
|
|
e1502f6953 | ||
|
|
abec938b0a | ||
|
|
a913e396d5 | ||
|
|
79040e348a | ||
|
|
9439ac108d | ||
|
|
a864167d46 | ||
|
|
92cfc4a62d | ||
|
|
f09cb56f19 | ||
|
|
fbefab4227 | ||
|
|
e517139e3c | ||
|
|
3f75724a31 | ||
|
|
2752ae4ae8 | ||
|
|
e769b867f0 | ||
|
|
de27911661 | ||
|
|
6e7dca9082 | ||
|
|
84ef9cae6c | ||
|
|
8497bb1327 | ||
|
|
31494dfade | ||
|
|
6cd75744ef | ||
|
|
2492f0bcac | ||
|
|
9112ad01be | ||
|
|
46a24c82ff | ||
|
|
228805353f | ||
|
|
319c2853df | ||
|
|
95214fcd4b | ||
|
|
fed5b99a9f | ||
|
|
9b29befdc8 | ||
|
|
3dfef4a376 | ||
|
|
1f458eb177 | ||
|
|
ee4c9aa3d0 | ||
|
|
8f6a543398 | ||
|
|
46f818b0c3 | ||
|
|
c363eed543 | ||
|
|
6385608f7f | ||
|
|
1ed7b1c76d | ||
|
|
8d09219533 | ||
|
|
ca83d36426 | ||
|
|
cd9bf72ee8 | ||
|
|
cfba59929a | ||
|
|
5478cc7e8e | ||
|
|
98b05b8428 | ||
|
|
bf276ecc69 | ||
|
|
5a44cc50cf | ||
|
|
01c442de64 | ||
|
|
cfbdc40814 | ||
|
|
83894dc5db | ||
|
|
deb36d5008 | ||
|
|
8141a26ba9 | ||
|
|
9deaacb454 | ||
|
|
6a47089c78 | ||
|
|
7baa218ca9 | ||
|
|
c92233cbc8 | ||
|
|
20d9f4b2b5 | ||
|
|
dc0be294dd | ||
|
|
9dd3338ede | ||
|
|
d8ba1278d1 | ||
|
|
a3cdf46fb6 | ||
|
|
5301808926 | ||
|
|
ccc60a1f33 | ||
|
|
36ce3e9546 | ||
|
|
3effa6f20c | ||
|
|
d57b9cb47f | ||
|
|
90ebd8eb12 | ||
|
|
c77e187742 | ||
|
|
7a3d220347 | ||
|
|
1898f91620 | ||
|
|
d16b581140 | ||
|
|
3f52e18a38 | ||
|
|
70042d2597 | ||
|
|
72f3a22ecc | ||
|
|
c80c3c18dc | ||
|
|
10607f7e86 | ||
|
|
ccf46a57bc | ||
|
|
062778c031 | ||
|
|
833daaa2b2 | ||
|
|
1632c4b837 | ||
|
|
b97f6bd7d4 | ||
|
|
23b84917e0 | ||
|
|
e790dbd737 | ||
|
|
c8282efb75 | ||
|
|
27bd47a333 | ||
|
|
db11b9b13b | ||
|
|
4989ecc5e0 | ||
|
|
9ebba76c03 | ||
|
|
4f8ebafa97 | ||
|
|
29501dbd01 | ||
|
|
acabf6f5ab | ||
|
|
c6fc5a23fc | ||
|
|
c8a1231ad7 | ||
|
|
6d68026c6c | ||
|
|
2d1438456b | ||
|
|
dd5264b4d1 | ||
|
|
e8608c2dbd | ||
|
|
a569dad8c5 | ||
|
|
17c240a639 | ||
|
|
fc06458038 | ||
|
|
84eef16755 | ||
|
|
c76459738e | ||
|
|
76d919fff5 | ||
|
|
26df9992cf | ||
|
|
858781ba83 | ||
|
|
4211a9c69f | ||
|
|
b7d8234a86 | ||
|
|
d53b51607c | ||
|
|
ff461d9d26 | ||
|
|
b7afec0743 | ||
|
|
8946cfd4f1 | ||
|
|
793d6c3691 | ||
|
|
b29e8d18a8 | ||
|
|
6d674eebb1 | ||
|
|
c486ab207a | ||
|
|
b202ad1e24 | ||
|
|
8582325e85 | ||
|
|
9b7eb0eecb | ||
|
|
e098d08728 | ||
|
|
f303caa87c | ||
|
|
3aa8ec0818 | ||
|
|
758d709c7a | ||
|
|
698d348168 | ||
|
|
f142aae9eb | ||
|
|
a9991f5451 | ||
|
|
af64140100 | ||
|
|
cacb56b103 | ||
|
|
24f1eac84f | ||
|
|
0a047194b6 | ||
|
|
7dc565fc2e | ||
|
|
392458b252 | ||
|
|
efe52f66e4 | ||
|
|
52952f7d51 | ||
|
|
bae09643c1 | ||
|
|
31c7ed9b8c | ||
|
|
ab503c7e43 | ||
|
|
c8c1be7ae5 | ||
|
|
2f35c98e76 | ||
|
|
d71f1fb30c | ||
|
|
6c77c220f7 | ||
|
|
76dcbcd6ea | ||
|
|
ba57e1d991 | ||
|
|
cbb5164cc8 | ||
|
|
49ec7e1582 | ||
|
|
927aac306f | ||
|
|
bd4e14dcee | ||
|
|
641b47f384 | ||
|
|
9ed89ace97 | ||
|
|
c7677b23e6 | ||
|
|
6e131f2121 | ||
|
|
dfcee48f81 | ||
|
|
56c6a51cd2 | ||
|
|
8af532ba98 | ||
|
|
8da91523d0 | ||
|
|
323b688ab8 | ||
|
|
940c4c0787 | ||
|
|
257de6a963 | ||
|
|
fa5442f211 | ||
|
|
a25f82c91f | ||
|
|
138ba53511 | ||
|
|
d105dcc0d3 | ||
|
|
5a35c3a279 | ||
|
|
63bf370cc0 | ||
|
|
8396a2d504 | ||
|
|
e2516dc808 | ||
|
|
74c29fb610 | ||
|
|
b66b5561ee | ||
|
|
713df08e3e | ||
|
|
fef262f829 | ||
|
|
e6952e2a16 | ||
|
|
1db4dd68a7 | ||
|
|
90151879cc | ||
|
|
f431ce4971 | ||
|
|
ad3ea6ec53 | ||
|
|
cc90919384 | ||
|
|
0a5adfe365 | ||
|
|
fd8b9450ee | ||
|
|
34ac68c4a8 | ||
|
|
f3e30c7ae3 | ||
|
|
0b85fb7ea2 | ||
|
|
58a6fe13d6 | ||
|
|
92b9525cfd | ||
|
|
1918e76913 | ||
|
|
ff9b23ebe5 | ||
|
|
c0f6a44e39 | ||
|
|
3828e2a53a | ||
|
|
be69192a61 | ||
|
|
8c1b5311fd | ||
|
|
6d4480ea6b | ||
|
|
1fe4b3fa28 | ||
|
|
f115376595 | ||
|
|
8122dd2c33 | ||
|
|
d2c0f9f754 | ||
|
|
03d499bf34 | ||
|
|
5e043812ef | ||
|
|
7764ca7209 | ||
|
|
ded316cd5e | ||
|
|
4b45a5fc6d | ||
|
|
078d518e36 | ||
|
|
212d858bf4 | ||
|
|
3faf2480e0 | ||
|
|
55d5b02f87 | ||
|
|
8fa33ba120 | ||
|
|
826f1cb90c | ||
|
|
ed5a865efb | ||
|
|
90b6d13714 | ||
|
|
85333a5974 | ||
|
|
5f941c5180 | ||
|
|
06a5ade3c6 | ||
|
|
374406375b | ||
|
|
4089620729 | ||
|
|
1de0152b6b | ||
|
|
94246d428b | ||
|
|
3b88dd6ef7 | ||
|
|
2cbf3080d0 | ||
|
|
d0621db8fd | ||
|
|
6f9ff39728 | ||
|
|
a64cf5514f | ||
|
|
93fbb6c092 | ||
|
|
600c3f2c2f | ||
|
|
deff96a1b0 | ||
|
|
b03daaebe4 | ||
|
|
4ddd337a64 | ||
|
|
a64a0fa88e | ||
|
|
c0cf065c1a | ||
|
|
96b2623887 | ||
|
|
e0d277e667 | ||
|
|
485bbd9ccb | ||
|
|
d228bdfb9e | ||
|
|
70887ae21a | ||
|
|
96f9611cf4 | ||
|
|
ef80cc3d56 | ||
|
|
0d9de7deaf | ||
|
|
96ca070c3a | ||
|
|
8948e27ced | ||
|
|
30e5e993c1 | ||
|
|
fd7b49b32b | ||
|
|
d36a6de25c | ||
|
|
d01db5a656 | ||
|
|
7d5cd2051a | ||
|
|
95ed3238be | ||
|
|
02e41b41b2 | ||
|
|
cd25ddeb06 | ||
|
|
7df531bc4e | ||
|
|
6cba2c50a2 | ||
|
|
dbc5f67dca | ||
|
|
7d71ad6f91 | ||
|
|
0e27f133d7 | ||
|
|
b965e54efc | ||
|
|
a9ac75c1f9 | ||
|
|
033efdcaa1 | ||
|
|
51961fccfa | ||
|
|
ac65f38842 | ||
|
|
0b0679e065 | ||
|
|
3ca87d205f | ||
|
|
dacf7f8bdc | ||
|
|
2cca0f9bb7 | ||
|
|
441c9ce376 | ||
|
|
902c239fdf | ||
|
|
9e6726f304 | ||
|
|
329d45562b | ||
|
|
83b44b735f | ||
|
|
3417c42bfd | ||
|
|
7f4064af16 | ||
|
|
ace11f9bc8 | ||
|
|
cd91440e47 | ||
|
|
5e5c71e1d7 | ||
|
|
7d4a1223fd | ||
|
|
98d0daa2fd | ||
|
|
f105c84349 | ||
|
|
720197f9c8 | ||
|
|
4d0b2ac9be | ||
|
|
1f2b02c18f | ||
|
|
32d98851bc | ||
|
|
82fc099602 | ||
|
|
34c1727cb3 | ||
|
|
23d44e322d | ||
|
|
8e2ab8b20b | ||
|
|
05755ba202 | ||
|
|
0881fd6397 | ||
|
|
52e257668d | ||
|
|
df62e78b71 | ||
|
|
dcb670fa46 | ||
|
|
134792a594 | ||
|
|
71f542d8f6 | ||
|
|
52fe92d02e | ||
|
|
92ddfd0d4c | ||
|
|
c81c9ee2b4 | ||
|
|
fc169221be | ||
|
|
c43a61c576 | ||
|
|
c4e4f085dd | ||
|
|
088f936dab | ||
|
|
e2b1394ad1 | ||
|
|
3cb9aadb80 | ||
|
|
ca218b6395 | ||
|
|
52852b963a | ||
|
|
d0ae89befa | ||
|
|
2acf9ac72f | ||
|
|
102d8fe506 | ||
|
|
2ee59cc82c | ||
|
|
03e16ffa57 | ||
|
|
782825fc29 | ||
|
|
0299328521 | ||
|
|
eb02a422de | ||
|
|
72af4941f8 | ||
|
|
744f737cba | ||
|
|
f72d5a4184 | ||
|
|
17d2467932 | ||
|
|
241baf77f1 | ||
|
|
b4299a2872 | ||
|
|
45baaeaf2c | ||
|
|
1fd7a4bfab | ||
|
|
826063a2f7 | ||
|
|
349a3c20ae | ||
|
|
6436a12d7f | ||
|
|
000be5d1d4 | ||
|
|
434f1368a0 | ||
|
|
668049a593 | ||
|
|
5c250455ad | ||
|
|
791d6de8b0 | ||
|
|
a3e5173c47 | ||
|
|
b71a5a5955 | ||
|
|
30c670bd83 | ||
|
|
596c0a8672 | ||
|
|
2ac677228d | ||
|
|
ff1c90b638 | ||
|
|
90f23c187f | ||
|
|
854443a291 | ||
|
|
9c7f6affc2 | ||
|
|
fade3eb679 | ||
|
|
cdf4bfa68f | ||
|
|
f8614ab019 | ||
|
|
6f117b8e0c | ||
|
|
dee964e0fe | ||
|
|
5957ede41a | ||
|
|
959c7a76e9 | ||
|
|
a0cdcc5f8d | ||
|
|
9cc3fbabf7 | ||
|
|
3db691d693 | ||
|
|
c1ca8476f8 | ||
|
|
21d1849723 | ||
|
|
50010934d1 | ||
|
|
849dd0db64 | ||
|
|
de0e4735de | ||
|
|
2117524102 | ||
|
|
876064036d | ||
|
|
b57046e67d | ||
|
|
03892153de | ||
|
|
439ba5116f | ||
|
|
5c378de22f | ||
|
|
3f1d22759a | ||
|
|
baaeb7cece | ||
|
|
eb8dc6b675 | ||
|
|
a5e63dc5fd | ||
|
|
5ae3d1a1b2 | ||
|
|
18ca4b6a3a | ||
|
|
51cfb5cff1 | ||
|
|
4ff7976060 | ||
|
|
90d314cc3b | ||
|
|
547097b036 | ||
|
|
df0381e76c | ||
|
|
ddc38eda26 | ||
|
|
9c783f53ba | ||
|
|
ed3e5739dc | ||
|
|
cc85946f55 | ||
|
|
03f876470e | ||
|
|
5cc4a30207 | ||
|
|
a58d989b60 | ||
|
|
dc93d94bc8 | ||
|
|
6c998aa4f2 | ||
|
|
1c7a47239b | ||
|
|
7fc8afa3e5 | ||
|
|
7ec4e7b0d8 | ||
|
|
41a3f123f1 | ||
|
|
f6081b18b6 | ||
|
|
7a6fe00f49 | ||
|
|
c64b4a3926 | ||
|
|
0431833866 | ||
|
|
280f9bf49c | ||
|
|
c7aa747891 | ||
|
|
8584c2f14b | ||
|
|
dbda1a1b05 | ||
|
|
897c6e93cb | ||
|
|
d6d245d0c3 | ||
|
|
0e6db8fd56 | ||
|
|
649633bbb7 | ||
|
|
4250f84272 | ||
|
|
f7528a0204 | ||
|
|
c65a0d90b8 | ||
|
|
1152fecb75 | ||
|
|
48abef27d8 | ||
|
|
624ade2c25 | ||
|
|
f3c64ea9d8 | ||
|
|
e383aa31c8 | ||
|
|
607b53c883 | ||
|
|
e044ada65c | ||
|
|
c74ae107f1 | ||
|
|
45a937df0a | ||
|
|
163361ee6a | ||
|
|
4b18a38e9f | ||
|
|
db2fda1b6f | ||
|
|
eb8fcf833c | ||
|
|
177091ca6f | ||
|
|
442c1b22e3 | ||
|
|
1b8c11121f | ||
|
|
2845267c18 | ||
|
|
764a10f7c7 | ||
|
|
ab2a061b59 | ||
|
|
d243a45173 | ||
|
|
3f15f51615 | ||
|
|
cfbea4a0e3 | ||
|
|
d561c5531b | ||
|
|
d5d1fa8290 | ||
|
|
46e7214974 | ||
|
|
cfb2812cea | ||
|
|
8d1d842185 | ||
|
|
c31629ad98 | ||
|
|
aa2b2f7c8f | ||
|
|
0a23c0b032 | ||
|
|
5bc86eaf9c | ||
|
|
ca7dec2082 | ||
|
|
fc4e10b6c0 | ||
|
|
e80e3a53e9 | ||
|
|
1f55f1635f | ||
|
|
77f73830e8 | ||
|
|
d3c58ea48c | ||
|
|
a1a431eb87 | ||
|
|
3ddd917ff4 | ||
|
|
a33eeda4f7 | ||
|
|
8ec3bc0272 | ||
|
|
982649bab7 | ||
|
|
a7ee737226 | ||
|
|
e842482ec8 | ||
|
|
f00b0a3485 | ||
|
|
fe943f560b | ||
|
|
975f85ea56 | ||
|
|
e734536815 | ||
|
|
3dfc0098ec | ||
|
|
06a501d4a2 | ||
|
|
e1336d8453 | ||
|
|
f8418554a3 | ||
|
|
65b7924528 | ||
|
|
5017db855c | ||
|
|
c6313b3d2d | ||
|
|
4eb0d497ab | ||
|
|
2ebea5501e | ||
|
|
2d68d60e00 | ||
|
|
6deb7afb82 | ||
|
|
8727636fcc | ||
|
|
00294a5b25 | ||
|
|
c491fa59df | ||
|
|
d97cf8c438 | ||
|
|
7a68d632e6 | ||
|
|
28cff4644e | ||
|
|
9d72bd4de4 | ||
|
|
c1b9ca14e7 | ||
|
|
32a957c455 | ||
|
|
85fdacbc49 | ||
|
|
f8f091c250 | ||
|
|
c51fef1568 | ||
|
|
1523a82bab | ||
|
|
92f50664d0 | ||
|
|
5798b152a6 | ||
|
|
b1e69e1357 | ||
|
|
9c36576ddd | ||
|
|
f7f09b028b | ||
|
|
089001bd92 | ||
|
|
97aa7b8e68 | ||
|
|
366ca47136 | ||
|
|
d21e30f57b | ||
|
|
d1da0aad7f | ||
|
|
321f87fe61 | ||
|
|
6743b83786 | ||
|
|
f464b8c4c5 | ||
|
|
25d0a7b62a | ||
|
|
b5b49c9ed0 | ||
|
|
ffeab383b5 | ||
|
|
0bd006a8eb | ||
|
|
0f9dd3736c | ||
|
|
6310d6c699 | ||
|
|
b2d53f1e1e | ||
|
|
4179cedf37 | ||
|
|
66349261a5 | ||
|
|
c1f32afeeb | ||
|
|
8f1fa4177e | ||
|
|
535d264497 | ||
|
|
2eedcde914 | ||
|
|
6b4b7c9831 | ||
|
|
b6aae790cf | ||
|
|
74d1685523 | ||
|
|
c9007557e5 | ||
|
|
c4cb90ab85 | ||
|
|
0adbcfd806 | ||
|
|
fd442df851 | ||
|
|
f927398b53 | ||
|
|
6414cb05f0 | ||
|
|
3b4e706758 | ||
|
|
559fd5cb31 | ||
|
|
1672cffe96 | ||
|
|
b8ec886609 | ||
|
|
728be219a4 | ||
|
|
2e91bf1e15 | ||
|
|
515525cfc6 | ||
|
|
83d951db7e | ||
|
|
8483cb4aa7 | ||
|
|
8cca1c987b | ||
|
|
78b88a70bb | ||
|
|
165d168ee5 | ||
|
|
753fb31c54 | ||
|
|
62eb077f29 | ||
|
|
cd8099d336 | ||
|
|
30109d64f2 | ||
|
|
ae266e2e03 | ||
|
|
c366525370 | ||
|
|
8f04def7b2 | ||
|
|
55808dffcd | ||
|
|
07f8f5f95a | ||
|
|
d7d4b8638d | ||
|
|
9890d1e251 | ||
|
|
f563fc9d5e | ||
|
|
41c2685204 | ||
|
|
73fbb69c50 | ||
|
|
5f9c857eb0 | ||
|
|
5d54d42953 | ||
|
|
81e00d8e56 | ||
|
|
455f0669e7 | ||
|
|
5bb35bbdaf | ||
|
|
d63a848011 | ||
|
|
aafbd865bf | ||
|
|
63874da087 | ||
|
|
d1f0d6c184 | ||
|
|
9ff7807be8 | ||
|
|
23de301955 | ||
|
|
0a5f8611e8 | ||
|
|
6f116eeaa4 | ||
|
|
0242818f39 | ||
|
|
3748ee49ea | ||
|
|
a8a881c8db | ||
|
|
fb52fdc592 | ||
|
|
bb7c63c052 | ||
|
|
9e8b26cc4e | ||
|
|
5db8197a5d | ||
|
|
0b0a17ff91 | ||
|
|
a68e3371f3 | ||
|
|
47bf8e1bb3 | ||
|
|
65099ab489 | ||
|
|
40619efb3b | ||
|
|
f02f9ba9fb | ||
|
|
de05ff894b | ||
|
|
57d2ae1aec | ||
|
|
46c2953edb | ||
|
|
f2d3d55e95 | ||
|
|
a59b53c7e6 | ||
|
|
08b56b7675 | ||
|
|
90795c4fa4 | ||
|
|
90d1c0b2b6 | ||
|
|
ec4212cce1 | ||
|
|
a45d5960d7 | ||
|
|
51cb36fa9b | ||
|
|
b97d7e7ecd | ||
|
|
e12c0dcf66 | ||
|
|
4f45b72381 | ||
|
|
81843f0dfb | ||
|
|
20116d7f05 | ||
|
|
0642be296d | ||
|
|
c8860d006b | ||
|
|
b53a858400 | ||
|
|
511dc9a80b | ||
|
|
7e1168c518 | ||
|
|
57356036db | ||
|
|
666a106fa8 | ||
|
|
414dcfcd07 | ||
|
|
787dbbe610 | ||
|
|
bc9a7806a5 | ||
|
|
565e4c5910 | ||
|
|
8f35198bfb | ||
|
|
c06f023313 | ||
|
|
0c46a7a4d9 | ||
|
|
b21dbdb20d | ||
|
|
c9d0960f47 | ||
|
|
a54dd1085a | ||
|
|
1cf28e8b75 | ||
|
|
9fd98bb27b | ||
|
|
025aa49f67 | ||
|
|
5994bf6745 | ||
|
|
9e2b7dbea5 | ||
|
|
edf063bae3 | ||
|
|
e7b2b93cee | ||
|
|
82322968a3 | ||
|
|
53642b2b17 | ||
|
|
fb9cf86836 | ||
|
|
faf6c5ad29 | ||
|
|
4649d1c73b | ||
|
|
703cb6deea | ||
|
|
9aed2a465f | ||
|
|
746beb0d8b | ||
|
|
6162d9090d | ||
|
|
11223cbc9b | ||
|
|
7e0e12b8a3 | ||
|
|
ca2d74e118 | ||
|
|
673004b878 | ||
|
|
2a8e8a0603 | ||
|
|
4e53019b75 | ||
|
|
833269ffde | ||
|
|
e9ba26f50e | ||
|
|
20a540e680 | ||
|
|
bf3edf8f87 | ||
|
|
10969b8c3c | ||
|
|
c52cf01a3c | ||
|
|
1672c95de3 | ||
|
|
649f04b7bc | ||
|
|
934a7fc118 | ||
|
|
3a3b197327 | ||
|
|
ece4c81c1a | ||
|
|
dcd2bf451d | ||
|
|
87565ec667 | ||
|
|
2e1c50c891 | ||
|
|
77f69cbe08 | ||
|
|
c60745b8a3 | ||
|
|
32ea2b67f0 | ||
|
|
9b05381acc | ||
|
|
a19d20cfb8 | ||
|
|
c422011d58 | ||
|
|
1f5e0c42f3 | ||
|
|
6e6ab9b907 | ||
|
|
7f73240fd5 | ||
|
|
932ffdc1e1 | ||
|
|
fe8965efa2 | ||
|
|
bdef033459 | ||
|
|
6ed70327f5 | ||
|
|
e9fab747ec | ||
|
|
feb31d088b | ||
|
|
a8f2646ba6 | ||
|
|
b2e1a93177 | ||
|
|
86064a7bd8 | ||
|
|
6d2a088be9 | ||
|
|
aa6f7a5d9f | ||
|
|
1d81d1a706 | ||
|
|
e345209f91 | ||
|
|
29964079ae | ||
|
|
94f853c654 | ||
|
|
bae652f46d | ||
|
|
59ee2859a7 | ||
|
|
2bd94293e0 | ||
|
|
c93973ab7a | ||
|
|
894ae1b3f5 | ||
|
|
00daff6ac8 | ||
|
|
f921df7ad1 | ||
|
|
bea4de9262 | ||
|
|
7a03e5f0b2 | ||
|
|
405edebc51 | ||
|
|
d56617e5d0 | ||
|
|
ec4a0e096f | ||
|
|
d21d83cfc8 | ||
|
|
1f3a89197c | ||
|
|
2f3a8ecd42 | ||
|
|
7a23980f4b | ||
|
|
9086b8067b | ||
|
|
3b6f0d83e1 | ||
|
|
6fa940f2c1 | ||
|
|
335e9f68b7 | ||
|
|
4185efa08f | ||
|
|
8ba271efba | ||
|
|
1d8ab03146 | ||
|
|
1f246229b1 | ||
|
|
9474fc0082 | ||
|
|
af339f44f4 | ||
|
|
d03527ae47 | ||
|
|
40874ddec6 | ||
|
|
465dee2c33 | ||
|
|
869e0ab14d | ||
|
|
260778e0fb | ||
|
|
43a8b6039e | ||
|
|
ca4b4709e5 | ||
|
|
809bd3757b | ||
|
|
fbbb704146 | ||
|
|
a4fefbe836 | ||
|
|
5e199152e2 | ||
|
|
13247e592b | ||
|
|
044e43397f | ||
|
|
cb9be091aa | ||
|
|
e8e7edf017 | ||
|
|
9262731f2c | ||
|
|
ba7ce7225b | ||
|
|
939ee94e67 | ||
|
|
f9f34fd628 | ||
|
|
6d844a0b67 | ||
|
|
6f3c46cc7e | ||
|
|
122017e6fa | ||
|
|
16dcc464cf | ||
|
|
94aa0762f0 | ||
|
|
b3f134de06 | ||
|
|
363712d057 | ||
|
|
8bc0c343fa | ||
|
|
37f2113032 | ||
|
|
10db2bce4e | ||
|
|
c0db0011ec | ||
|
|
4de502252b | ||
|
|
a0b9d47d5e | ||
|
|
51f3fb9bde | ||
|
|
7cab7b6c7e | ||
|
|
993c2413e8 | ||
|
|
a9ca152069 | ||
|
|
4bbb70de74 | ||
|
|
db37ab1039 | ||
|
|
dffe4fdd4f | ||
|
|
ac6d815c0e | ||
|
|
af9cbb4514 | ||
|
|
04b7f0d2d6 | ||
|
|
65fa9d2883 | ||
|
|
508551b81b | ||
|
|
a369a4172b | ||
|
|
4d085c4aae | ||
|
|
d43ef97a7b | ||
|
|
de1d24b616 | ||
|
|
0252d7686c | ||
|
|
2a4f5c3284 | ||
|
|
af0ac9b95c | ||
|
|
90d6b91bf7 | ||
|
|
30ccb6aea5 | ||
|
|
0c711f690e | ||
|
|
89bf71e580 | ||
|
|
70c49b78ae | ||
|
|
d3efc52745 | ||
|
|
72db5ed7cb | ||
|
|
8907053a9d | ||
|
|
05b7c2bf80 | ||
|
|
047cad1a4d | ||
|
|
a82bcc7e3c | ||
|
|
c806c465fa | ||
|
|
6fc2a2a051 | ||
|
|
e61b88fc2a | ||
|
|
47b12eee57 | ||
|
|
783ee3e315 | ||
|
|
9e7bbcd8f6 | ||
|
|
d1b2d1a10e | ||
|
|
5ef5d60f77 | ||
|
|
95696c9456 | ||
|
|
5788600c46 | ||
|
|
ba9a55c391 | ||
|
|
d46834265f | ||
|
|
99f5f17a8d | ||
|
|
6c3d29712f | ||
|
|
ce26687577 |
File diff suppressed because it is too large
Load Diff
7
.circleci/fix-known-hosts.sh
Executable file
7
.circleci/fix-known-hosts.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
mkdir -p ~/.ssh
|
||||
echo "|1|B3r+7aO0/x90IdefihIjxIoJrrk=|OJddGDfhbuLFc1bUyy84hhIw57M= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
|
||||
|1|rGlEvW55DtzNZp+pzw9gvyOyKi4=|LLWr+7qlkAlw3YGGVfLHHxB/kR0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" >> ~/.ssh/known_hosts
|
||||
@@ -1,7 +1,7 @@
|
||||
# These env vars are only necessary for creating Electron releases.
|
||||
# See docs/development/releasing.md
|
||||
|
||||
APPVEYOR_TOKEN=
|
||||
APPVEYOR_CLOUD_TOKEN=
|
||||
CIRCLE_TOKEN=
|
||||
ELECTRON_GITHUB_TOKEN=
|
||||
VSTS_TOKEN=
|
||||
@@ -1,12 +1,34 @@
|
||||
{
|
||||
"extends": "standard",
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"rules": {
|
||||
"no-var": "error",
|
||||
"no-unused-vars": 0,
|
||||
"no-global-assign": 0,
|
||||
"@typescript-eslint/no-unused-vars": ["error", {
|
||||
"vars": "all",
|
||||
"args": "after-used",
|
||||
"ignoreRestSiblings": false
|
||||
}],
|
||||
"prefer-const": ["error", {
|
||||
"destructuring": "all"
|
||||
}]
|
||||
}
|
||||
}],
|
||||
"node/no-deprecated-api": 0
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.js",
|
||||
"rules": {
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
27
.github/CODEOWNERS
vendored
27
.github/CODEOWNERS
vendored
@@ -3,19 +3,18 @@
|
||||
# https://help.github.com/articles/about-codeowners
|
||||
# https://git-scm.com/docs/gitignore
|
||||
|
||||
# Everything that falls through the cracks:
|
||||
* @electron/reviewers
|
||||
# Most stuff in here is owned by the Community & Safety WG...
|
||||
/.github/* @electron/wg-community
|
||||
|
||||
# filename patterns
|
||||
*browser_view* @electron/browserview
|
||||
*notification* @electron/notifications
|
||||
*pdf* @electron/printing
|
||||
*printing* @electron/printing
|
||||
*updater* @electron/updater
|
||||
# ...except the Admin WG maintains this file.
|
||||
/.github/CODEOWNERS @electron/wg-admin
|
||||
|
||||
# directories
|
||||
/.github/ @electron/electrocats
|
||||
/default_app/ @electron/docs
|
||||
/docs/ @electron/docs
|
||||
/docs-translations/ @electron/i18n
|
||||
/npm/ @electron/electrocats
|
||||
# Upgrades WG
|
||||
/patches/ @electron/wg-upgrades
|
||||
|
||||
# Docs & Tooling WG
|
||||
/default_app/ @electron/wg-docs-tools
|
||||
/docs/ @electron/wg-docs-tools
|
||||
|
||||
# Releases WG
|
||||
/npm/ @electron/wg-releases
|
||||
|
||||
38
.github/ISSUE_TEMPLATE.md
vendored
38
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,38 +0,0 @@
|
||||
<!--
|
||||
Thanks for opening an issue! A few things to keep in mind:
|
||||
|
||||
- The issue tracker is only for bugs and feature requests.
|
||||
- Before reporting a bug, please try reproducing your issue against
|
||||
the latest version of Electron.
|
||||
- If you need general advice, join our Slack: http://atom-slack.herokuapp.com
|
||||
-->
|
||||
|
||||
* Output of `node_modules/.bin/electron --version`:
|
||||
* Operating System (Platform and Version):
|
||||
|
||||
<!-- If this used to work -->
|
||||
* Output of `node_modules/.bin/electron --version` on last known working Electron version (if applicable):
|
||||
|
||||
### Expected behavior
|
||||
|
||||
<!-- What do you think should happen? -->
|
||||
|
||||
### Actual behavior
|
||||
|
||||
<!-- What actually happens? -->
|
||||
|
||||
### How to reproduce
|
||||
|
||||
<!--
|
||||
|
||||
Your best chance of getting this bug looked at quickly is to provide a REPOSITORY that can be cloned and run.
|
||||
|
||||
You can fork https://github.com/electron/electron-quick-start and include a link to the branch with your changes.
|
||||
|
||||
If you provide a URL, please list the commands required to clone/setup/run your repo e.g.
|
||||
|
||||
$ git clone $YOUR_URL -b $BRANCH
|
||||
$ npm install
|
||||
$ npm start || electron .
|
||||
|
||||
-->
|
||||
48
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
48
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@@ -4,29 +4,51 @@ about: Create a report to help us improve Electron
|
||||
|
||||
---
|
||||
|
||||
* Output of `node_modules/.bin/electron --version`:
|
||||
* Operating System (Platform and Version):
|
||||
* Output of `node_modules/.bin/electron --version` on last known working Electron version (if applicable):
|
||||
<!-- As an open source project with a dedicated but small maintainer team, it can sometimes take a long time for issues to be addressed so please be patient and we will get back to you as soon as we can.
|
||||
-->
|
||||
|
||||
**Expected Behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
### Preflight Checklist
|
||||
<!-- Please ensure you've completed the following steps by replacing [ ] with [x]-->
|
||||
|
||||
**Actual behavior**
|
||||
A clear and concise description of what actually happened.
|
||||
* [ ] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
|
||||
* [ ] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
|
||||
* [ ] I have searched the issue tracker for an issue that matches the one I want to file, without success.
|
||||
|
||||
**To Reproduce**
|
||||
### Issue Details
|
||||
|
||||
* **Electron Version:**
|
||||
* <!-- (output of `node_modules/.bin/electron --version`) e.g. 4.0.3 -->
|
||||
* **Operating System:**
|
||||
* <!-- (Platform and Version) e.g. macOS 10.13.6 / Windows 10 (1803) / Ubuntu 18.04 x64 -->
|
||||
* **Last Known Working Electron version:**:
|
||||
* <!-- (if applicable) e.g. 3.1.0 -->
|
||||
|
||||
### Expected Behavior
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
### Actual Behavior
|
||||
<!-- A clear and concise description of what actually happened. -->
|
||||
|
||||
### To Reproduce
|
||||
<!--
|
||||
Your best chance of getting this bug looked at quickly is to provide a REPOSITORY that can be cloned and run.
|
||||
-->
|
||||
|
||||
You can fork [electron-quick-start](https://github.com/electron/electron-quick-start) and include a link to the branch with your changes.
|
||||
<!--
|
||||
You can fork electron-quick-start (https://github.com/electron/electron-quick-start) and include a link to the branch with your changes.
|
||||
-->
|
||||
|
||||
<!--
|
||||
If you provide a URL, please list the commands required to clone/setup/run your repo e.g.
|
||||
```sh
|
||||
$ git clone $YOUR_URL -b $BRANCH
|
||||
$ npm install
|
||||
$ npm start || electron .
|
||||
```
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
-->
|
||||
|
||||
**Additional Information**
|
||||
Add any other context about the problem here.
|
||||
### Screenshots
|
||||
<!-- If applicable, add screenshots to help explain your problem. -->
|
||||
|
||||
### Additional Information
|
||||
<!-- Add any other context about the problem here. -->
|
||||
|
||||
26
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
26
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
@@ -4,14 +4,24 @@ about: Suggest an idea for Electron
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is.
|
||||
<!-- As an open source project with a dedicated but small maintainer team, it can sometimes take a long time for issues to be addressed so please be patient and we will get back to you as soon as we can.
|
||||
-->
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
### Preflight Checklist
|
||||
<!-- Please ensure you've completed the following steps by replacing [ ] with [x]-->
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
* [ ] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
|
||||
* [ ] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
|
||||
* [ ] I have searched the issue tracker for a feature request that matches the one I want to file, without success.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
### Problem Description
|
||||
<!-- Is your feature request related to a problem? Please add a clear and concise description of what the problem is. -->
|
||||
|
||||
### Proposed Solution
|
||||
<!-- Describe the solution you'd like in a clear and concise manner -->
|
||||
|
||||
### Alternatives Considered
|
||||
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
|
||||
|
||||
### Additional Information
|
||||
<!-- Add any other context about the problem here. -->
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
name: Mac App Store Private API Rejection
|
||||
about: Your app was rejected from the Mac App Store for using private API's
|
||||
|
||||
---
|
||||
|
||||
* Electron Version:
|
||||
|
||||
**Rejection Email**
|
||||
Paste the contents of your rejection email here, censoring any private information such as app names.
|
||||
|
||||
**Additional Information**
|
||||
Add any other context about the problem here.
|
||||
25
.github/ISSUE_TEMPLATE/mac_app_store_private_api_rejection.md
vendored
Normal file
25
.github/ISSUE_TEMPLATE/mac_app_store_private_api_rejection.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: Mac App Store Private API Rejection
|
||||
about: Your app was rejected from the Mac App Store for using private API's
|
||||
|
||||
---
|
||||
|
||||
<!-- As an open source project with a dedicated but small maintainer team, it can sometimes take a long time for issues to be addressed so please be patient and we will get back to you as soon as we can.
|
||||
-->
|
||||
|
||||
### Preflight Checklist
|
||||
<!-- Please ensure you've completed the following steps by replacing [ ] with [x]-->
|
||||
|
||||
* [ ] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
|
||||
* [ ] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
|
||||
|
||||
### Issue Details
|
||||
|
||||
* **Electron Version:**
|
||||
* <!-- (output of `node_modules/.bin/electron --version`) e.g. 4.0.3 -->
|
||||
|
||||
### Rejection Email
|
||||
<!-- Paste the contents of your rejection email here, censoring any private information such as app names.-->
|
||||
|
||||
### Additional Information
|
||||
<!-- Add any other context about the problem here. -->
|
||||
@@ -4,6 +4,7 @@ about: Do not create an issue for security reports, send an email to security@el
|
||||
|
||||
---
|
||||
|
||||
Do not create an issue for security reports, send an email to:
|
||||
### Notice
|
||||
|
||||
security@electronjs.org
|
||||
**DO NOT** create an issue for security reports.
|
||||
Send an email to: **security@electronjs.org**.
|
||||
11
.github/PULL_REQUEST_TEMPLATE.md
vendored
11
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,4 +1,4 @@
|
||||
##### Description of Change
|
||||
#### Description of Change
|
||||
<!--
|
||||
Thank you for your Pull Request. Please provide a description above and review
|
||||
the requirements below.
|
||||
@@ -6,7 +6,7 @@ the requirements below.
|
||||
Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTING.md
|
||||
-->
|
||||
|
||||
##### Checklist
|
||||
#### Checklist
|
||||
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->
|
||||
|
||||
- [ ] PR description included and stakeholders cc'd
|
||||
@@ -14,9 +14,8 @@ Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTIN
|
||||
- [ ] tests are [changed or added](https://github.com/electron/electron/blob/master/docs/development/testing.md)
|
||||
- [ ] relevant documentation is changed or added
|
||||
- [ ] PR title follows semantic [commit guidelines](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines)
|
||||
- [ ] [PR release notes](https://github.com/electron/clerk/blob/master/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/master/README.md#examples).
|
||||
|
||||
#### Release Notes
|
||||
|
||||
##### Release Notes
|
||||
<!-- Used to describe release notes for future release versions. See https://github.com/electron/clerk/blob/master/README.md for details. -->
|
||||
|
||||
Notes: <!-- One-line Change Summary Here-->
|
||||
Notes: <!-- Please add a one-line description for app developers to read in the release notes, or `no-notes` if no notes relevant to app developers. Examples and help on special cases: https://github.com/electron/clerk/blob/master/README.md#examples -->
|
||||
|
||||
18
.github/config.yml
vendored
18
.github/config.yml
vendored
@@ -1,13 +1,3 @@
|
||||
# Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
|
||||
|
||||
# Comment to be posted to on first time issues
|
||||
newIssueWelcomeComment: |
|
||||
👋 Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.
|
||||
|
||||
To help make it easier for us to investigate your issue, please follow the [contributing guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md).
|
||||
|
||||
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
|
||||
|
||||
# Comment to be posted to on PRs from first time contributors in your repository
|
||||
newPRWelcomeComment: |
|
||||
💖 Thanks for opening this pull request! 💖
|
||||
@@ -36,18 +26,16 @@ newPRWelcomeComment: |
|
||||
firstPRMergeComment: >
|
||||
Congrats on merging your first pull request! 🎉🎉🎉
|
||||
|
||||
# Configuration for trop - https://github.com/codebytere/trop
|
||||
|
||||
watchedProject:
|
||||
name: Backports
|
||||
|
||||
# Users authorized to run manual trop backports
|
||||
authorizedUsers:
|
||||
- alexeykuzmin
|
||||
- BinaryMuse
|
||||
- ckerr
|
||||
- codebytere
|
||||
- deepak1556
|
||||
- jkleinsc
|
||||
- MarshallOfSound
|
||||
- miniak
|
||||
- nitsakh
|
||||
- nornagon
|
||||
- zcbenz
|
||||
|
||||
15
.gitignore
vendored
15
.gitignore
vendored
@@ -16,13 +16,6 @@
|
||||
*.vcxproj.user
|
||||
*.xcodeproj
|
||||
/.idea/
|
||||
/brightray/brightray.opensdf
|
||||
/brightray/brightray.sdf
|
||||
/brightray/brightray.sln
|
||||
/brightray/brightray.suo
|
||||
/brightray/brightray.v12.suo
|
||||
/brightray/brightray.vcxproj*
|
||||
/brightray/brightray.xcodeproj/
|
||||
/dist/
|
||||
/external_binaries/
|
||||
/out/
|
||||
@@ -44,7 +37,7 @@
|
||||
/vendor/pyyaml
|
||||
node_modules/
|
||||
SHASUMS256.txt
|
||||
**/yarn.lock
|
||||
**/package-lock.json
|
||||
compile_commands.json
|
||||
.envrc
|
||||
|
||||
@@ -63,3 +56,9 @@ spec/.hash
|
||||
|
||||
# Eslint Cache
|
||||
.eslintcache
|
||||
|
||||
# Generated native addon files
|
||||
/spec/fixtures/native-addon/echo/build/
|
||||
|
||||
# If someone runs tsc this is where stuff will end up
|
||||
ts-gen
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
pool:
|
||||
vmImage: 'Ubuntu 16.04'
|
||||
|
||||
steps:
|
||||
- bash: |
|
||||
# "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
|
||||
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git "${AGENT_BUILDDIRECTORY}/third_party/depot_tools"
|
||||
echo "##vso[task.setvariable variable=PATH]$PATH:${AGENT_BUILDDIRECTORY}/third_party/depot_tools"
|
||||
displayName: Setup Depot Tools
|
||||
|
||||
- bash: |
|
||||
chromium_revision="$(grep -A1 chromium_version DEPS | tr -d '\n' | cut -d\' -f4)"
|
||||
buildtools_revision="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep buildtools_revision -A1 | tr -d '\n' | cut -d\' -f4)"
|
||||
|
||||
git clone https://chromium.googlesource.com/chromium/buildtools "${AGENT_TEMPDIRECTORY}/buildtools"
|
||||
(cd "${AGENT_TEMPDIRECTORY}/buildtools" && git checkout "$buildtools_revision")
|
||||
echo "##vso[task.setvariable variable=CHROMIUM_BUILDTOOLS_PATH]$AGENT_TEMPDIRECTORY/buildtools"
|
||||
|
||||
download_from_google_storage --bucket chromium-gn -s "${AGENT_TEMPDIRECTORY}/buildtools/linux64/gn.sha1"
|
||||
displayName: Download gn binary
|
||||
|
||||
- bash: |
|
||||
# gn.py tries to find a gclient root folder starting from the current dir.
|
||||
# When it fails and returns "None" path, the whole script fails. Let's "fix" it.
|
||||
touch .gclient
|
||||
# Another option would be to checkout "buildtools" inside the Electron checkout,
|
||||
# but then we would lint its contents (at least gn format), and it doesn't pass it.
|
||||
|
||||
npm install
|
||||
npm run lint
|
||||
displayName: Run Lint
|
||||
646
BUILD.gn
646
BUILD.gn
@@ -1,18 +1,22 @@
|
||||
import("build/asar.gni")
|
||||
import("build/npm.gni")
|
||||
import("buildflags/buildflags.gni")
|
||||
import("electron_paks.gni")
|
||||
import("filenames.gni")
|
||||
import("//build/config/locales.gni")
|
||||
import("//build/config/ui.gni")
|
||||
import("//build/config/win/manifest.gni")
|
||||
import("//pdf/features.gni")
|
||||
import("//services/service_manager/public/service_manifest.gni")
|
||||
import("//printing/buildflags/buildflags.gni")
|
||||
import("//third_party/ffmpeg/ffmpeg_options.gni")
|
||||
import("//third_party/widevine/cdm/widevine.gni")
|
||||
import("//tools/generate_library_loader/generate_library_loader.gni")
|
||||
import("//tools/grit/grit_rule.gni")
|
||||
import("//tools/grit/repack.gni")
|
||||
import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
|
||||
import("//v8/snapshot_toolchain.gni")
|
||||
import("//v8/gni/snapshot_toolchain.gni")
|
||||
import("build/asar.gni")
|
||||
import("build/js_wrap.gni")
|
||||
import("build/npm.gni")
|
||||
import("build/tsc.gni")
|
||||
import("buildflags/buildflags.gni")
|
||||
import("electron_paks.gni")
|
||||
import("filenames.auto.gni")
|
||||
import("filenames.gni")
|
||||
|
||||
if (is_mac) {
|
||||
import("//build/config/mac/rules.gni")
|
||||
@@ -26,6 +30,13 @@ if (is_linux) {
|
||||
pkg_config("gio_unix") {
|
||||
packages = [ "gio-unix-2.0" ]
|
||||
}
|
||||
|
||||
pkg_config("libnotify_config") {
|
||||
packages = [
|
||||
"glib-2.0",
|
||||
"gdk-pixbuf-2.0",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
branding = read_file("atom/app/BRANDING.json", "json")
|
||||
@@ -45,65 +56,150 @@ config("branding") {
|
||||
]
|
||||
}
|
||||
|
||||
npm_action("atom_browserify_sandbox") {
|
||||
# We geneate the definitions twice here, once in //electron/electron.d.ts
|
||||
# and once in $target_gen_dir
|
||||
# The one in $target_gen_dir is used for the actual TSC build later one
|
||||
# and the one in //electron/electron.d.ts is used by your IDE (vscode)
|
||||
# for typescript prompting
|
||||
npm_action("build_electron_definitions") {
|
||||
script = "gn-typescript-definitions"
|
||||
args = [ rebase_path("$target_gen_dir/tsc/typings/electron.d.ts") ]
|
||||
inputs = auto_filenames.api_docs + [ "yarn.lock" ]
|
||||
|
||||
outputs = [
|
||||
"$target_gen_dir/tsc/typings/electron.d.ts",
|
||||
]
|
||||
}
|
||||
|
||||
npm_action("atom_browserify_sandbox_unwrapped") {
|
||||
script = "browserify"
|
||||
deps = [
|
||||
":atom_js2c_copy",
|
||||
":build_electron_definitions",
|
||||
]
|
||||
|
||||
sandbox_args = [
|
||||
inputs = auto_filenames.sandbox_browserify_deps
|
||||
|
||||
outputs = [
|
||||
"$target_gen_dir/js2c/sandbox_bundle_unwrapped.js",
|
||||
]
|
||||
|
||||
args = [
|
||||
"lib/sandboxed_renderer/init.js",
|
||||
"-r",
|
||||
"./lib/sandboxed_renderer/api/exports/electron.js:electron",
|
||||
"-r",
|
||||
"./lib/sandboxed_renderer/api/exports/fs.js:fs",
|
||||
"-r",
|
||||
"./lib/sandboxed_renderer/api/exports/os.js:os",
|
||||
"-r",
|
||||
"./lib/sandboxed_renderer/api/exports/path.js:path",
|
||||
"-r",
|
||||
"./lib/sandboxed_renderer/api/exports/child_process.js:child_process",
|
||||
"-t",
|
||||
"aliasify",
|
||||
"-p",
|
||||
"[",
|
||||
"tsify",
|
||||
"-p",
|
||||
"tsconfig.electron.json",
|
||||
"]",
|
||||
"--standalone",
|
||||
"sandboxed_preload",
|
||||
"-o",
|
||||
rebase_path(outputs[0]),
|
||||
]
|
||||
|
||||
inputs = [
|
||||
"lib/sandboxed_renderer/init.js",
|
||||
"lib/sandboxed_renderer/api/exports/electron.js",
|
||||
"lib/sandboxed_renderer/api/exports/fs.js",
|
||||
"lib/sandboxed_renderer/api/exports/os.js",
|
||||
"lib/sandboxed_renderer/api/exports/path.js",
|
||||
"lib/sandboxed_renderer/api/exports/child_process.js",
|
||||
]
|
||||
outputs = [
|
||||
"$target_gen_dir/js2c/preload_bundle.js",
|
||||
]
|
||||
|
||||
script = "browserify"
|
||||
args = sandbox_args + [
|
||||
"-o",
|
||||
rebase_path(outputs[0]),
|
||||
]
|
||||
}
|
||||
|
||||
npm_action("atom_browserify_isolated") {
|
||||
npm_action("atom_browserify_isolated_unwrapped") {
|
||||
script = "browserify"
|
||||
deps = [
|
||||
":atom_js2c_copy",
|
||||
":build_electron_definitions",
|
||||
]
|
||||
|
||||
inputs = auto_filenames.isolated_browserify_deps
|
||||
|
||||
outputs = [
|
||||
"$target_gen_dir/js2c/isolated_bundle_unwrapped.js",
|
||||
]
|
||||
|
||||
args = [
|
||||
"lib/isolated_renderer/init.js",
|
||||
"-t",
|
||||
"aliasify",
|
||||
"-p",
|
||||
"[",
|
||||
"tsify",
|
||||
"-p",
|
||||
"tsconfig.electron.json",
|
||||
"]",
|
||||
"--standalone",
|
||||
"isolated_preload",
|
||||
"-o",
|
||||
rebase_path(outputs[0]),
|
||||
]
|
||||
}
|
||||
|
||||
npm_action("atom_browserify_content_script_unwrapped") {
|
||||
script = "browserify"
|
||||
deps = [
|
||||
":build_electron_definitions",
|
||||
]
|
||||
|
||||
inputs = auto_filenames.context_script_browserify_deps
|
||||
|
||||
outputs = [
|
||||
"$target_gen_dir/js2c/content_script_bundle_unwrapped.js",
|
||||
]
|
||||
|
||||
args = [
|
||||
"lib/content_script/init.js",
|
||||
"-t",
|
||||
"aliasify",
|
||||
"-p",
|
||||
"[",
|
||||
"tsify",
|
||||
"-p",
|
||||
"tsconfig.electron.json",
|
||||
"]",
|
||||
"--standalone",
|
||||
"content_script_preload",
|
||||
"-o",
|
||||
rebase_path(outputs[0]),
|
||||
]
|
||||
}
|
||||
|
||||
js_wrap("atom_browserify_content_script") {
|
||||
deps = [
|
||||
":atom_browserify_content_script_unwrapped",
|
||||
]
|
||||
|
||||
inputs = [
|
||||
"lib/isolated_renderer/init.js",
|
||||
"$target_gen_dir/js2c/content_script_bundle_unwrapped.js",
|
||||
]
|
||||
|
||||
outputs = [
|
||||
"$target_gen_dir/js2c/content_script_bundle.js",
|
||||
]
|
||||
}
|
||||
|
||||
js_wrap("atom_browserify_isolated") {
|
||||
deps = [
|
||||
":atom_browserify_isolated_unwrapped",
|
||||
]
|
||||
|
||||
inputs = [
|
||||
"$target_gen_dir/js2c/isolated_bundle_unwrapped.js",
|
||||
]
|
||||
|
||||
outputs = [
|
||||
"$target_gen_dir/js2c/isolated_bundle.js",
|
||||
]
|
||||
}
|
||||
|
||||
script = "browserify"
|
||||
args = inputs + [
|
||||
"-t",
|
||||
"aliasify",
|
||||
"-o",
|
||||
rebase_path(outputs[0]),
|
||||
]
|
||||
js_wrap("atom_browserify_sandbox") {
|
||||
deps = [
|
||||
":atom_browserify_sandbox_unwrapped",
|
||||
]
|
||||
|
||||
inputs = [
|
||||
"$target_gen_dir/js2c/sandbox_bundle_unwrapped.js",
|
||||
]
|
||||
|
||||
outputs = [
|
||||
"$target_gen_dir/js2c/sandbox_bundle.js",
|
||||
]
|
||||
}
|
||||
|
||||
copy("atom_js2c_copy") {
|
||||
@@ -118,31 +214,43 @@ copy("atom_js2c_copy") {
|
||||
|
||||
action("atom_js2c") {
|
||||
deps = [
|
||||
":atom_browserify_content_script",
|
||||
":atom_browserify_isolated",
|
||||
":atom_browserify_sandbox",
|
||||
":atom_js2c_copy",
|
||||
]
|
||||
|
||||
js2c_sources = filenames.js2c_sources
|
||||
|
||||
browserify_sources = [
|
||||
"$target_gen_dir/js2c/content_script_bundle.js",
|
||||
"$target_gen_dir/js2c/isolated_bundle.js",
|
||||
"$target_gen_dir/js2c/preload_bundle.js",
|
||||
"$target_gen_dir/js2c/sandbox_bundle.js",
|
||||
]
|
||||
|
||||
inputs = js2c_sources + browserify_sources
|
||||
sources = browserify_sources + [
|
||||
"$target_gen_dir/js2c/asar.js",
|
||||
"$target_gen_dir/js2c/asar_init.js",
|
||||
]
|
||||
|
||||
inputs = sources
|
||||
outputs = [
|
||||
"$target_gen_dir/atom_natives.h",
|
||||
"$root_gen_dir/atom_natives.cc",
|
||||
]
|
||||
|
||||
script = "tools/js2c.py"
|
||||
args = [ rebase_path("//third_party/electron_node") ] +
|
||||
rebase_path(outputs, root_build_dir) +
|
||||
[ rebase_path("$target_gen_dir/js2c", root_build_dir) ]
|
||||
rebase_path(sources, root_build_dir)
|
||||
}
|
||||
|
||||
asar("js2asar") {
|
||||
target_gen_electron_js = "$target_gen_dir/js/electron"
|
||||
target_gen_default_app_js = "$target_gen_dir/js/default_app"
|
||||
|
||||
typescript_build("lib_js") {
|
||||
deps = [
|
||||
":build_electron_definitions",
|
||||
]
|
||||
type_root = rebase_path("$target_gen_dir/tsc/electron/typings")
|
||||
|
||||
sources = filenames.js_sources
|
||||
if (enable_desktop_capturer) {
|
||||
sources += [
|
||||
@@ -156,21 +264,70 @@ asar("js2asar") {
|
||||
"lib/browser/api/views/button.js",
|
||||
"lib/browser/api/views/label-button.js",
|
||||
"lib/browser/api/views/layout-manager.js",
|
||||
"lib/browser/api/views/md-text-button.js",
|
||||
"lib/browser/api/views/resize-area.js",
|
||||
"lib/browser/api/views/text-field.js",
|
||||
]
|
||||
}
|
||||
|
||||
output_gen_dir = target_gen_electron_js
|
||||
output_dir_name = "lib"
|
||||
tsconfig = "tsconfig.electron.json"
|
||||
}
|
||||
|
||||
asar("electron_asar") {
|
||||
deps = [
|
||||
":lib_js",
|
||||
]
|
||||
|
||||
root = "$target_gen_electron_js/electron/lib"
|
||||
sources = get_target_outputs(":lib_js")
|
||||
outputs = [
|
||||
"$root_out_dir/resources/electron.asar",
|
||||
]
|
||||
root = "lib"
|
||||
}
|
||||
|
||||
asar("app2asar") {
|
||||
sources = filenames.default_app_sources
|
||||
typescript_build("default_app_js") {
|
||||
deps = [
|
||||
":build_electron_definitions",
|
||||
]
|
||||
type_root = rebase_path("$target_gen_dir/tsc/electron/typings")
|
||||
|
||||
sources = filenames.default_app_ts_sources
|
||||
|
||||
output_gen_dir = target_gen_default_app_js
|
||||
output_dir_name = "default_app"
|
||||
tsconfig = "tsconfig.default_app.json"
|
||||
}
|
||||
|
||||
copy("default_app_static") {
|
||||
sources = filenames.default_app_static_sources
|
||||
outputs = [
|
||||
"$target_gen_default_app_js/{{source}}",
|
||||
]
|
||||
}
|
||||
|
||||
copy("default_app_octicon_deps") {
|
||||
sources = filenames.default_app_octicon_sources
|
||||
outputs = [
|
||||
"$target_gen_default_app_js/electron/default_app/octicon/{{source_file_part}}",
|
||||
]
|
||||
}
|
||||
|
||||
asar("default_app_asar") {
|
||||
deps = [
|
||||
":default_app_js",
|
||||
":default_app_octicon_deps",
|
||||
":default_app_static",
|
||||
]
|
||||
|
||||
root = "$target_gen_default_app_js/electron/default_app"
|
||||
sources = get_target_outputs(":default_app_js") +
|
||||
get_target_outputs(":default_app_static") +
|
||||
get_target_outputs(":default_app_octicon_deps")
|
||||
outputs = [
|
||||
"$root_out_dir/resources/default_app.asar",
|
||||
]
|
||||
root = "default_app"
|
||||
}
|
||||
|
||||
grit("resources") {
|
||||
@@ -181,18 +338,77 @@ grit("resources") {
|
||||
"electron_resources.pak",
|
||||
]
|
||||
|
||||
# Mojo manifest overlays are generated.
|
||||
source_is_generated = true
|
||||
grit_flags = [
|
||||
"-E",
|
||||
"target_gen_dir=" + rebase_path(target_gen_dir, root_build_dir),
|
||||
]
|
||||
|
||||
deps = [
|
||||
":electron_content_manifest_overlays",
|
||||
":copy_shell_devtools_discovery_page",
|
||||
]
|
||||
|
||||
output_dir = "$target_gen_dir"
|
||||
}
|
||||
|
||||
copy("copy_shell_devtools_discovery_page") {
|
||||
sources = [
|
||||
"//content/shell/resources/shell_devtools_discovery_page.html",
|
||||
]
|
||||
outputs = [
|
||||
"$target_gen_dir/shell_devtools_discovery_page.html",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_linux) {
|
||||
generate_library_loader("libnotify_loader") {
|
||||
name = "LibNotifyLoader"
|
||||
output_h = "libnotify_loader.h"
|
||||
output_cc = "libnotify_loader.cc"
|
||||
header = "<libnotify/notify.h>"
|
||||
config = ":libnotify_config"
|
||||
|
||||
functions = [
|
||||
"notify_is_initted",
|
||||
"notify_init",
|
||||
"notify_get_server_caps",
|
||||
"notify_get_server_info",
|
||||
"notify_notification_new",
|
||||
"notify_notification_add_action",
|
||||
"notify_notification_set_image_from_pixbuf",
|
||||
"notify_notification_set_timeout",
|
||||
"notify_notification_set_hint_string",
|
||||
"notify_notification_show",
|
||||
"notify_notification_close",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
source_set("manifests") {
|
||||
sources = [
|
||||
"//electron/atom/app/manifests.cc",
|
||||
"//electron/atom/app/manifests.h",
|
||||
]
|
||||
|
||||
include_dirs = [ "//electron" ]
|
||||
|
||||
deps = [
|
||||
"//electron/atom/common/api:mojo",
|
||||
"//printing/buildflags",
|
||||
"//services/proxy_resolver/public/cpp:manifest",
|
||||
"//services/service_manager/public/cpp",
|
||||
]
|
||||
|
||||
if (enable_basic_printing) {
|
||||
deps += [ "//components/services/pdf_compositor/public/cpp:manifest" ]
|
||||
}
|
||||
|
||||
if (enable_print_preview) {
|
||||
deps += [ "//chrome/services/printing/public/cpp:manifest" ]
|
||||
}
|
||||
}
|
||||
|
||||
static_library("electron_lib") {
|
||||
configs += [ "//v8:external_startup_data" ]
|
||||
configs += [ "//third_party/electron_node:node_internals" ]
|
||||
@@ -201,29 +417,44 @@ static_library("electron_lib") {
|
||||
|
||||
deps = [
|
||||
":atom_js2c",
|
||||
"brightray",
|
||||
":manifests",
|
||||
":resources",
|
||||
"atom/common/api:mojo",
|
||||
"buildflags",
|
||||
"chromium_src:chrome",
|
||||
"native_mate",
|
||||
"//base",
|
||||
"//base:i18n",
|
||||
"//base:base_static",
|
||||
"//base/allocator:buildflags",
|
||||
"//chrome/app/resources:platform_locale_settings",
|
||||
"//components/certificate_transparency",
|
||||
"//components/net_log",
|
||||
"//components/network_session_configurator/common",
|
||||
"//components/prefs",
|
||||
"//components/printing/common",
|
||||
"//components/spellcheck/renderer",
|
||||
"//components/viz/host",
|
||||
"//components/viz/service",
|
||||
"//content/public/app:both",
|
||||
"//content/public/browser",
|
||||
"//content/public/child",
|
||||
"//content/public/common:service_names",
|
||||
"//content/public/renderer",
|
||||
"//content/public/utility",
|
||||
"//device/bluetooth",
|
||||
"//gin",
|
||||
"//media/capture/mojom:video_capture",
|
||||
"//media/mojo/interfaces",
|
||||
"//net:extras",
|
||||
"//net:net_resources",
|
||||
"//net:net_with_v8",
|
||||
"//ppapi/host",
|
||||
"//ppapi/proxy",
|
||||
"//ppapi/shared_impl",
|
||||
"//printing",
|
||||
"//printing/buildflags",
|
||||
"//services/audio/public/mojom:constants",
|
||||
"//services/device/public/cpp/geolocation",
|
||||
"//services/device/public/mojom",
|
||||
"//services/proxy_resolver:lib",
|
||||
"//services/video_capture/public/mojom:constants",
|
||||
"//services/viz/privileged/interfaces/compositing",
|
||||
"//skia",
|
||||
"//third_party/blink/public:blink",
|
||||
"//third_party/boringssl",
|
||||
@@ -232,17 +463,21 @@ static_library("electron_lib") {
|
||||
"//third_party/libyuv",
|
||||
"//third_party/webrtc_overrides:init_webrtc",
|
||||
"//third_party/widevine/cdm:headers",
|
||||
"//ui/base/idle",
|
||||
"//ui/events:dom_keycode_converter",
|
||||
"//ui/gl",
|
||||
"//ui/native_theme",
|
||||
"//ui/shell_dialogs",
|
||||
"//ui/views",
|
||||
"//v8",
|
||||
"//v8:v8_libplatform",
|
||||
]
|
||||
|
||||
# TODO: this requires a visibility patch to chromium src. it would be better
|
||||
# to use the publicly-available API, which I think is mojo-based. Once
|
||||
# electron switches to using the public API, we can remove this from the deps
|
||||
# list and remove the visibility patch from chromium.
|
||||
deps += [ "//services/device/wake_lock/power_save_blocker" ]
|
||||
public_deps = [
|
||||
"//base",
|
||||
"//base:i18n",
|
||||
"//content/public/app:both",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"chromium_src",
|
||||
@@ -254,9 +489,13 @@ static_library("electron_lib") {
|
||||
"//third_party/blink/renderer",
|
||||
]
|
||||
|
||||
defines = []
|
||||
defines = [ "V8_DEPRECATION_WARNINGS" ]
|
||||
libs = []
|
||||
|
||||
if (is_linux) {
|
||||
defines += [ "GDK_DISABLE_DEPRECATION_WARNINGS" ]
|
||||
}
|
||||
|
||||
extra_source_filters = []
|
||||
if (!is_linux) {
|
||||
extra_source_filters += [
|
||||
@@ -285,8 +524,6 @@ static_library("electron_lib") {
|
||||
"*_views.cc",
|
||||
"*_views.h",
|
||||
"*\bviews/*",
|
||||
"*/autofill_popup.cc",
|
||||
"*/autofill_popup.h",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -295,16 +532,6 @@ static_library("electron_lib") {
|
||||
sources = filenames.lib_sources
|
||||
set_sources_assignment_filter(sources_assignment_filter)
|
||||
|
||||
sources += [
|
||||
"$target_gen_dir/atom_natives.h",
|
||||
"//extensions/browser/app_window/size_constraints.cc",
|
||||
"//extensions/browser/app_window/size_constraints.h",
|
||||
"//extensions/common/constants.cc",
|
||||
"//extensions/common/constants.h",
|
||||
"//extensions/common/url_pattern.cc",
|
||||
"//extensions/common/url_pattern.h",
|
||||
]
|
||||
|
||||
if (is_component_build) {
|
||||
defines += [ "NODE_SHARED_MODE" ]
|
||||
}
|
||||
@@ -318,17 +545,14 @@ static_library("electron_lib") {
|
||||
|
||||
if (is_mac) {
|
||||
deps += [
|
||||
"//third_party/crashpad/crashpad/client",
|
||||
"//components/remote_cocoa/app_shim",
|
||||
"//ui/accelerated_widget_mac",
|
||||
]
|
||||
include_dirs += [
|
||||
# NOTE(nornagon): other chromium files use the full path to include
|
||||
# crashpad; this is just here for compatibility between GN and GYP, so that
|
||||
# the #includes can be agnostic about where crashpad is vendored.
|
||||
"//third_party/crashpad",
|
||||
sources += [
|
||||
"atom/browser/ui/views/autofill_popup_view.cc",
|
||||
"atom/browser/ui/views/autofill_popup_view.h",
|
||||
]
|
||||
if (is_mas_build) {
|
||||
deps -= [ "//third_party/crashpad/crashpad/client" ]
|
||||
sources += [ "atom/browser/api/atom_api_app_mas.mm" ]
|
||||
sources -= [
|
||||
"atom/browser/auto_updater_mac.mm",
|
||||
@@ -353,29 +577,46 @@ static_library("electron_lib") {
|
||||
}
|
||||
if (is_linux) {
|
||||
deps += [
|
||||
":libnotify_loader",
|
||||
"//build/config/linux/gtk",
|
||||
"//chrome/browser/ui/libgtkui",
|
||||
"//dbus",
|
||||
"//device/bluetooth",
|
||||
"//third_party/breakpad:client",
|
||||
"//ui/events/devices/x11",
|
||||
"//ui/events/platform/x11",
|
||||
"//ui/native_theme",
|
||||
"//ui/views/controls/webview",
|
||||
"//ui/wm",
|
||||
]
|
||||
configs += [ ":gio_unix" ]
|
||||
include_dirs += [ "//third_party/breakpad" ]
|
||||
defines += [
|
||||
# Disable warnings for g_settings_list_schemas.
|
||||
"GLIB_DISABLE_DEPRECATION_WARNINGS",
|
||||
]
|
||||
|
||||
sources += filenames.lib_sources_nss
|
||||
}
|
||||
if (is_win) {
|
||||
sources += filenames.lib_sources_win
|
||||
libs += [ "dwmapi.lib" ]
|
||||
deps += [
|
||||
"//ui/native_theme:native_theme_browser",
|
||||
"//ui/views/controls/webview",
|
||||
"//ui/wm",
|
||||
"//ui/wm/public",
|
||||
]
|
||||
public_deps += [
|
||||
"//sandbox/win:sandbox",
|
||||
"//third_party/crashpad/crashpad/handler",
|
||||
]
|
||||
}
|
||||
if (is_linux || is_win) {
|
||||
deps += [ "//third_party/breakpad:client" ]
|
||||
include_dirs += [ "//third_party/breakpad" ]
|
||||
|
||||
if ((is_mac && !is_mas_build) || is_win) {
|
||||
sources += [
|
||||
"atom/common/crash_reporter/crash_reporter_crashpad.cc",
|
||||
"atom/common/crash_reporter/crash_reporter_crashpad.h",
|
||||
]
|
||||
deps += [ "//third_party/crashpad/crashpad/client" ]
|
||||
}
|
||||
|
||||
if (enable_pdf) {
|
||||
@@ -391,12 +632,13 @@ static_library("electron_lib") {
|
||||
|
||||
if (enable_osr) {
|
||||
sources += [
|
||||
"atom/browser/api/atom_api_web_contents_osr.cc",
|
||||
"atom/browser/osr/osr_output_device.cc",
|
||||
"atom/browser/osr/osr_output_device.h",
|
||||
"atom/browser/osr/osr_host_display_client.cc",
|
||||
"atom/browser/osr/osr_host_display_client.h",
|
||||
"atom/browser/osr/osr_host_display_client_mac.mm",
|
||||
"atom/browser/osr/osr_render_widget_host_view.cc",
|
||||
"atom/browser/osr/osr_render_widget_host_view.h",
|
||||
"atom/browser/osr/osr_render_widget_host_view_mac.mm",
|
||||
"atom/browser/osr/osr_video_consumer.cc",
|
||||
"atom/browser/osr/osr_video_consumer.h",
|
||||
"atom/browser/osr/osr_view_proxy.cc",
|
||||
"atom/browser/osr/osr_view_proxy.h",
|
||||
"atom/browser/osr/osr_web_contents_view.cc",
|
||||
@@ -432,23 +674,26 @@ static_library("electron_lib") {
|
||||
"atom/browser/api/views/atom_api_label_button.h",
|
||||
"atom/browser/api/views/atom_api_layout_manager.cc",
|
||||
"atom/browser/api/views/atom_api_layout_manager.h",
|
||||
"atom/browser/api/views/atom_api_md_text_button.cc",
|
||||
"atom/browser/api/views/atom_api_md_text_button.h",
|
||||
"atom/browser/api/views/atom_api_resize_area.cc",
|
||||
"atom/browser/api/views/atom_api_resize_area.h",
|
||||
"atom/browser/api/views/atom_api_text_field.cc",
|
||||
"atom/browser/api/views/atom_api_text_field.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_pepper_flash) {
|
||||
deps += [ "components/pepper_flash" ]
|
||||
if (enable_basic_printing) {
|
||||
sources += [
|
||||
"atom/browser/printing/print_preview_message_handler.cc",
|
||||
"atom/browser/printing/print_preview_message_handler.h",
|
||||
"atom/renderer/printing/print_render_frame_helper_delegate.cc",
|
||||
"atom/renderer/printing/print_render_frame_helper_delegate.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_widevine) {
|
||||
sources += [
|
||||
"//chrome/renderer/media/chrome_key_systems.cc",
|
||||
"//chrome/renderer/media/chrome_key_systems.h",
|
||||
"//chrome/renderer/media/chrome_key_systems_provider.cc",
|
||||
"//chrome/renderer/media/chrome_key_systems_provider.h",
|
||||
]
|
||||
deps += [ "//components/cdm/renderer" ]
|
||||
if (enable_pepper_flash) {
|
||||
deps += [ "components/pepper_flash" ]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -548,7 +793,7 @@ if (is_mac) {
|
||||
}
|
||||
info_plist = "atom/common/resources/mac/Info.plist"
|
||||
|
||||
electron_version = read_file("VERSION", "trim string")
|
||||
electron_version = read_file("ELECTRON_VERSION", "trim string")
|
||||
extra_substitutions = [
|
||||
"ATOM_BUNDLE_ID=$electron_mac_bundle_id.framework",
|
||||
"ELECTRON_VERSION=$electron_version",
|
||||
@@ -558,7 +803,9 @@ if (is_mac) {
|
||||
sources = filenames.framework_sources
|
||||
|
||||
libs = [
|
||||
"AVFoundation.framework",
|
||||
"Carbon.framework",
|
||||
"LocalAuthentication.framework",
|
||||
"QuartzCore.framework",
|
||||
"Quartz.framework",
|
||||
"Security.framework",
|
||||
@@ -566,6 +813,11 @@ if (is_mac) {
|
||||
"ServiceManagement.framework",
|
||||
"StoreKit.framework",
|
||||
]
|
||||
|
||||
if (enable_osr) {
|
||||
libs += [ "IOSurface.framework" ]
|
||||
}
|
||||
|
||||
ldflags = [
|
||||
"-F",
|
||||
rebase_path("external_binaries", root_build_dir),
|
||||
@@ -586,7 +838,12 @@ if (is_mac) {
|
||||
deps = [
|
||||
":electron_framework+link",
|
||||
]
|
||||
if (!is_mas_build) {
|
||||
deps += [ "//sandbox/mac:seatbelt" ]
|
||||
}
|
||||
defines = [ "HELPER_EXECUTABLE" ]
|
||||
sources = filenames.app_sources
|
||||
sources += [ "atom/common/atom_constants.cc" ]
|
||||
include_dirs = [ "." ]
|
||||
info_plist = "atom/renderer/resources/mac/Info.plist"
|
||||
extra_substitutions = [ "ATOM_BUNDLE_ID=$electron_mac_bundle_id.helper" ]
|
||||
@@ -594,6 +851,12 @@ if (is_mac) {
|
||||
"-rpath",
|
||||
"@executable_path/../../..",
|
||||
]
|
||||
if (is_component_build) {
|
||||
ldflags += [
|
||||
"-rpath",
|
||||
"@executable_path/../../../../../..",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
bundle_data("electron_app_framework_bundle_data") {
|
||||
@@ -635,14 +898,45 @@ if (is_mac) {
|
||||
"$root_out_dir/$electron_login_helper_name.app",
|
||||
]
|
||||
outputs = [
|
||||
"{{bundle_contents_dir}}/Library/LoginItems",
|
||||
"{{bundle_contents_dir}}/Library/LoginItems/{{source_file_part}}",
|
||||
]
|
||||
}
|
||||
|
||||
action("electron_app_lproj_dirs") {
|
||||
outputs = []
|
||||
|
||||
foreach(locale, locales_as_mac_outputs) {
|
||||
outputs += [ "$target_gen_dir/app_infoplist_strings/$locale.lproj" ]
|
||||
}
|
||||
script = "build/mac/make_locale_dirs.py"
|
||||
args = rebase_path(outputs)
|
||||
}
|
||||
|
||||
foreach(locale, locales_as_mac_outputs) {
|
||||
bundle_data("electron_app_strings_${locale}_bundle_data") {
|
||||
sources = [
|
||||
"$target_gen_dir/app_infoplist_strings/$locale.lproj",
|
||||
]
|
||||
outputs = [
|
||||
"{{bundle_resources_dir}}/$locale.lproj",
|
||||
]
|
||||
public_deps = [
|
||||
":electron_app_lproj_dirs",
|
||||
]
|
||||
}
|
||||
}
|
||||
group("electron_app_strings_bundle_data") {
|
||||
public_deps = []
|
||||
foreach(locale, locales_as_mac_outputs) {
|
||||
public_deps += [ ":electron_app_strings_${locale}_bundle_data" ]
|
||||
}
|
||||
}
|
||||
|
||||
bundle_data("electron_app_resources") {
|
||||
public_deps = [
|
||||
":app2asar",
|
||||
":js2asar",
|
||||
":default_app_asar",
|
||||
":electron_app_strings_bundle_data",
|
||||
":electron_asar",
|
||||
]
|
||||
sources = [
|
||||
"$root_out_dir/resources/default_app.asar",
|
||||
@@ -657,6 +951,7 @@ if (is_mac) {
|
||||
mac_app_bundle("electron_app") {
|
||||
output_name = electron_product_name
|
||||
sources = filenames.app_sources
|
||||
sources += [ "atom/common/atom_constants.cc" ]
|
||||
include_dirs = [ "." ]
|
||||
deps = [
|
||||
":electron_app_framework_bundle_data",
|
||||
@@ -688,12 +983,13 @@ if (is_mac) {
|
||||
sources = filenames.app_sources
|
||||
include_dirs = [ "." ]
|
||||
deps = [
|
||||
":app2asar",
|
||||
":default_app_asar",
|
||||
":electron_app_manifest",
|
||||
":electron_asar",
|
||||
":electron_lib",
|
||||
":js2asar",
|
||||
":packed_resources",
|
||||
"//content:sandbox_helper_win",
|
||||
"//electron/buildflags",
|
||||
"//ui/strings",
|
||||
]
|
||||
|
||||
@@ -722,17 +1018,7 @@ if (is_mac) {
|
||||
# TODO: we should be generating our .rc files more like how chrome does
|
||||
"atom/browser/resources/win/atom.ico",
|
||||
"atom/browser/resources/win/atom.rc",
|
||||
"atom/browser/resources/win/resources.h",
|
||||
]
|
||||
|
||||
deps += [
|
||||
"//third_party/breakpad:breakpad_handler",
|
||||
"//third_party/breakpad:breakpad_sender",
|
||||
"//ui/native_theme:native_theme_browser",
|
||||
"//ui/shell_dialogs",
|
||||
"//ui/views/controls/webview",
|
||||
"//ui/wm",
|
||||
"//ui/wm/public",
|
||||
"atom/browser/resources/win/resource.h",
|
||||
]
|
||||
|
||||
libs = [
|
||||
@@ -750,6 +1036,16 @@ if (is_mac) {
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll",
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-string-l1-1-0.dll",
|
||||
]
|
||||
|
||||
# This is to support renaming of electron.exe. node-gyp has hard-coded
|
||||
# executable names which it will recognise as node. This module definition
|
||||
# file claims that the electron executable is in fact named "node.exe",
|
||||
# which is one of the executable names that node-gyp recognizes.
|
||||
# See https://github.com/nodejs/node-gyp/commit/52ceec3a6d15de3a8f385f43dbe5ecf5456ad07a
|
||||
ldflags += [ "/DEF:" + rebase_path("build/electron.def", root_build_dir) ]
|
||||
inputs = [
|
||||
"build/electron.def",
|
||||
]
|
||||
}
|
||||
if (is_linux) {
|
||||
ldflags = [ "-pie" ]
|
||||
@@ -761,72 +1057,6 @@ if (is_mac) {
|
||||
}
|
||||
}
|
||||
|
||||
group("electron_tests") {
|
||||
testonly = true
|
||||
|
||||
deps = [
|
||||
":chromium_browsertests",
|
||||
":chromium_unittests",
|
||||
]
|
||||
}
|
||||
|
||||
group("chromium_unittests") {
|
||||
testonly = true
|
||||
|
||||
deps = [
|
||||
"//base:base_unittests",
|
||||
"//cc:cc_unittests",
|
||||
"//content/test:content_unittests",
|
||||
"//crypto:crypto_unittests",
|
||||
"//device:device_unittests",
|
||||
"//gin:gin_unittests",
|
||||
"//gpu:gpu_unittests",
|
||||
"//ipc:ipc_tests",
|
||||
"//media:media_unittests",
|
||||
"//media/capture:capture_unittests",
|
||||
"//media/midi:midi_unittests",
|
||||
"//media/mojo:media_mojo_unittests",
|
||||
"//mojo:mojo_unittests",
|
||||
"//net:net_unittests",
|
||||
"//ppapi:ppapi_unittests",
|
||||
"//printing:printing_unittests",
|
||||
"//skia:skia_unittests",
|
||||
"//sql:sql_unittests",
|
||||
"//storage:storage_unittests",
|
||||
"//third_party/angle/src/tests:angle_unittests",
|
||||
"//third_party/blink/public:all_blink",
|
||||
"//third_party/blink/public:test_support",
|
||||
"//third_party/leveldatabase:env_chromium_unittests",
|
||||
"//ui/base:ui_base_unittests",
|
||||
"//ui/compositor:compositor_unittests",
|
||||
"//ui/display:display_unittests",
|
||||
"//ui/events:events_unittests",
|
||||
"//ui/gl:gl_unittests",
|
||||
"//url:url_unittests",
|
||||
"//url/ipc:url_ipc_unittests",
|
||||
"//v8/test/unittests:unittests",
|
||||
]
|
||||
|
||||
if (is_linux) {
|
||||
deps += [
|
||||
"//net:disk_cache_memory_test",
|
||||
"//sandbox/linux:sandbox_linux_unittests",
|
||||
]
|
||||
|
||||
if (use_dbus) {
|
||||
deps += [ "//dbus:dbus_unittests" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group("chromium_browsertests") {
|
||||
testonly = true
|
||||
|
||||
deps = [
|
||||
"//content/test:content_browsertests",
|
||||
]
|
||||
}
|
||||
|
||||
template("dist_zip") {
|
||||
_runtime_deps_target = "${target_name}__deps"
|
||||
_runtime_deps_file =
|
||||
@@ -839,6 +1069,7 @@ template("dist_zip") {
|
||||
"deps",
|
||||
"data_deps",
|
||||
"data",
|
||||
"testonly",
|
||||
])
|
||||
write_runtime_deps = _runtime_deps_file
|
||||
}
|
||||
@@ -848,7 +1079,11 @@ template("dist_zip") {
|
||||
deps = [
|
||||
":$_runtime_deps_target",
|
||||
]
|
||||
forward_variables_from(invoker, [ "outputs" ])
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"outputs",
|
||||
"testonly",
|
||||
])
|
||||
args = rebase_path(outputs + [ _runtime_deps_file ], root_build_dir) + [
|
||||
target_cpu,
|
||||
target_os,
|
||||
@@ -885,7 +1120,7 @@ group("licenses") {
|
||||
|
||||
copy("electron_version") {
|
||||
sources = [
|
||||
"VERSION",
|
||||
"ELECTRON_VERSION",
|
||||
]
|
||||
outputs = [
|
||||
"$root_build_dir/version",
|
||||
@@ -898,6 +1133,9 @@ dist_zip("electron_dist_zip") {
|
||||
":licenses",
|
||||
":electron_version",
|
||||
]
|
||||
if (is_linux) {
|
||||
data_deps += [ "//sandbox/linux:chrome_sandbox" ]
|
||||
}
|
||||
outputs = [
|
||||
"$root_build_dir/dist.zip",
|
||||
]
|
||||
@@ -913,6 +1151,7 @@ dist_zip("electron_ffmpeg_zip") {
|
||||
}
|
||||
|
||||
dist_zip("electron_chromedriver_zip") {
|
||||
testonly = true
|
||||
data_deps = [
|
||||
"//chrome/test/chromedriver",
|
||||
":licenses",
|
||||
@@ -925,6 +1164,7 @@ dist_zip("electron_chromedriver_zip") {
|
||||
dist_zip("electron_mksnapshot_zip") {
|
||||
data_deps = [
|
||||
"//v8:mksnapshot($v8_snapshot_toolchain)",
|
||||
"//tools/v8_context_snapshot:v8_context_snapshot_generator",
|
||||
":licenses",
|
||||
]
|
||||
outputs = [
|
||||
@@ -933,23 +1173,7 @@ dist_zip("electron_mksnapshot_zip") {
|
||||
}
|
||||
|
||||
group("electron") {
|
||||
deps = [
|
||||
public_deps = [
|
||||
":electron_app",
|
||||
]
|
||||
}
|
||||
|
||||
group("electron_content_manifest_overlays") {
|
||||
deps = [
|
||||
":electron_content_browser_manifest_overlay",
|
||||
":electron_content_packaged_services_manifest_overlay",
|
||||
]
|
||||
}
|
||||
|
||||
service_manifest("electron_content_packaged_services_manifest_overlay") {
|
||||
source = "//electron/manifests/electron_content_packaged_services_manifest_overlay.json"
|
||||
packaged_services = [ "//services/proxy_resolver:proxy_resolver_manifest" ]
|
||||
}
|
||||
|
||||
service_manifest("electron_content_browser_manifest_overlay") {
|
||||
source = "//electron/manifests/electron_content_browser_manifest_overlay.json"
|
||||
}
|
||||
|
||||
51
DEPS
51
DEPS
@@ -10,9 +10,9 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'69.0.3497.106',
|
||||
'76.0.3809.26',
|
||||
'node_version':
|
||||
'5654c276d0497ff9a0bb0d7550b9073b2e2e7d3f',
|
||||
'229bd3245b2f54c12ea9ad0abcadbc209f8023dc',
|
||||
|
||||
'boto_version': 'f7574aa6cc2c819430c1f05e9a1a1a666ef8169b',
|
||||
'pyyaml_version': '3.12',
|
||||
@@ -24,9 +24,22 @@ vars = {
|
||||
'requests_git': 'https://github.com/kennethreitz',
|
||||
'yaml_git': 'https://github.com/yaml',
|
||||
|
||||
# KEEP IN SYNC WITH spec-runner FILE
|
||||
'yarn_version': '1.15.2',
|
||||
|
||||
# To be able to build clean Chromium from sources.
|
||||
'apply_patches': True,
|
||||
|
||||
# Python interface to Amazon Web Services. Is used for releases only.
|
||||
'checkout_boto': False,
|
||||
|
||||
# To allow in-house builds to checkout those manually.
|
||||
'checkout_chromium': True,
|
||||
'checkout_node': True,
|
||||
|
||||
# It's only needed to parse the native tests configurations.
|
||||
'checkout_pyyaml': False,
|
||||
|
||||
# Python "requests" module is used for releases only.
|
||||
'checkout_requests': False,
|
||||
|
||||
@@ -49,12 +62,18 @@ vars = {
|
||||
}
|
||||
|
||||
deps = {
|
||||
'src':
|
||||
(Var("chromium_git")) + '/chromium/src.git@' + (Var("chromium_version")),
|
||||
'src/third_party/electron_node':
|
||||
(Var("electron_git")) + '/node.git@' + (Var("node_version")),
|
||||
'src/electron/vendor/pyyaml':
|
||||
(Var("yaml_git")) + '/pyyaml.git@' + (Var("pyyaml_version")),
|
||||
'src': {
|
||||
'url': (Var("chromium_git")) + '/chromium/src.git@' + (Var("chromium_version")),
|
||||
'condition': 'checkout_chromium',
|
||||
},
|
||||
'src/third_party/electron_node': {
|
||||
'url': (Var("electron_git")) + '/node.git@' + (Var("node_version")),
|
||||
'condition': 'checkout_node',
|
||||
},
|
||||
'src/electron/vendor/pyyaml': {
|
||||
'url': (Var("yaml_git")) + '/pyyaml.git@' + (Var("pyyaml_version")),
|
||||
'condition': 'checkout_pyyaml',
|
||||
},
|
||||
'src/electron/vendor/boto': {
|
||||
'url': Var('boto_git') + '/boto.git' + '@' + Var('boto_version'),
|
||||
'condition': 'checkout_boto',
|
||||
@@ -68,12 +87,12 @@ deps = {
|
||||
hooks = [
|
||||
{
|
||||
'name': 'patch_chromium',
|
||||
'condition': 'checkout_chromium and apply_patches',
|
||||
'pattern': 'src/electron',
|
||||
'action': [
|
||||
'python',
|
||||
'src/electron/script/apply-patches',
|
||||
'--project-root=.',
|
||||
'--commit',
|
||||
'src/electron/script/apply_all_patches.py',
|
||||
'src/electron/patches/common/config.json',
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -83,8 +102,6 @@ hooks = [
|
||||
'action': [
|
||||
'python',
|
||||
'src/electron/script/update-external-binaries.py',
|
||||
'--root-url=http://github.com/electron/electron-frameworks/releases/download',
|
||||
'--version=v1.4.0',
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -93,7 +110,7 @@ hooks = [
|
||||
'action': [
|
||||
'python',
|
||||
'-c',
|
||||
'import os; os.chdir("src"); os.chdir("electron"); os.system("npm install")',
|
||||
'import os, subprocess; os.chdir(os.path.join("src", "electron")); subprocess.check_call(["python", "script/lib/npx.py", "yarn@' + (Var("yarn_version")) + '", "install", "--frozen-lockfile"]);',
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -103,7 +120,7 @@ hooks = [
|
||||
'action': [
|
||||
'python',
|
||||
'-c',
|
||||
'import os; os.chdir("src"); os.chdir("electron"); os.chdir("vendor"); os.chdir("boto"); os.system("python setup.py build");',
|
||||
'import os, subprocess; os.chdir(os.path.join("src", "electron", "vendor", "boto")); subprocess.check_call(["python", "setup.py", "build"]);',
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -113,9 +130,9 @@ hooks = [
|
||||
'action': [
|
||||
'python',
|
||||
'-c',
|
||||
'import os; os.chdir("src"); os.chdir("electron"); os.chdir("vendor"); os.chdir("requests"); os.system("python setup.py build");',
|
||||
'import os, subprocess; os.chdir(os.path.join("src", "electron", "vendor", "requests")); subprocess.check_call(["python", "setup.py", "build"]);',
|
||||
],
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
recursedeps = [
|
||||
|
||||
@@ -16,7 +16,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
locales \
|
||||
lsb-release \
|
||||
nano \
|
||||
python-dbusmock \
|
||||
python-dbus \
|
||||
python-pip \
|
||||
python-setuptools \
|
||||
sudo \
|
||||
@@ -33,6 +33,9 @@ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
|
||||
# crcmod is required by gsutil, which is used for filling the gclient git cache
|
||||
RUN pip install -U crcmod
|
||||
|
||||
# dbusmock is needed for Electron tests
|
||||
RUN pip install python-dbusmock
|
||||
|
||||
RUN mkdir /tmp/workspace
|
||||
RUN chown builduser:builduser /tmp/workspace
|
||||
|
||||
|
||||
1
ELECTRON_VERSION
Normal file
1
ELECTRON_VERSION
Normal file
@@ -0,0 +1 @@
|
||||
6.0.0-beta.9
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2013-2018 GitHub Inc.
|
||||
Copyright (c) 2013-2019 GitHub Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
|
||||
[](https://circleci.com/gh/electron/electron/tree/master)
|
||||
[](https://windows-ci.electronjs.org/project/AppVeyor/electron/branch/master)
|
||||
[](https://github.visualstudio.com/electron/_build/latest?definitionId=36)
|
||||
[](https://david-dm.org/electron/electron?type=dev)
|
||||
[](https://atom-slack.herokuapp.com/)
|
||||
|
||||
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹.
|
||||
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹 🇵🇱.
|
||||
View these docs in other languages at [electron/i18n](https://github.com/electron/i18n/tree/master/content/).
|
||||
|
||||
The Electron framework lets you write cross-platform desktop applications
|
||||
|
||||
51
appveyor.yml
51
appveyor.yml
@@ -1,10 +1,35 @@
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "GN_CONFIG" Build type. One of {'debug', 'testing', 'release'}.
|
||||
# - "GN_EXTRA_ARGS" Additional gn arguments for a build config,
|
||||
# e.g. 'target_cpu="x86"' to build for a 32bit platform.
|
||||
# https://gn.googlesource.com/gn/+/master/docs/reference.md#target_cpu
|
||||
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordningly
|
||||
# if you pass a custom value for 'target_cpu'.
|
||||
# - "ELECTRON_RELEASE" Set it to '1' upload binaries on success.
|
||||
# - "NPM_CONFIG_ARCH" E.g. 'x86'. Is used to build native Node.js modules.
|
||||
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "TARGET_ARCH" value.
|
||||
# - "TARGET_ARCH" Choose from {'ia32', 'x64', 'arm', 'arm64', 'mips64el'}.
|
||||
# Is used in some publishing scripts, but does NOT affect the Electron binary.
|
||||
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "NPM_CONFIG_ARCH" value.
|
||||
# - "UPLOAD_TO_S3" Set it to '1' upload a release to the S3 bucket.
|
||||
# Otherwise the release will be uploaded to the Github Releases.
|
||||
# (The value is only checked if "ELECTRON_RELEASE" is defined.)
|
||||
#
|
||||
# The publishing scripts expect access tokens to be defined as env vars,
|
||||
# but those are not covered here.
|
||||
#
|
||||
# AppVeyor docs on variables:
|
||||
# https://www.appveyor.com/docs/environment-variables/
|
||||
# https://www.appveyor.com/docs/build-configuration/#secure-variables
|
||||
# https://www.appveyor.com/docs/build-configuration/#custom-environment-variables
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: libcc-20
|
||||
image: libcc-20-vs2017-15.7.4
|
||||
image: libcc-20-vs2017-15.9
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\electron\libcc_cache
|
||||
DISABLE_CRASH_REPORTER_TESTS: true
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
build_script:
|
||||
- ps: >-
|
||||
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
|
||||
@@ -13,7 +38,7 @@ build_script:
|
||||
- echo "Building $env:GN_CONFIG build"
|
||||
- git config --global core.longpaths true
|
||||
- cd ..
|
||||
- md src
|
||||
- ps: if (Test-Path src\electron) { Remove-Item src\electron -Recurse }
|
||||
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: $env:SCCACHE_PATH="$pwd\src\electron\external_binaries\sccache.exe"
|
||||
@@ -27,9 +52,14 @@ build_script:
|
||||
--unmanaged
|
||||
%GCLIENT_EXTRA_ARGS%
|
||||
"https://github.com/electron/electron"
|
||||
- gclient sync --with_branch_heads --with_tags
|
||||
- gclient sync --with_branch_heads --with_tags --reset
|
||||
- cd src
|
||||
- gn gen out/Default "--args=import(\"//electron/build/args/%GN_CONFIG%.gn\") %GN_EXTRA_ARGS%"
|
||||
- ps: $env:BUILD_CONFIG_PATH="//electron/build/args/%GN_CONFIG%.gn"
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS%"
|
||||
- gn check out/Default //electron:electron_lib
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron:manifests
|
||||
- gn check out/Default //electron/atom/common/api:mojo
|
||||
- ninja -C out/Default electron:electron_app
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
|
||||
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
@@ -44,18 +74,19 @@ build_script:
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
ninja -C out/Default third_party/breakpad:dump_syms
|
||||
}
|
||||
- if "%GN_CONFIG%"=="release" ( python electron\script\dump-symbols.py -d %cd%\out\Default\electron.breakpad.syms -v)
|
||||
- if "%GN_CONFIG%"=="release" ( python electron\script\dump-symbols.py -d %cd%\out\Default\breakpad_symbols -v)
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
python electron\script\zip-symbols.py
|
||||
appveyor PushArtifact out/Default/symbols.zip
|
||||
}
|
||||
test_script:
|
||||
# Workaround for https://github.com/appveyor/ci/issues/2420
|
||||
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
|
||||
- ps: >-
|
||||
if ((-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
|
||||
$env:RUN_TESTS="true"
|
||||
}
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- ps: >-
|
||||
if ($env:RUN_TESTS -eq 'true') {
|
||||
New-Item .\out\Default\gen\node_headers\Release -Type directory
|
||||
@@ -64,8 +95,12 @@ test_script:
|
||||
echo "Skipping tests for $env:GN_CONFIG build"
|
||||
}
|
||||
- cd electron
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & npm run test -- --ci )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & npm run test -- --ci --enable-logging)
|
||||
- cd ..
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- echo "About to verify mksnapshot"
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% )
|
||||
- echo "Done verifying mksnapshot"
|
||||
deploy_script:
|
||||
- cd electron
|
||||
- ps: >-
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/chrome_version.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_util.h"
|
||||
@@ -17,10 +15,10 @@
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/common/content_constants.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
#include "url/url_constants.h"
|
||||
// In SHARED_INTERMEDIATE_DIR.
|
||||
#include "widevine_cdm_version.h" // NOLINT(build/include)
|
||||
@@ -179,33 +177,53 @@ AtomContentClient::AtomContentClient() {}
|
||||
|
||||
AtomContentClient::~AtomContentClient() {}
|
||||
|
||||
std::string AtomContentClient::GetProduct() const {
|
||||
return "Chrome/" CHROME_VERSION_STRING;
|
||||
}
|
||||
|
||||
std::string AtomContentClient::GetUserAgent() const {
|
||||
return content::BuildUserAgentFromProduct("Chrome/" CHROME_VERSION_STRING
|
||||
" " ATOM_PRODUCT_NAME
|
||||
"/" ATOM_VERSION_STRING);
|
||||
}
|
||||
|
||||
base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
|
||||
return l10n_util::GetStringUTF16(message_id);
|
||||
}
|
||||
|
||||
void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) {
|
||||
schemes->standard_schemes.push_back("chrome-extension");
|
||||
base::StringPiece AtomContentClient::GetDataResource(
|
||||
int resource_id,
|
||||
ui::ScaleFactor scale_factor) const {
|
||||
return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(
|
||||
resource_id, scale_factor);
|
||||
}
|
||||
|
||||
gfx::Image& AtomContentClient::GetNativeImageNamed(int resource_id) const {
|
||||
return ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(
|
||||
resource_id);
|
||||
}
|
||||
|
||||
base::RefCountedMemory* AtomContentClient::GetDataResourceBytes(
|
||||
int resource_id) const {
|
||||
return ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
|
||||
resource_id);
|
||||
}
|
||||
|
||||
void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) {
|
||||
std::vector<std::string> splited;
|
||||
ConvertStringWithSeparatorToVector(&splited, ",",
|
||||
switches::kRegisterServiceWorkerSchemes);
|
||||
switches::kServiceWorkerSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->service_worker_schemes.push_back(scheme);
|
||||
schemes->service_worker_schemes.push_back(url::kFileScheme);
|
||||
|
||||
ConvertStringWithSeparatorToVector(&splited, ",", switches::kStandardSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->standard_schemes.push_back(scheme);
|
||||
schemes->standard_schemes.push_back("chrome-extension");
|
||||
|
||||
ConvertStringWithSeparatorToVector(&splited, ",", switches::kSecureSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->secure_schemes.push_back(scheme);
|
||||
|
||||
ConvertStringWithSeparatorToVector(&splited, ",",
|
||||
switches::kBypassCSPSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->csp_bypassing_schemes.push_back(scheme);
|
||||
|
||||
ConvertStringWithSeparatorToVector(&splited, ",", switches::kCORSSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->cors_enabled_schemes.push_back(scheme);
|
||||
}
|
||||
|
||||
void AtomContentClient::AddPepperPlugins(
|
||||
@@ -250,4 +268,8 @@ void AtomContentClient::AddContentDecryptionModules(
|
||||
}
|
||||
}
|
||||
|
||||
bool AtomContentClient::IsDataResourceGzipped(int resource_id) const {
|
||||
return ui::ResourceBundle::GetSharedInstance().IsGzipped(resource_id);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -9,26 +9,29 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "brightray/common/content_client.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomContentClient : public brightray::ContentClient {
|
||||
class AtomContentClient : public content::ContentClient {
|
||||
public:
|
||||
AtomContentClient();
|
||||
~AtomContentClient() override;
|
||||
|
||||
protected:
|
||||
// content::ContentClient:
|
||||
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;
|
||||
gfx::Image& GetNativeImageNamed(int resource_id) const override;
|
||||
base::RefCountedMemory* GetDataResourceBytes(int resource_id) const override;
|
||||
void AddAdditionalSchemes(Schemes* schemes) override;
|
||||
void AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) override;
|
||||
void AddContentDecryptionModules(
|
||||
std::vector<content::CdmInfo>* cdms,
|
||||
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) override;
|
||||
bool IsDataResourceGzipped(int resource_id) const override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
#include "atom/app/node_main.h"
|
||||
#include "atom/common/atom_command_line.h"
|
||||
#include "atom/common/mac/main_application_bundle.h"
|
||||
#include "base/at_exit.h"
|
||||
#include "base/i18n/icu_util.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
||||
#include "brightray/common/mac/main_application_bundle.h"
|
||||
#include "content/public/app/content_main.h"
|
||||
|
||||
int AtomMain(int argc, char* argv[]) {
|
||||
@@ -28,7 +28,7 @@ int AtomInitializeICUandStartNode(int argc, char* argv[]) {
|
||||
base::AtExitManager atexit_manager;
|
||||
base::mac::ScopedNSAutoreleasePool pool;
|
||||
base::mac::SetOverrideFrameworkBundlePath(
|
||||
brightray::MainApplicationBundlePath()
|
||||
atom::MainApplicationBundlePath()
|
||||
.Append("Contents")
|
||||
.Append("Frameworks")
|
||||
.Append(ATOM_PRODUCT_NAME " Framework.framework"));
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
#include "atom/app/atom_main.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@@ -24,26 +26,32 @@
|
||||
#include "base/win/windows_version.h"
|
||||
#include "content/public/app/sandbox_helper_win.h"
|
||||
#include "sandbox/win/src/sandbox_types.h"
|
||||
#elif defined(OS_LINUX) // defined(OS_WIN)
|
||||
#elif defined(OS_LINUX) // defined(OS_WIN)
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#include "atom/app/atom_main_delegate.h" // NOLINT
|
||||
#include "content/public/app/content_main.h"
|
||||
#else // defined(OS_LINUX)
|
||||
#include <mach-o/dyld.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#include "atom/app/atom_library_main.h"
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
#include "atom/app/node_main.h"
|
||||
#include "atom/common/atom_command_line.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "base/at_exit.h"
|
||||
#include "base/i18n/icu_util.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
|
||||
namespace {
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
const char kRunAsNode[] = "ELECTRON_RUN_AS_NODE";
|
||||
#if defined(HELPER_EXECUTABLE) && !defined(MAS_BUILD)
|
||||
#include "sandbox/mac/seatbelt_exec.h" // nogncheck
|
||||
#endif
|
||||
|
||||
bool IsEnvSet(const char* name) {
|
||||
namespace {
|
||||
|
||||
ALLOW_UNUSED_TYPE bool IsEnvSet(const char* name) {
|
||||
#if defined(OS_WIN)
|
||||
size_t required_size;
|
||||
getenv_s(&required_size, nullptr, 0, name);
|
||||
@@ -54,9 +62,33 @@ bool IsEnvSet(const char* name) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
void FixStdioStreams() {
|
||||
// libuv may mark stdin/stdout/stderr as close-on-exec, which interferes
|
||||
// with chromium's subprocess spawning. As a workaround, we detect if these
|
||||
// streams are closed on startup, and reopen them as /dev/null if necessary.
|
||||
// Otherwise, an unrelated file descriptor will be assigned as stdout/stderr
|
||||
// which may cause various errors when attempting to write to them.
|
||||
//
|
||||
// For details see https://github.com/libuv/libuv/issues/2062
|
||||
struct stat st;
|
||||
if (fstat(STDIN_FILENO, &st) < 0 && errno == EBADF)
|
||||
ignore_result(freopen("/dev/null", "r", stdin));
|
||||
if (fstat(STDOUT_FILENO, &st) < 0 && errno == EBADF)
|
||||
ignore_result(freopen("/dev/null", "w", stdout));
|
||||
if (fstat(STDERR_FILENO, &st) < 0 && errno == EBADF)
|
||||
ignore_result(freopen("/dev/null", "w", stderr));
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
namespace crash_reporter {
|
||||
extern const char kCrashpadProcess[];
|
||||
}
|
||||
|
||||
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
struct Arguments {
|
||||
int argc = 0;
|
||||
@@ -93,7 +125,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
bool run_as_node = IsEnvSet(kRunAsNode);
|
||||
bool run_as_node = IsEnvSet(atom::kRunAsNode);
|
||||
#else
|
||||
bool run_as_node = false;
|
||||
#endif
|
||||
@@ -119,13 +151,11 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
atexit([]() { OnThreadExit(nullptr, DLL_THREAD_DETACH, nullptr); });
|
||||
#endif
|
||||
|
||||
std::vector<char*> argv(arguments.argc);
|
||||
std::transform(arguments.argv, arguments.argv + arguments.argc, argv.begin(),
|
||||
[](auto& a) { return _strdup(base::WideToUTF8(a).c_str()); });
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
if (run_as_node) {
|
||||
std::vector<char*> argv(arguments.argc);
|
||||
std::transform(
|
||||
arguments.argv, arguments.argv + arguments.argc, argv.begin(),
|
||||
[](auto& a) { return _strdup(base::WideToUTF8(a).c_str()); });
|
||||
|
||||
base::AtExitManager atexit_manager;
|
||||
base::i18n::InitializeICU();
|
||||
auto ret = atom::NodeMain(argv.size(), argv.data());
|
||||
@@ -134,8 +164,11 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) {
|
||||
return crash_service::Main(cmd);
|
||||
base::CommandLine::Init(argv.size(), argv.data());
|
||||
const base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess();
|
||||
if (cmd_line.GetSwitchValueASCII("type") ==
|
||||
crash_reporter::kCrashpadProcess) {
|
||||
return crash_service::Main(&argv);
|
||||
}
|
||||
|
||||
if (!atom::CheckCommandLineArguments(arguments.argc, arguments.argv))
|
||||
@@ -155,8 +188,10 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
#elif defined(OS_LINUX) // defined(OS_WIN)
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
FixStdioStreams();
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
if (IsEnvSet(kRunAsNode)) {
|
||||
if (IsEnvSet(atom::kRunAsNode)) {
|
||||
base::i18n::InitializeICU();
|
||||
base::AtExitManager atexit_manager;
|
||||
return atom::NodeMain(argc, argv);
|
||||
@@ -174,12 +209,43 @@ int main(int argc, char* argv[]) {
|
||||
#else // defined(OS_LINUX)
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
FixStdioStreams();
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
if (IsEnvSet(kRunAsNode)) {
|
||||
if (IsEnvSet(atom::kRunAsNode)) {
|
||||
return AtomInitializeICUandStartNode(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HELPER_EXECUTABLE) && !defined(MAS_BUILD)
|
||||
uint32_t exec_path_size = 0;
|
||||
int rv = _NSGetExecutablePath(NULL, &exec_path_size);
|
||||
if (rv != -1) {
|
||||
fprintf(stderr, "_NSGetExecutablePath: get length failed\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
std::unique_ptr<char[]> exec_path(new char[exec_path_size]);
|
||||
rv = _NSGetExecutablePath(exec_path.get(), &exec_path_size);
|
||||
if (rv != 0) {
|
||||
fprintf(stderr, "_NSGetExecutablePath: get path failed\n");
|
||||
abort();
|
||||
}
|
||||
sandbox::SeatbeltExecServer::CreateFromArgumentsResult seatbelt =
|
||||
sandbox::SeatbeltExecServer::CreateFromArguments(exec_path.get(), argc,
|
||||
argv);
|
||||
if (seatbelt.sandbox_required) {
|
||||
if (!seatbelt.server) {
|
||||
fprintf(stderr, "Failed to create seatbelt sandbox server.\n");
|
||||
abort();
|
||||
}
|
||||
if (!seatbelt.server->InitializeSandbox()) {
|
||||
fprintf(stderr, "Failed to initialize sandbox.\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif // defined(HELPER_EXECUTABLE) && !defined(MAS_BUILD)
|
||||
|
||||
return AtomMain(argc, argv);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,10 +8,13 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#include <glib.h> // for g_setenv()
|
||||
#endif
|
||||
|
||||
#include "atom/app/atom_content_client.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/relauncher.h"
|
||||
#include "atom/common/google_api_key.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "atom/renderer/atom_renderer_client.h"
|
||||
#include "atom/renderer/atom_sandboxed_renderer_client.h"
|
||||
@@ -20,12 +23,17 @@
|
||||
#include "base/debug/stack_trace.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/path_service.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "ipc/ipc_buildflags.h"
|
||||
#include "services/service_manager/embedder/switches.h"
|
||||
#include "services/service_manager/sandbox/switches.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
#include "ui/base/ui_base_switches.h"
|
||||
|
||||
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
|
||||
#define IPC_MESSAGE_MACROS_LOG_ENABLED
|
||||
@@ -39,6 +47,13 @@
|
||||
#include "atom/app/atom_main_delegate_mac.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/win/win_util.h"
|
||||
#if defined(_WIN64)
|
||||
#include "atom/common/crash_reporter/crash_reporter_win.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
@@ -50,6 +65,25 @@ bool IsBrowserProcess(base::CommandLine* cmd) {
|
||||
return process_type.empty();
|
||||
}
|
||||
|
||||
// Returns true if this subprocess type needs the ResourceBundle initialized
|
||||
// and resources loaded.
|
||||
bool SubprocessNeedsResourceBundle(const std::string& process_type) {
|
||||
return
|
||||
#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
||||
// The zygote process opens the resources for the renderers.
|
||||
process_type == service_manager::switches::kZygoteProcess ||
|
||||
#endif
|
||||
#if defined(OS_MACOSX)
|
||||
// Mac needs them too for scrollbar related images and for sandbox
|
||||
// profiles.
|
||||
process_type == ::switches::kPpapiPluginProcess ||
|
||||
process_type == ::switches::kPpapiBrokerProcess ||
|
||||
process_type == ::switches::kGpuProcess ||
|
||||
#endif
|
||||
process_type == ::switches::kRendererProcess ||
|
||||
process_type == ::switches::kUtilityProcess;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void InvalidParameterHandler(const wchar_t*,
|
||||
const wchar_t*,
|
||||
@@ -62,6 +96,37 @@ void InvalidParameterHandler(const wchar_t*,
|
||||
|
||||
} // namespace
|
||||
|
||||
void LoadResourceBundle(const std::string& locale) {
|
||||
const bool initialized = ui::ResourceBundle::HasSharedInstance();
|
||||
if (initialized)
|
||||
ui::ResourceBundle::CleanupSharedInstance();
|
||||
|
||||
// Load other resource files.
|
||||
base::FilePath pak_dir;
|
||||
#if defined(OS_MACOSX)
|
||||
pak_dir =
|
||||
base::mac::FrameworkBundlePath().Append(FILE_PATH_LITERAL("Resources"));
|
||||
#else
|
||||
base::PathService::Get(base::DIR_MODULE, &pak_dir);
|
||||
#endif
|
||||
|
||||
ui::ResourceBundle::InitSharedInstanceWithLocale(
|
||||
locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
|
||||
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
|
||||
bundle.ReloadLocaleResources(locale);
|
||||
bundle.AddDataPackFromPath(pak_dir.Append(FILE_PATH_LITERAL("resources.pak")),
|
||||
ui::SCALE_FACTOR_NONE);
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
NOTIMPLEMENTED()
|
||||
<< "Hi, whoever's fixing PDF support! Thanks! The pdf "
|
||||
"viewer resources haven't been ported over to the GN build yet, so "
|
||||
"you'll probably need to change this bit of code.";
|
||||
bundle.AddDataPackFromPath(
|
||||
pak_dir.Append(FILE_PATH_LITERAL("pdf_viewer_resources.pak")),
|
||||
ui::GetSupportedScaleFactors()[0]);
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
}
|
||||
|
||||
AtomMainDelegate::AtomMainDelegate() {}
|
||||
|
||||
AtomMainDelegate::~AtomMainDelegate() {}
|
||||
@@ -71,6 +136,10 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
|
||||
logging::LoggingSettings settings;
|
||||
#if defined(OS_WIN)
|
||||
#if defined(_WIN64)
|
||||
crash_reporter::CrashReporterWin::SetUnhandledExceptionFilter();
|
||||
#endif
|
||||
|
||||
// On Windows the terminal returns immediately, so we add a new line to
|
||||
// prevent output in the same line as the prompt.
|
||||
if (IsBrowserProcess(command_line))
|
||||
@@ -82,10 +151,12 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
settings.lock_log = logging::LOCK_LOG_FILE;
|
||||
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
|
||||
#else
|
||||
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
||||
settings.logging_dest =
|
||||
logging::LOG_TO_SYSTEM_DEBUG_LOG | logging::LOG_TO_STDERR;
|
||||
#endif // defined(DEBUG)
|
||||
#else // defined(OS_WIN)
|
||||
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
||||
settings.logging_dest =
|
||||
logging::LOG_TO_SYSTEM_DEBUG_LOG | logging::LOG_TO_STDERR;
|
||||
#endif // !defined(OS_WIN)
|
||||
|
||||
// Only enable logging when --enable-logging is specified.
|
||||
@@ -101,23 +172,19 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
// Logging with pid and timestamp.
|
||||
logging::SetLogItems(true, false, true, false);
|
||||
|
||||
// Enable convient stack printing.
|
||||
#if defined(DEBUG) && defined(OS_LINUX)
|
||||
bool enable_stack_dumping = true;
|
||||
#else
|
||||
bool enable_stack_dumping = env->HasVar("ELECTRON_ENABLE_STACK_DUMPING");
|
||||
#endif
|
||||
#if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
|
||||
// For 32bit ARM enabling stack printing would end up crashing.
|
||||
// https://github.com/electron/electron/pull/11230#issuecomment-363232482
|
||||
enable_stack_dumping = false;
|
||||
#endif
|
||||
if (enable_stack_dumping)
|
||||
// Enable convient stack printing. This is enabled by default in non-official
|
||||
// builds.
|
||||
if (env->HasVar("ELECTRON_ENABLE_STACK_DUMPING"))
|
||||
base::debug::EnableInProcessStackDumping();
|
||||
|
||||
if (env->HasVar("ELECTRON_DISABLE_SANDBOX"))
|
||||
command_line->AppendSwitch(service_manager::switches::kNoSandbox);
|
||||
|
||||
chrome::RegisterPathProvider();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
OverrideChildProcessPath();
|
||||
OverrideFrameworkBundlePath();
|
||||
SetUpBundleOverrides();
|
||||
#endif
|
||||
|
||||
@@ -127,32 +194,65 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
// Disable the ActiveVerifier, which is used by Chrome to track possible
|
||||
// bugs, but no use in Electron.
|
||||
base::win::DisableHandleVerifier();
|
||||
|
||||
if (IsBrowserProcess(command_line))
|
||||
base::win::PinUser32();
|
||||
#endif
|
||||
|
||||
return brightray::MainDelegate::BasicStartupComplete(exit_code);
|
||||
content_client_ = std::make_unique<AtomContentClient>();
|
||||
SetContentClient(content_client_.get());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AtomMainDelegate::PostEarlyInitialization(bool is_running_tests) {
|
||||
std::string custom_locale;
|
||||
ui::ResourceBundle::InitSharedInstanceWithLocale(
|
||||
custom_locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
|
||||
auto* cmd_line = base::CommandLine::ForCurrentProcess();
|
||||
if (cmd_line->HasSwitch(::switches::kLang)) {
|
||||
const std::string locale = cmd_line->GetSwitchValueASCII(::switches::kLang);
|
||||
const base::FilePath locale_file_path =
|
||||
ui::ResourceBundle::GetSharedInstance().GetLocaleFilePath(locale, true);
|
||||
if (!locale_file_path.empty()) {
|
||||
custom_locale = locale;
|
||||
#if defined(OS_LINUX)
|
||||
/* When built with USE_GLIB, libcc's GetApplicationLocaleInternal() uses
|
||||
* glib's g_get_language_names(), which keys off of getenv("LC_ALL") */
|
||||
g_setenv("LC_ALL", custom_locale.c_str(), TRUE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
if (custom_locale.empty())
|
||||
l10n_util::OverrideLocaleWithCocoaLocale();
|
||||
#endif
|
||||
|
||||
LoadResourceBundle(custom_locale);
|
||||
|
||||
AtomBrowserClient::SetApplicationLocale(
|
||||
l10n_util::GetApplicationLocale(custom_locale));
|
||||
}
|
||||
|
||||
void AtomMainDelegate::PreSandboxStartup() {
|
||||
brightray::MainDelegate::PreSandboxStartup();
|
||||
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
std::string process_type =
|
||||
command_line->GetSwitchValueASCII(::switches::kProcessType);
|
||||
|
||||
// Initialize ResourceBundle which handles files loaded from external
|
||||
// sources. The language should have been passed in to us from the
|
||||
// browser process as a command line flag.
|
||||
if (SubprocessNeedsResourceBundle(process_type)) {
|
||||
std::string locale = command_line->GetSwitchValueASCII(::switches::kLang);
|
||||
LoadResourceBundle(locale);
|
||||
}
|
||||
|
||||
// Only append arguments for browser process.
|
||||
if (!IsBrowserProcess(command_line))
|
||||
return;
|
||||
|
||||
if (!command_line->HasSwitch(switches::kEnableMixedSandbox)) {
|
||||
if (command_line->HasSwitch(switches::kEnableSandbox)) {
|
||||
// Disable setuid sandbox since it is not longer required on
|
||||
// linux(namespace sandbox is available on most distros).
|
||||
command_line->AppendSwitch(
|
||||
service_manager::switches::kDisableSetuidSandbox);
|
||||
} else {
|
||||
// Disable renderer sandbox for most of node's functions.
|
||||
command_line->AppendSwitch(service_manager::switches::kNoSandbox);
|
||||
}
|
||||
}
|
||||
|
||||
// Allow file:// URIs to read other file:// URIs by default.
|
||||
command_line->AppendSwitch(::switches::kAllowFileAccessFromFiles);
|
||||
|
||||
@@ -162,7 +262,7 @@ void AtomMainDelegate::PreSandboxStartup() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void AtomMainDelegate::PreContentInitialization() {
|
||||
void AtomMainDelegate::PreCreateMainMessageLoop() {
|
||||
#if defined(OS_MACOSX)
|
||||
RegisterAtomCrApp();
|
||||
#endif
|
||||
@@ -212,9 +312,12 @@ bool AtomMainDelegate::DelaySandboxInitialization(
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<brightray::ContentClient>
|
||||
AtomMainDelegate::CreateContentClient() {
|
||||
return std::make_unique<AtomContentClient>();
|
||||
bool AtomMainDelegate::ShouldLockSchemeRegistry() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomMainDelegate::ShouldCreateFeatureList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "brightray/common/content_client.h"
|
||||
#include "brightray/common/main_delegate.h"
|
||||
#include "content/public/app/content_main_delegate.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomMainDelegate : public brightray::MainDelegate {
|
||||
void LoadResourceBundle(const std::string& locale);
|
||||
|
||||
class AtomMainDelegate : public content::ContentMainDelegate {
|
||||
public:
|
||||
AtomMainDelegate();
|
||||
~AtomMainDelegate() override;
|
||||
@@ -22,7 +24,8 @@ class AtomMainDelegate : public brightray::MainDelegate {
|
||||
// content::ContentMainDelegate:
|
||||
bool BasicStartupComplete(int* exit_code) override;
|
||||
void PreSandboxStartup() override;
|
||||
void PreContentInitialization() override;
|
||||
void PreCreateMainMessageLoop() override;
|
||||
void PostEarlyInitialization(bool is_running_tests) override;
|
||||
content::ContentBrowserClient* CreateContentBrowserClient() override;
|
||||
content::ContentRendererClient* CreateContentRendererClient() override;
|
||||
content::ContentUtilityClient* CreateContentUtilityClient() override;
|
||||
@@ -33,20 +36,18 @@ class AtomMainDelegate : public brightray::MainDelegate {
|
||||
bool ShouldSendMachPort(const std::string& process_type) override;
|
||||
bool DelaySandboxInitialization(const std::string& process_type) override;
|
||||
#endif
|
||||
|
||||
// brightray::MainDelegate:
|
||||
std::unique_ptr<brightray::ContentClient> CreateContentClient() override;
|
||||
#if defined(OS_MACOSX)
|
||||
void OverrideChildProcessPath() override;
|
||||
void OverrideFrameworkBundlePath() override;
|
||||
#endif
|
||||
bool ShouldLockSchemeRegistry() override;
|
||||
bool ShouldCreateFeatureList() override;
|
||||
|
||||
private:
|
||||
#if defined(OS_MACOSX)
|
||||
void OverrideChildProcessPath();
|
||||
void OverrideFrameworkBundlePath();
|
||||
void SetUpBundleOverrides();
|
||||
#endif
|
||||
|
||||
std::unique_ptr<content::ContentBrowserClient> browser_client_;
|
||||
std::unique_ptr<content::ContentClient> content_client_;
|
||||
std::unique_ptr<content::ContentRendererClient> renderer_client_;
|
||||
std::unique_ptr<content::ContentUtilityClient> utility_client_;
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
|
||||
#include "atom/browser/mac/atom_application.h"
|
||||
#include "atom/common/application_info.h"
|
||||
#include "atom/common/mac/main_application_bundle.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
@@ -12,8 +14,6 @@
|
||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
#include "brightray/common/mac/main_application_bundle.h"
|
||||
#include "content/public/common/content_paths.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -21,9 +21,7 @@ namespace atom {
|
||||
namespace {
|
||||
|
||||
base::FilePath GetFrameworksPath() {
|
||||
return brightray::MainApplicationBundlePath()
|
||||
.Append("Contents")
|
||||
.Append("Frameworks");
|
||||
return MainApplicationBundlePath().Append("Contents").Append("Frameworks");
|
||||
}
|
||||
|
||||
base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
|
||||
@@ -46,8 +44,7 @@ void AtomMainDelegate::OverrideChildProcessPath() {
|
||||
base::FilePath helper_path =
|
||||
GetHelperAppPath(frameworks_path, ATOM_PRODUCT_NAME);
|
||||
if (!base::PathExists(helper_path))
|
||||
helper_path =
|
||||
GetHelperAppPath(frameworks_path, brightray::GetApplicationName());
|
||||
helper_path = GetHelperAppPath(frameworks_path, GetApplicationName());
|
||||
if (!base::PathExists(helper_path))
|
||||
LOG(FATAL) << "Unable to find helper app";
|
||||
base::PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
|
||||
@@ -55,7 +52,7 @@ void AtomMainDelegate::OverrideChildProcessPath() {
|
||||
|
||||
void AtomMainDelegate::SetUpBundleOverrides() {
|
||||
base::mac::ScopedNSAutoreleasePool pool;
|
||||
NSBundle* bundle = brightray::MainApplicationBundle();
|
||||
NSBundle* bundle = MainApplicationBundle();
|
||||
std::string base_bundle_id =
|
||||
base::SysNSStringToUTF8([bundle bundleIdentifier]);
|
||||
NSString* team_id = [bundle objectForInfoDictionaryKey:@"ElectronTeamID"];
|
||||
|
||||
65
atom/app/manifests.cc
Normal file
65
atom/app/manifests.cc
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/app/manifests.h"
|
||||
|
||||
#include "base/no_destructor.h"
|
||||
#include "electron/atom/common/api/api.mojom.h"
|
||||
#include "printing/buildflags/buildflags.h"
|
||||
#include "services/proxy_resolver/public/cpp/manifest.h"
|
||||
#include "services/service_manager/public/cpp/manifest_builder.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
#include "components/services/pdf_compositor/public/cpp/manifest.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||
#include "chrome/services/printing/public/cpp/manifest.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
// TODO(https://crbug.com/781334): Remove these helpers and just update the
|
||||
// manifest definitions to be marked out-of-process. This is here only to avoid
|
||||
// extra churn when transitioning away from content_packaged_services.
|
||||
service_manager::Manifest MakeOutOfProcess(
|
||||
const service_manager::Manifest& manifest) {
|
||||
// cpplint.py emits a false positive [build/include_what_you_use]
|
||||
service_manager::Manifest copy(manifest); // NOLINT
|
||||
copy.options.execution_mode =
|
||||
service_manager::Manifest::ExecutionMode::kOutOfProcessBuiltin;
|
||||
return copy;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const service_manager::Manifest& GetElectronContentBrowserOverlayManifest() {
|
||||
static base::NoDestructor<service_manager::Manifest> manifest{
|
||||
service_manager::ManifestBuilder()
|
||||
.WithDisplayName("Electron (browser process)")
|
||||
.RequireCapability("device", "device:geolocation_control")
|
||||
.RequireCapability("proxy_resolver", "factory")
|
||||
.RequireCapability("chrome_printing", "converter")
|
||||
.RequireCapability("pdf_compositor", "compositor")
|
||||
.ExposeInterfaceFilterCapability_Deprecated(
|
||||
"navigation:frame", "renderer",
|
||||
service_manager::Manifest::InterfaceList<
|
||||
atom::mojom::ElectronBrowser>())
|
||||
.Build()};
|
||||
return *manifest;
|
||||
}
|
||||
|
||||
const std::vector<service_manager::Manifest>&
|
||||
GetElectronBuiltinServiceManifests() {
|
||||
static base::NoDestructor<std::vector<service_manager::Manifest>> manifests{{
|
||||
MakeOutOfProcess(proxy_resolver::GetManifest()),
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
MakeOutOfProcess(printing::GetPdfCompositorManifest()),
|
||||
#endif
|
||||
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||
MakeOutOfProcess(GetChromePrintingManifest()),
|
||||
#endif
|
||||
}};
|
||||
return *manifests;
|
||||
}
|
||||
16
atom/app/manifests.h
Normal file
16
atom/app/manifests.h
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_APP_MANIFESTS_H_
|
||||
#define ATOM_APP_MANIFESTS_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "services/service_manager/public/cpp/manifest.h"
|
||||
|
||||
const service_manager::Manifest& GetElectronContentBrowserOverlayManifest();
|
||||
const std::vector<service_manager::Manifest>&
|
||||
GetElectronBuiltinServiceManifests();
|
||||
|
||||
#endif // ATOM_APP_MANIFESTS_H_
|
||||
@@ -10,20 +10,24 @@
|
||||
#include "atom/app/uv_task_runner.h"
|
||||
#include "atom/browser/javascript_environment.h"
|
||||
#include "atom/browser/node_debugger.h"
|
||||
#include "atom/common/api/atom_bindings.h"
|
||||
#include "atom/common/api/electron_bindings.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/crash_reporter/crash_reporter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/node_bindings.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/task_scheduler/task_scheduler.h"
|
||||
#include "base/task/thread_pool/thread_pool.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "gin/array_buffer.h"
|
||||
#include "gin/public/isolate_holder.h"
|
||||
#include "gin/v8_initializer.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
#if defined(_WIN64)
|
||||
#include "atom/common/crash_reporter/crash_reporter_win.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -48,10 +52,13 @@ int NodeMain(int argc, char* argv[]) {
|
||||
gin::V8Initializer::LoadV8Natives();
|
||||
|
||||
// V8 requires a task scheduler apparently
|
||||
base::TaskScheduler::CreateAndStartWithDefaultParams("Electron");
|
||||
base::ThreadPoolInstance::CreateAndStartWithDefaultParams("Electron");
|
||||
|
||||
// Initialize gin::IsolateHolder.
|
||||
JavascriptEnvironment gin_env(loop);
|
||||
#if defined(_WIN64)
|
||||
crash_reporter::CrashReporterWin::SetUnhandledExceptionFilter();
|
||||
#endif
|
||||
|
||||
// Explicitly register electron's builtin modules.
|
||||
NodeBindings::RegisterBuiltinModules();
|
||||
@@ -70,15 +77,20 @@ int NodeMain(int argc, char* argv[]) {
|
||||
|
||||
mate::Dictionary process(gin_env.isolate(), env->process_object());
|
||||
#if defined(OS_WIN)
|
||||
process.SetMethod("log", &AtomBindings::Log);
|
||||
process.SetMethod("log", &ElectronBindings::Log);
|
||||
#endif
|
||||
process.SetMethod("crash", &AtomBindings::Crash);
|
||||
process.SetMethod("crash", &ElectronBindings::Crash);
|
||||
|
||||
// Setup process.crashReporter.start in child node processes
|
||||
auto reporter = mate::Dictionary::CreateEmpty(gin_env.isolate());
|
||||
reporter.SetMethod("start", &crash_reporter::CrashReporter::StartInstance);
|
||||
process.Set("crashReporter", reporter);
|
||||
|
||||
mate::Dictionary versions;
|
||||
if (process.Get("versions", &versions)) {
|
||||
versions.SetReadOnly(ATOM_PROJECT_NAME, ATOM_VERSION_STRING);
|
||||
}
|
||||
|
||||
node::LoadEnvironment(env);
|
||||
|
||||
bool more;
|
||||
@@ -96,6 +108,7 @@ int NodeMain(int argc, char* argv[]) {
|
||||
}
|
||||
} while (more == true);
|
||||
|
||||
node_debugger.Stop();
|
||||
exit_code = node::EmitExit(env);
|
||||
node::RunAtExit(env);
|
||||
gin_env.platform()->DrainTasks(env->isolate());
|
||||
@@ -107,10 +120,10 @@ int NodeMain(int argc, char* argv[]) {
|
||||
|
||||
// According to "src/gin/shell/gin_main.cc":
|
||||
//
|
||||
// gin::IsolateHolder waits for tasks running in TaskScheduler in its
|
||||
// destructor and thus must be destroyed before TaskScheduler starts skipping
|
||||
// gin::IsolateHolder waits for tasks running in ThreadPool in its
|
||||
// destructor and thus must be destroyed before ThreadPool starts skipping
|
||||
// CONTINUE_ON_SHUTDOWN tasks.
|
||||
base::TaskScheduler::GetInstance()->Shutdown();
|
||||
base::ThreadPoolInstance::Get()->Shutdown();
|
||||
|
||||
v8::V8::Dispose();
|
||||
|
||||
|
||||
@@ -13,8 +13,10 @@
|
||||
#include "atom/browser/api/gpuinfo_manager.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_paths.h"
|
||||
#include "atom/browser/login_handler.h"
|
||||
#include "atom/browser/relauncher.h"
|
||||
#include "atom/common/application_info.h"
|
||||
#include "atom/common/atom_command_line.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
@@ -30,14 +32,12 @@
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/sys_info.h"
|
||||
#include "brightray/browser/brightray_paths.h"
|
||||
#include "base/system/sys_info.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/browser/icon_manager.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "content/browser/gpu/compositor_util.h"
|
||||
#include "content/browser/gpu/gpu_data_manager_impl.h"
|
||||
#include "content/browser/gpu/compositor_util.h" // nogncheck
|
||||
#include "content/browser/gpu/gpu_data_manager_impl.h" // nogncheck
|
||||
#include "content/public/browser/browser_accessibility_state.h"
|
||||
#include "content/public/browser/browser_child_process_host.h"
|
||||
#include "content/public/browser/child_process_data.h"
|
||||
@@ -49,7 +49,6 @@
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/ssl/client_cert_identity.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
#include "services/network/public/cpp/network_switches.h"
|
||||
#include "services/service_manager/sandbox/switches.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
@@ -60,6 +59,7 @@
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include "atom/browser/ui/cocoa/atom_bundle_mover.h"
|
||||
#endif
|
||||
|
||||
@@ -84,6 +84,7 @@ struct Converter<Browser::UserTask> {
|
||||
return false;
|
||||
dict.Get("arguments", &(out->arguments));
|
||||
dict.Get("description", &(out->description));
|
||||
dict.Get("workingDirectory", &(out->working_dir));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -157,6 +158,7 @@ struct Converter<JumpListItem> {
|
||||
|
||||
dict.Get("args", &(out->arguments));
|
||||
dict.Get("description", &(out->description));
|
||||
dict.Get("workingDirectory", &(out->working_dir));
|
||||
return true;
|
||||
|
||||
case JumpListItem::Type::SEPARATOR:
|
||||
@@ -183,6 +185,7 @@ struct Converter<JumpListItem> {
|
||||
dict.Set("iconPath", val.icon_path);
|
||||
dict.Set("iconIndex", val.icon_index);
|
||||
dict.Set("description", val.description);
|
||||
dict.Set("workingDirectory", val.working_dir);
|
||||
break;
|
||||
|
||||
case JumpListItem::Type::SEPARATOR:
|
||||
@@ -390,15 +393,15 @@ IconLoader::IconSize GetIconSizeByString(const std::string& size) {
|
||||
// Return the path constant from string.
|
||||
int GetPathConstant(const std::string& name) {
|
||||
if (name == "appData")
|
||||
return brightray::DIR_APP_DATA;
|
||||
return DIR_APP_DATA;
|
||||
else if (name == "userData")
|
||||
return brightray::DIR_USER_DATA;
|
||||
return DIR_USER_DATA;
|
||||
else if (name == "cache")
|
||||
return brightray::DIR_CACHE;
|
||||
return DIR_CACHE;
|
||||
else if (name == "userCache")
|
||||
return brightray::DIR_USER_CACHE;
|
||||
return DIR_USER_CACHE;
|
||||
else if (name == "logs")
|
||||
return brightray::DIR_APP_LOGS;
|
||||
return DIR_APP_LOGS;
|
||||
else if (name == "home")
|
||||
return base::DIR_HOME;
|
||||
else if (name == "temp")
|
||||
@@ -529,18 +532,11 @@ int ImportIntoCertStore(CertificateManagerModel* model,
|
||||
}
|
||||
#endif
|
||||
|
||||
void OnIconDataAvailable(v8::Isolate* isolate,
|
||||
const App::FileIconCallback& callback,
|
||||
gfx::Image* icon) {
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
if (icon && !icon->IsEmpty()) {
|
||||
callback.Run(v8::Null(isolate), *icon);
|
||||
void OnIconDataAvailable(util::Promise promise, gfx::Image icon) {
|
||||
if (!icon.IsEmpty()) {
|
||||
promise.Resolve(icon);
|
||||
} else {
|
||||
v8::Local<v8::String> error_message =
|
||||
v8::String::NewFromUtf8(isolate, "Failed to get file icon.");
|
||||
callback.Run(v8::Exception::Error(error_message), gfx::Image());
|
||||
promise.RejectWithErrorMessage("Failed to get file icon.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -678,8 +674,8 @@ void App::OnLogin(scoped_refptr<LoginHandler> login_handler,
|
||||
content::WebContents* web_contents = login_handler->GetWebContents();
|
||||
if (web_contents) {
|
||||
prevent_default = Emit(
|
||||
"login", WebContents::CreateFrom(isolate(), web_contents),
|
||||
request_details, login_handler->auth_info(),
|
||||
"login", WebContents::FromOrCreate(isolate(), web_contents),
|
||||
request_details, *login_handler->auth_info(),
|
||||
base::Bind(&PassLoginInformation, base::RetainedRef(login_handler)));
|
||||
}
|
||||
|
||||
@@ -692,7 +688,7 @@ bool App::CanCreateWindow(
|
||||
content::RenderFrameHost* opener,
|
||||
const GURL& opener_url,
|
||||
const GURL& opener_top_level_frame_url,
|
||||
const GURL& source_origin,
|
||||
const url::Origin& source_origin,
|
||||
content::mojom::WindowContainerType container_type,
|
||||
const GURL& target_url,
|
||||
const content::Referrer& referrer,
|
||||
@@ -709,9 +705,12 @@ bool App::CanCreateWindow(
|
||||
content::WebContents* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(opener);
|
||||
if (web_contents) {
|
||||
auto api_web_contents = WebContents::CreateFrom(isolate(), web_contents);
|
||||
api_web_contents->OnCreateWindow(target_url, referrer, frame_name,
|
||||
disposition, additional_features, body);
|
||||
auto api_web_contents = WebContents::From(isolate(), web_contents);
|
||||
// No need to emit any event if the WebContents is not available in JS.
|
||||
if (!api_web_contents.IsEmpty()) {
|
||||
api_web_contents->OnCreateWindow(target_url, referrer, frame_name,
|
||||
disposition, additional_features, body);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -722,7 +721,7 @@ void App::AllowCertificateError(
|
||||
int cert_error,
|
||||
const net::SSLInfo& ssl_info,
|
||||
const GURL& request_url,
|
||||
content::ResourceType resource_type,
|
||||
bool is_main_frame_request,
|
||||
bool strict_enforcement,
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(content::CertificateRequestResultType)>&
|
||||
@@ -730,7 +729,7 @@ void App::AllowCertificateError(
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
bool prevent_default = Emit(
|
||||
"certificate-error", WebContents::CreateFrom(isolate(), web_contents),
|
||||
"certificate-error", WebContents::FromOrCreate(isolate(), web_contents),
|
||||
request_url, net::ErrorToString(cert_error), ssl_info.cert, callback);
|
||||
|
||||
// Deny the certificate by default.
|
||||
@@ -757,7 +756,7 @@ void App::SelectClientCertificate(
|
||||
|
||||
bool prevent_default =
|
||||
Emit("select-client-certificate",
|
||||
WebContents::CreateFrom(isolate(), web_contents),
|
||||
WebContents::FromOrCreate(isolate(), web_contents),
|
||||
cert_request_info->host_and_port.ToString(), std::move(client_certs),
|
||||
base::Bind(&OnClientCertificateSelected, isolate(), shared_delegate,
|
||||
shared_identities));
|
||||
@@ -779,24 +778,24 @@ void App::OnGpuProcessCrashed(base::TerminationStatus status) {
|
||||
|
||||
void App::BrowserChildProcessLaunchedAndConnected(
|
||||
const content::ChildProcessData& data) {
|
||||
ChildProcessLaunched(data.process_type, data.handle);
|
||||
ChildProcessLaunched(data.process_type, data.GetProcess().Handle());
|
||||
}
|
||||
|
||||
void App::BrowserChildProcessHostDisconnected(
|
||||
const content::ChildProcessData& data) {
|
||||
ChildProcessDisconnected(base::GetProcId(data.handle));
|
||||
ChildProcessDisconnected(base::GetProcId(data.GetProcess().Handle()));
|
||||
}
|
||||
|
||||
void App::BrowserChildProcessCrashed(
|
||||
const content::ChildProcessData& data,
|
||||
const content::ChildProcessTerminationInfo& info) {
|
||||
ChildProcessDisconnected(base::GetProcId(data.handle));
|
||||
ChildProcessDisconnected(base::GetProcId(data.GetProcess().Handle()));
|
||||
}
|
||||
|
||||
void App::BrowserChildProcessKilled(
|
||||
const content::ChildProcessData& data,
|
||||
const content::ChildProcessTerminationInfo& info) {
|
||||
ChildProcessDisconnected(base::GetProcId(data.handle));
|
||||
ChildProcessDisconnected(base::GetProcId(data.GetProcess().Handle()));
|
||||
}
|
||||
|
||||
void App::RenderProcessReady(content::RenderProcessHost* host) {
|
||||
@@ -835,6 +834,26 @@ void App::SetAppPath(const base::FilePath& app_path) {
|
||||
app_path_ = app_path;
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
void App::SetAppLogsPath(mate::Arguments* args) {
|
||||
base::FilePath custom_path;
|
||||
if (args->GetNext(&custom_path)) {
|
||||
if (!custom_path.IsAbsolute()) {
|
||||
args->ThrowError("Path must be absolute");
|
||||
return;
|
||||
}
|
||||
base::PathService::Override(DIR_APP_LOGS, custom_path);
|
||||
} else {
|
||||
base::FilePath path;
|
||||
if (base::PathService::Get(DIR_USER_DATA, &path)) {
|
||||
path = path.Append(base::FilePath::FromUTF8Unsafe(GetApplicationName()));
|
||||
path = path.Append(base::FilePath::FromUTF8Unsafe("logs"));
|
||||
base::PathService::Override(DIR_APP_LOGS, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
|
||||
bool succeed = false;
|
||||
base::FilePath path;
|
||||
@@ -874,6 +893,45 @@ std::string App::GetLocale() {
|
||||
return g_browser_process->GetApplicationLocale();
|
||||
}
|
||||
|
||||
std::string App::GetLocaleCountryCode() {
|
||||
std::string region;
|
||||
#if defined(OS_WIN)
|
||||
WCHAR locale_name[LOCALE_NAME_MAX_LENGTH] = {0};
|
||||
|
||||
if (GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SISO3166CTRYNAME,
|
||||
(LPWSTR)&locale_name,
|
||||
sizeof(locale_name) / sizeof(WCHAR)) ||
|
||||
GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_SISO3166CTRYNAME,
|
||||
(LPWSTR)&locale_name,
|
||||
sizeof(locale_name) / sizeof(WCHAR))) {
|
||||
base::WideToUTF8(locale_name, wcslen(locale_name), ®ion);
|
||||
}
|
||||
#elif defined(OS_MACOSX)
|
||||
CFLocaleRef locale = CFLocaleCopyCurrent();
|
||||
CFStringRef value = CFStringRef(
|
||||
static_cast<CFTypeRef>(CFLocaleGetValue(locale, kCFLocaleCountryCode)));
|
||||
const CFIndex kCStringSize = 128;
|
||||
char temporaryCString[kCStringSize] = {0};
|
||||
CFStringGetCString(value, temporaryCString, kCStringSize,
|
||||
kCFStringEncodingUTF8);
|
||||
region = temporaryCString;
|
||||
#else
|
||||
const char* locale_ptr = setlocale(LC_TIME, NULL);
|
||||
if (!locale_ptr)
|
||||
locale_ptr = setlocale(LC_NUMERIC, NULL);
|
||||
if (locale_ptr) {
|
||||
std::string locale = locale_ptr;
|
||||
std::string::size_type rpos = locale.find('.');
|
||||
if (rpos != std::string::npos)
|
||||
locale = locale.substr(0, rpos);
|
||||
rpos = locale.find('_');
|
||||
if (rpos != std::string::npos && rpos + 1 < locale.size())
|
||||
region = locale.substr(rpos + 1);
|
||||
}
|
||||
#endif
|
||||
return region.size() == 2 ? region : std::string();
|
||||
}
|
||||
|
||||
void App::OnSecondInstance(const base::CommandLine::StringVector& cmd,
|
||||
const base::FilePath& cwd) {
|
||||
Emit("second-instance", cmd, cwd);
|
||||
@@ -890,7 +948,7 @@ bool App::RequestSingleInstanceLock() {
|
||||
return true;
|
||||
|
||||
base::FilePath user_dir;
|
||||
base::PathService::Get(brightray::DIR_USER_DATA, &user_dir);
|
||||
base::PathService::Get(DIR_USER_DATA, &user_dir);
|
||||
|
||||
auto cb = base::Bind(&App::OnSecondInstance, base::Unretained(this));
|
||||
|
||||
@@ -976,7 +1034,14 @@ bool App::IsAccessibilitySupportEnabled() {
|
||||
return ax_state->IsAccessibleBrowser();
|
||||
}
|
||||
|
||||
void App::SetAccessibilitySupportEnabled(bool enabled) {
|
||||
void App::SetAccessibilitySupportEnabled(bool enabled, mate::Arguments* args) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
args->ThrowError(
|
||||
"app.setAccessibilitySupportEnabled() can only be called "
|
||||
"after app is ready");
|
||||
return;
|
||||
}
|
||||
|
||||
auto* ax_state = content::BrowserAccessibilityState::GetInstance();
|
||||
if (enabled) {
|
||||
ax_state->OnScreenReaderDetected();
|
||||
@@ -994,7 +1059,7 @@ Browser::LoginItemSettings App::GetLoginItemSettings(mate::Arguments* args) {
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void App::ImportCertificate(const base::DictionaryValue& options,
|
||||
const net::CompletionCallback& callback) {
|
||||
net::CompletionRepeatingCallback callback) {
|
||||
auto browser_context = AtomBrowserContext::From("", false);
|
||||
if (!certificate_manager_model_) {
|
||||
auto copy = base::DictionaryValue::From(
|
||||
@@ -1007,17 +1072,17 @@ void App::ImportCertificate(const base::DictionaryValue& options,
|
||||
}
|
||||
|
||||
int rv = ImportIntoCertStore(certificate_manager_model_.get(), options);
|
||||
callback.Run(rv);
|
||||
std::move(callback).Run(rv);
|
||||
}
|
||||
|
||||
void App::OnCertificateManagerModelCreated(
|
||||
std::unique_ptr<base::DictionaryValue> options,
|
||||
const net::CompletionCallback& callback,
|
||||
net::CompletionOnceCallback callback,
|
||||
std::unique_ptr<CertificateManagerModel> model) {
|
||||
certificate_manager_model_ = std::move(model);
|
||||
int rv =
|
||||
ImportIntoCertStore(certificate_manager_model_.get(), *(options.get()));
|
||||
callback.Run(rv);
|
||||
std::move(callback).Run(rv);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1077,16 +1142,14 @@ JumpListResult App::SetJumpList(v8::Local<v8::Value> val,
|
||||
}
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
void App::GetFileIcon(const base::FilePath& path, mate::Arguments* args) {
|
||||
mate::Dictionary options;
|
||||
IconLoader::IconSize icon_size;
|
||||
FileIconCallback callback;
|
||||
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
|
||||
v8::Local<v8::Promise> App::GetFileIcon(const base::FilePath& path,
|
||||
mate::Arguments* args) {
|
||||
util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
base::FilePath normalized_path = path.NormalizePathSeparators();
|
||||
|
||||
IconLoader::IconSize icon_size;
|
||||
mate::Dictionary options;
|
||||
if (!args->GetNext(&options)) {
|
||||
icon_size = IconLoader::IconSize::NORMAL;
|
||||
} else {
|
||||
@@ -1095,26 +1158,23 @@ void App::GetFileIcon(const base::FilePath& path, mate::Arguments* args) {
|
||||
icon_size = GetIconSizeByString(icon_size_string);
|
||||
}
|
||||
|
||||
if (!args->GetNext(&callback)) {
|
||||
args->ThrowError("Missing required callback function");
|
||||
return;
|
||||
}
|
||||
|
||||
auto* icon_manager = AtomBrowserMainParts::Get()->GetIconManager();
|
||||
gfx::Image* icon =
|
||||
icon_manager->LookupIconFromFilepath(normalized_path, icon_size);
|
||||
if (icon) {
|
||||
callback.Run(v8::Null(isolate()), *icon);
|
||||
promise.Resolve(*icon);
|
||||
} else {
|
||||
icon_manager->LoadIcon(
|
||||
normalized_path, icon_size,
|
||||
base::Bind(&OnIconDataAvailable, isolate(), callback),
|
||||
base::BindOnce(&OnIconDataAvailable, std::move(promise)),
|
||||
&cancelable_task_tracker_);
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
std::vector<mate::Dictionary> App::GetAppMetrics(v8::Isolate* isolate) {
|
||||
std::vector<mate::Dictionary> result;
|
||||
result.reserve(app_metrics_.size());
|
||||
int processor_count = base::SysInfo::NumberOfProcessors();
|
||||
|
||||
for (const auto& process_metric : app_metrics_) {
|
||||
@@ -1158,30 +1218,30 @@ v8::Local<v8::Value> App::GetGPUFeatureStatus(v8::Isolate* isolate) {
|
||||
v8::Local<v8::Promise> App::GetGPUInfo(v8::Isolate* isolate,
|
||||
const std::string& info_type) {
|
||||
auto* const gpu_data_manager = content::GpuDataManagerImpl::GetInstance();
|
||||
scoped_refptr<util::Promise> promise = new util::Promise(isolate);
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
if (info_type != "basic" && info_type != "complete") {
|
||||
promise->RejectWithErrorMessage(
|
||||
promise.RejectWithErrorMessage(
|
||||
"Invalid info type. Use 'basic' or 'complete'");
|
||||
return promise->GetHandle();
|
||||
return handle;
|
||||
}
|
||||
std::string reason;
|
||||
if (!gpu_data_manager->GpuAccessAllowed(&reason)) {
|
||||
promise->RejectWithErrorMessage("GPU access not allowed. Reason: " +
|
||||
reason);
|
||||
return promise->GetHandle();
|
||||
promise.RejectWithErrorMessage("GPU access not allowed. Reason: " + reason);
|
||||
return handle;
|
||||
}
|
||||
|
||||
auto* const info_mgr = GPUInfoManager::GetInstance();
|
||||
if (info_type == "complete") {
|
||||
#if defined(OS_WIN)
|
||||
info_mgr->FetchCompleteInfo(promise);
|
||||
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||
info_mgr->FetchCompleteInfo(std::move(promise));
|
||||
#else
|
||||
info_mgr->FetchBasicInfo(promise);
|
||||
info_mgr->FetchBasicInfo(std::move(promise));
|
||||
#endif
|
||||
} else /* (info_type == "basic") */ {
|
||||
info_mgr->FetchBasicInfo(promise);
|
||||
info_mgr->FetchBasicInfo(std::move(promise));
|
||||
}
|
||||
return promise->GetHandle();
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void RemoveNoSandboxSwitch(base::CommandLine* command_line) {
|
||||
@@ -1211,17 +1271,19 @@ void App::EnableSandbox(mate::Arguments* args) {
|
||||
command_line->AppendSwitch(switches::kEnableSandbox);
|
||||
}
|
||||
|
||||
void App::EnableMixedSandbox(mate::Arguments* args) {
|
||||
if (Browser::Get()->is_ready()) {
|
||||
args->ThrowError(
|
||||
"app.enableMixedSandbox() can only be called "
|
||||
"before app is ready");
|
||||
return;
|
||||
}
|
||||
void App::SetUserAgentFallback(const std::string& user_agent) {
|
||||
AtomBrowserClient::Get()->SetUserAgent(user_agent);
|
||||
}
|
||||
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
RemoveNoSandboxSwitch(command_line);
|
||||
command_line->AppendSwitch(switches::kEnableMixedSandbox);
|
||||
std::string App::GetUserAgentFallback() {
|
||||
return AtomBrowserClient::Get()->GetUserAgent();
|
||||
}
|
||||
|
||||
void App::SetBrowserClientCanUseCustomSiteInstance(bool should_disable) {
|
||||
AtomBrowserClient::Get()->SetCanUseCustomSiteInstance(should_disable);
|
||||
}
|
||||
bool App::CanBrowserClientUseCustomSiteInstance() {
|
||||
return AtomBrowserClient::Get()->CanUseCustomSiteInstance();
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
@@ -1232,6 +1294,46 @@ bool App::MoveToApplicationsFolder(mate::Arguments* args) {
|
||||
bool App::IsInApplicationsFolder() {
|
||||
return ui::cocoa::AtomBundleMover::IsCurrentAppInApplicationsFolder();
|
||||
}
|
||||
|
||||
int DockBounce(const std::string& type) {
|
||||
int request_id = -1;
|
||||
if (type == "critical")
|
||||
request_id = Browser::Get()->DockBounce(Browser::BOUNCE_CRITICAL);
|
||||
else if (type == "informational")
|
||||
request_id = Browser::Get()->DockBounce(Browser::BOUNCE_INFORMATIONAL);
|
||||
return request_id;
|
||||
}
|
||||
|
||||
void DockSetMenu(atom::api::Menu* menu) {
|
||||
Browser::Get()->DockSetMenu(menu->model());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> App::GetDockAPI(v8::Isolate* isolate) {
|
||||
if (dock_.IsEmpty()) {
|
||||
// Initialize the Dock API, the methods are bound to "dock" which exists
|
||||
// for the lifetime of "app"
|
||||
auto browser = base::Unretained(Browser::Get());
|
||||
mate::Dictionary dock_obj = mate::Dictionary::CreateEmpty(isolate);
|
||||
dock_obj.SetMethod("bounce", &DockBounce);
|
||||
dock_obj.SetMethod("cancelBounce",
|
||||
base::Bind(&Browser::DockCancelBounce, browser));
|
||||
dock_obj.SetMethod("downloadFinished",
|
||||
base::Bind(&Browser::DockDownloadFinished, browser));
|
||||
dock_obj.SetMethod("setBadge",
|
||||
base::Bind(&Browser::DockSetBadgeText, browser));
|
||||
dock_obj.SetMethod("getBadge",
|
||||
base::Bind(&Browser::DockGetBadgeText, browser));
|
||||
dock_obj.SetMethod("hide", base::Bind(&Browser::DockHide, browser));
|
||||
dock_obj.SetMethod("show", base::Bind(&Browser::DockShow, browser));
|
||||
dock_obj.SetMethod("isVisible",
|
||||
base::Bind(&Browser::DockIsVisible, browser));
|
||||
dock_obj.SetMethod("setMenu", &DockSetMenu);
|
||||
dock_obj.SetMethod("setIcon", base::Bind(&Browser::DockSetIcon, browser));
|
||||
|
||||
dock_.Reset(isolate, dock_obj.GetHandle());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, dock_);
|
||||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
@@ -1271,6 +1373,8 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getLoginItemSettings", &App::GetLoginItemSettings)
|
||||
.SetMethod("setLoginItemSettings",
|
||||
base::Bind(&Browser::SetLoginItemSettings, browser))
|
||||
.SetMethod("isEmojiPanelSupported",
|
||||
base::Bind(&Browser::IsEmojiPanelSupported, browser))
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("hide", base::Bind(&Browser::Hide, browser))
|
||||
.SetMethod("show", base::Bind(&Browser::Show, browser))
|
||||
@@ -1282,8 +1386,22 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
||||
base::Bind(&Browser::InvalidateCurrentActivity, browser))
|
||||
.SetMethod("updateCurrentActivity",
|
||||
base::Bind(&Browser::UpdateCurrentActivity, browser))
|
||||
// TODO(juturu): Remove in 2.0, deprecate before then with warnings
|
||||
.SetMethod("moveToApplicationsFolder", &App::MoveToApplicationsFolder)
|
||||
.SetMethod("isInApplicationsFolder", &App::IsInApplicationsFolder)
|
||||
#endif
|
||||
#if defined(OS_MACOSX) || defined(OS_LINUX)
|
||||
.SetMethod("setAboutPanelOptions",
|
||||
base::Bind(&Browser::SetAboutPanelOptions, browser))
|
||||
.SetMethod("showAboutPanel",
|
||||
base::Bind(&Browser::ShowAboutPanel, browser))
|
||||
#endif
|
||||
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||
.SetMethod("showEmojiPanel",
|
||||
base::Bind(&Browser::ShowEmojiPanel, browser))
|
||||
.SetProperty("accessibilitySupportEnabled",
|
||||
&App::IsAccessibilitySupportEnabled,
|
||||
&App::SetAccessibilitySupportEnabled)
|
||||
#endif
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser))
|
||||
@@ -1298,8 +1416,10 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getAppPath", &App::GetAppPath)
|
||||
.SetMethod("setPath", &App::SetPath)
|
||||
.SetMethod("getPath", &App::GetPath)
|
||||
.SetMethod("setAppLogsPath", &App::SetAppLogsPath)
|
||||
.SetMethod("setDesktopName", &App::SetDesktopName)
|
||||
.SetMethod("getLocale", &App::GetLocale)
|
||||
.SetMethod("getLocaleCountryCode", &App::GetLocaleCountryCode)
|
||||
#if defined(USE_NSS_CERTS)
|
||||
.SetMethod("importCertificate", &App::ImportCertificate)
|
||||
#endif
|
||||
@@ -1307,9 +1427,9 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("requestSingleInstanceLock", &App::RequestSingleInstanceLock)
|
||||
.SetMethod("releaseSingleInstanceLock", &App::ReleaseSingleInstanceLock)
|
||||
.SetMethod("relaunch", &App::Relaunch)
|
||||
.SetMethod("isAccessibilitySupportEnabled",
|
||||
.SetMethod("_isAccessibilitySupportEnabled",
|
||||
&App::IsAccessibilitySupportEnabled)
|
||||
.SetMethod("setAccessibilitySupportEnabled",
|
||||
.SetMethod("_setAccessibilitySupportEnabled",
|
||||
&App::SetAccessibilitySupportEnabled)
|
||||
.SetMethod("disableHardwareAcceleration",
|
||||
&App::DisableHardwareAcceleration)
|
||||
@@ -1319,17 +1439,19 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getAppMetrics", &App::GetAppMetrics)
|
||||
.SetMethod("getGPUFeatureStatus", &App::GetGPUFeatureStatus)
|
||||
.SetMethod("getGPUInfo", &App::GetGPUInfo)
|
||||
// TODO(juturu): Remove in 2.0, deprecate before then with warnings
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("moveToApplicationsFolder", &App::MoveToApplicationsFolder)
|
||||
.SetMethod("isInApplicationsFolder", &App::IsInApplicationsFolder)
|
||||
#endif
|
||||
#if defined(MAS_BUILD)
|
||||
.SetMethod("startAccessingSecurityScopedResource",
|
||||
&App::StartAccessingSecurityScopedResource)
|
||||
#endif
|
||||
#if defined(OS_MACOSX)
|
||||
.SetProperty("dock", &App::GetDockAPI)
|
||||
#endif
|
||||
.SetProperty("userAgentFallback", &App::GetUserAgentFallback,
|
||||
&App::SetUserAgentFallback)
|
||||
.SetMethod("enableSandbox", &App::EnableSandbox)
|
||||
.SetMethod("enableMixedSandbox", &App::EnableMixedSandbox);
|
||||
.SetProperty("allowRendererProcessReuse",
|
||||
&App::CanBrowserClientUseCustomSiteInstance,
|
||||
&App::SetBrowserClientCanUseCustomSiteInstance);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
@@ -1338,72 +1460,18 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
namespace {
|
||||
|
||||
void AppendSwitch(const std::string& switch_string, mate::Arguments* args) {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
if (base::EndsWith(switch_string, "-path",
|
||||
base::CompareCase::INSENSITIVE_ASCII) ||
|
||||
switch_string == network::switches::kLogNetLog) {
|
||||
base::FilePath path;
|
||||
args->GetNext(&path);
|
||||
command_line->AppendSwitchPath(switch_string, path);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string value;
|
||||
if (args->GetNext(&value))
|
||||
command_line->AppendSwitchASCII(switch_string, value);
|
||||
else
|
||||
command_line->AppendSwitch(switch_string);
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
int DockBounce(const std::string& type) {
|
||||
int request_id = -1;
|
||||
if (type == "critical")
|
||||
request_id = Browser::Get()->DockBounce(Browser::BOUNCE_CRITICAL);
|
||||
else if (type == "informational")
|
||||
request_id = Browser::Get()->DockBounce(Browser::BOUNCE_INFORMATIONAL);
|
||||
return request_id;
|
||||
}
|
||||
|
||||
void DockSetMenu(atom::api::Menu* menu) {
|
||||
Browser::Get()->DockSetMenu(menu->model());
|
||||
}
|
||||
#endif
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("App", atom::api::App::GetConstructor(isolate)->GetFunction());
|
||||
dict.Set("App", atom::api::App::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
dict.Set("app", atom::api::App::Create(isolate));
|
||||
dict.SetMethod("appendSwitch", &AppendSwitch);
|
||||
dict.SetMethod("appendArgument", base::Bind(&base::CommandLine::AppendArg,
|
||||
base::Unretained(command_line)));
|
||||
#if defined(OS_MACOSX)
|
||||
auto browser = base::Unretained(Browser::Get());
|
||||
dict.SetMethod("dockBounce", &DockBounce);
|
||||
dict.SetMethod("dockCancelBounce",
|
||||
base::Bind(&Browser::DockCancelBounce, browser));
|
||||
dict.SetMethod("dockDownloadFinished",
|
||||
base::Bind(&Browser::DockDownloadFinished, browser));
|
||||
dict.SetMethod("dockSetBadgeText",
|
||||
base::Bind(&Browser::DockSetBadgeText, browser));
|
||||
dict.SetMethod("dockGetBadgeText",
|
||||
base::Bind(&Browser::DockGetBadgeText, browser));
|
||||
dict.SetMethod("dockHide", base::Bind(&Browser::DockHide, browser));
|
||||
dict.SetMethod("dockShow", base::Bind(&Browser::DockShow, browser));
|
||||
dict.SetMethod("dockIsVisible", base::Bind(&Browser::DockIsVisible, browser));
|
||||
dict.SetMethod("dockSetMenu", &DockSetMenu);
|
||||
dict.SetMethod("dockSetIcon", base::Bind(&Browser::DockSetIcon, browser));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_app, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_app, Initialize)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/process/process_iterator.h"
|
||||
#include "base/process/process_metrics.h"
|
||||
#include "base/task/cancelable_task_tracker.h"
|
||||
#include "chrome/browser/icon_manager.h"
|
||||
#include "chrome/browser/process_singleton.h"
|
||||
@@ -26,7 +27,8 @@
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/base/completion_callback.h"
|
||||
#include "net/base/completion_once_callback.h"
|
||||
#include "net/base/completion_repeating_callback.h"
|
||||
#include "net/ssl/client_cert_identity.h"
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
@@ -77,7 +79,7 @@ class App : public AtomBrowserClient::Delegate,
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void OnCertificateManagerModelCreated(
|
||||
std::unique_ptr<base::DictionaryValue> options,
|
||||
const net::CompletionCallback& callback,
|
||||
net::CompletionOnceCallback callback,
|
||||
std::unique_ptr<CertificateManagerModel> model);
|
||||
#endif
|
||||
|
||||
@@ -128,7 +130,7 @@ class App : public AtomBrowserClient::Delegate,
|
||||
int cert_error,
|
||||
const net::SSLInfo& ssl_info,
|
||||
const GURL& request_url,
|
||||
content::ResourceType resource_type,
|
||||
bool is_main_frame_request,
|
||||
bool strict_enforcement,
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(content::CertificateRequestResultType)>&
|
||||
@@ -141,7 +143,7 @@ class App : public AtomBrowserClient::Delegate,
|
||||
bool CanCreateWindow(content::RenderFrameHost* opener,
|
||||
const GURL& opener_url,
|
||||
const GURL& opener_top_level_frame_url,
|
||||
const GURL& source_origin,
|
||||
const url::Origin& source_origin,
|
||||
content::mojom::WindowContainerType container_type,
|
||||
const GURL& target_url,
|
||||
const content::Referrer& referrer,
|
||||
@@ -174,6 +176,8 @@ class App : public AtomBrowserClient::Delegate,
|
||||
void ChildProcessLaunched(int process_type, base::ProcessHandle handle);
|
||||
void ChildProcessDisconnected(base::ProcessId pid);
|
||||
|
||||
void SetAppLogsPath(mate::Arguments* args);
|
||||
|
||||
// Get/Set the pre-defined path in PathService.
|
||||
base::FilePath GetPath(mate::Arguments* args, const std::string& name);
|
||||
void SetPath(mate::Arguments* args,
|
||||
@@ -182,6 +186,7 @@ class App : public AtomBrowserClient::Delegate,
|
||||
|
||||
void SetDesktopName(const std::string& desktop_name);
|
||||
std::string GetLocale();
|
||||
std::string GetLocaleCountryCode();
|
||||
void OnSecondInstance(const base::CommandLine::StringVector& cmd,
|
||||
const base::FilePath& cwd);
|
||||
bool HasSingleInstanceLock() const;
|
||||
@@ -191,25 +196,32 @@ class App : public AtomBrowserClient::Delegate,
|
||||
void DisableHardwareAcceleration(mate::Arguments* args);
|
||||
void DisableDomainBlockingFor3DAPIs(mate::Arguments* args);
|
||||
bool IsAccessibilitySupportEnabled();
|
||||
void SetAccessibilitySupportEnabled(bool enabled);
|
||||
void SetAccessibilitySupportEnabled(bool enabled, mate::Arguments* args);
|
||||
Browser::LoginItemSettings GetLoginItemSettings(mate::Arguments* args);
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void ImportCertificate(const base::DictionaryValue& options,
|
||||
const net::CompletionCallback& callback);
|
||||
net::CompletionRepeatingCallback callback);
|
||||
#endif
|
||||
void GetFileIcon(const base::FilePath& path, mate::Arguments* args);
|
||||
v8::Local<v8::Promise> GetFileIcon(const base::FilePath& path,
|
||||
mate::Arguments* args);
|
||||
|
||||
std::vector<mate::Dictionary> GetAppMetrics(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> GetGPUFeatureStatus(v8::Isolate* isolate);
|
||||
v8::Local<v8::Promise> GetGPUInfo(v8::Isolate* isolate,
|
||||
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();
|
||||
void SetBrowserClientCanUseCustomSiteInstance(bool should_disable);
|
||||
bool CanBrowserClientUseCustomSiteInstance();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool MoveToApplicationsFolder(mate::Arguments* args);
|
||||
bool IsInApplicationsFolder();
|
||||
v8::Local<v8::Value> GetDockAPI(v8::Isolate* isolate);
|
||||
v8::Global<v8::Value> dock_;
|
||||
#endif
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
base::Callback<void()> StartAccessingSecurityScopedResource(
|
||||
mate::Arguments* args);
|
||||
|
||||
38
atom/browser/api/atom_api_app_mac.mm
Normal file
38
atom/browser/api/atom_api_app_mac.mm
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_app.h"
|
||||
#include "atom/browser/atom_paths.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "base/path_service.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
void App::SetAppLogsPath(mate::Arguments* args) {
|
||||
base::FilePath custom_path;
|
||||
if (args->GetNext(&custom_path)) {
|
||||
if (!custom_path.IsAbsolute()) {
|
||||
args->ThrowError("Path must be absolute");
|
||||
return;
|
||||
}
|
||||
base::PathService::Override(DIR_APP_LOGS, custom_path);
|
||||
} else {
|
||||
NSString* bundle_name =
|
||||
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
|
||||
NSString* logs_path =
|
||||
[NSString stringWithFormat:@"Library/Logs/%@", bundle_name];
|
||||
NSString* library_path =
|
||||
[NSHomeDirectory() stringByAppendingPathComponent:logs_path];
|
||||
base::PathService::Override(DIR_APP_LOGS,
|
||||
base::FilePath([library_path UTF8String]));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
} // namespace api
|
||||
@@ -64,11 +64,17 @@ void AutoUpdater::OnError(const std::string& message,
|
||||
auto errorObject =
|
||||
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
auto context = isolate()->GetCurrentContext();
|
||||
|
||||
// add two new params for better error handling
|
||||
errorObject->Set(mate::StringToV8(isolate(), "code"),
|
||||
v8::Integer::New(isolate(), code));
|
||||
errorObject->Set(mate::StringToV8(isolate(), "domain"),
|
||||
mate::StringToV8(isolate(), domain));
|
||||
errorObject
|
||||
->Set(context, mate::StringToV8(isolate(), "code"),
|
||||
v8::Integer::New(isolate(), code))
|
||||
.Check();
|
||||
errorObject
|
||||
->Set(context, mate::StringToV8(isolate(), "domain"),
|
||||
mate::StringToV8(isolate(), domain))
|
||||
.Check();
|
||||
|
||||
mate::EmitEvent(isolate(), GetWrapper(), "error", errorObject, message);
|
||||
}
|
||||
@@ -147,9 +153,11 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("autoUpdater", AutoUpdater::Create(isolate));
|
||||
dict.Set("AutoUpdater", AutoUpdater::GetConstructor(isolate)->GetFunction());
|
||||
dict.Set("AutoUpdater", AutoUpdater::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_auto_updater, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_auto_updater, Initialize)
|
||||
|
||||
@@ -37,6 +37,14 @@ struct Converter<atom::AutoResizeFlags> {
|
||||
if (params.Get("height", &height) && height) {
|
||||
flags |= atom::kAutoResizeHeight;
|
||||
}
|
||||
bool horizontal = false;
|
||||
if (params.Get("horizontal", &horizontal) && horizontal) {
|
||||
flags |= atom::kAutoResizeHorizontal;
|
||||
}
|
||||
bool vertical = false;
|
||||
if (params.Get("vertical", &vertical) && vertical) {
|
||||
flags |= atom::kAutoResizeVertical;
|
||||
}
|
||||
|
||||
*auto_resize_flags = static_cast<atom::AutoResizeFlags>(flags);
|
||||
return true;
|
||||
@@ -66,6 +74,7 @@ void BrowserView::Init(v8::Isolate* isolate,
|
||||
|
||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||
api_web_contents_ = web_contents.get();
|
||||
Observe(web_contents->web_contents());
|
||||
|
||||
view_.reset(
|
||||
NativeBrowserView::Create(api_web_contents_->managed_web_contents()));
|
||||
@@ -74,7 +83,16 @@ void BrowserView::Init(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
BrowserView::~BrowserView() {
|
||||
api_web_contents_->DestroyWebContents(true /* async */);
|
||||
if (api_web_contents_) { // destroy() is called
|
||||
// Destroy WebContents asynchronously unless app is shutting down,
|
||||
// because destroy() might be called inside WebContents's event handler.
|
||||
api_web_contents_->DestroyWebContents(!Browser::Get()->is_shutting_down());
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserView::WebContentsDestroyed() {
|
||||
api_web_contents_ = nullptr;
|
||||
web_contents_.Reset();
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -149,8 +167,9 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
BrowserView::SetConstructor(isolate, base::Bind(&BrowserView::New));
|
||||
|
||||
mate::Dictionary browser_view(
|
||||
isolate, BrowserView::GetConstructor(isolate)->GetFunction());
|
||||
mate::Dictionary browser_view(isolate, BrowserView::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
browser_view.SetMethod("fromId",
|
||||
&mate::TrackableObject<BrowserView>::FromWeakMapID);
|
||||
browser_view.SetMethod("getAllViews",
|
||||
@@ -161,4 +180,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_browser_view, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_browser_view, Initialize)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/native_browser_view.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace gfx {
|
||||
@@ -29,7 +30,8 @@ namespace api {
|
||||
|
||||
class WebContents;
|
||||
|
||||
class BrowserView : public mate::TrackableObject<BrowserView> {
|
||||
class BrowserView : public mate::TrackableObject<BrowserView>,
|
||||
public content::WebContentsObserver {
|
||||
public:
|
||||
static mate::WrappableBase* New(mate::Arguments* args);
|
||||
|
||||
@@ -47,6 +49,9 @@ class BrowserView : public mate::TrackableObject<BrowserView> {
|
||||
const mate::Dictionary& options);
|
||||
~BrowserView() override;
|
||||
|
||||
// content::WebContentsObserver:
|
||||
void WebContentsDestroyed() override;
|
||||
|
||||
private:
|
||||
void Init(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
|
||||
@@ -15,16 +15,17 @@
|
||||
#include "atom/common/color_util.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h" // nogncheck
|
||||
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h" // nogncheck
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "gin/converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gl/gpu_switching_manager.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -66,7 +67,7 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||
api_web_contents_ = web_contents.get();
|
||||
api_web_contents_ = web_contents->GetWeakPtr();
|
||||
api_web_contents_->AddObserver(this);
|
||||
Observe(api_web_contents_->web_contents());
|
||||
|
||||
@@ -74,10 +75,6 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
|
||||
mate::Dictionary(isolate, web_contents->GetWrapper())
|
||||
.Set("browserWindowOptions", options);
|
||||
|
||||
// Tell the content module to initialize renderer widget with transparent
|
||||
// mode.
|
||||
ui::GpuSwitchingManager::SetTransparent(window()->transparent());
|
||||
|
||||
// Associate with BrowserWindow.
|
||||
web_contents->SetOwnerWindow(window());
|
||||
|
||||
@@ -97,7 +94,9 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
BrowserWindow::~BrowserWindow() {
|
||||
api_web_contents_->RemoveObserver(this);
|
||||
// FIXME This is a hack rather than a proper fix preventing shutdown crashes.
|
||||
if (api_web_contents_)
|
||||
api_web_contents_->RemoveObserver(this);
|
||||
// Note that the OnWindowClosed will not be called after the destructor runs,
|
||||
// since the window object is managed by the TopLevelWindow class.
|
||||
if (web_contents())
|
||||
@@ -133,7 +132,7 @@ void BrowserWindow::RenderViewCreated(
|
||||
render_view_host->GetProcess()->GetID(),
|
||||
render_view_host->GetRoutingID());
|
||||
if (impl)
|
||||
impl->SetBackgroundOpaque(false);
|
||||
impl->owner_delegate()->SetBackgroundOpaque(false);
|
||||
}
|
||||
|
||||
void BrowserWindow::DidFirstVisuallyNonEmptyPaint() {
|
||||
@@ -185,7 +184,14 @@ bool BrowserWindow::OnMessageReceived(const IPC::Message& message,
|
||||
}
|
||||
|
||||
void BrowserWindow::OnCloseContents() {
|
||||
DCHECK(web_contents());
|
||||
// On some machines it may happen that the window gets destroyed for twice,
|
||||
// checking web_contents() can effectively guard against that.
|
||||
// https://github.com/electron/electron/issues/16202.
|
||||
//
|
||||
// TODO(zcbenz): We should find out the root cause and improve the closing
|
||||
// procedure of BrowserWindow.
|
||||
if (!web_contents())
|
||||
return;
|
||||
|
||||
// Close all child windows before closing current window.
|
||||
v8::Locker locker(isolate());
|
||||
@@ -234,7 +240,7 @@ void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
|
||||
return;
|
||||
|
||||
if (web_contents()->NeedToFireBeforeUnload())
|
||||
web_contents()->DispatchBeforeUnload();
|
||||
web_contents()->DispatchBeforeUnload(false /* auto_cancel */);
|
||||
else
|
||||
web_contents()->Close();
|
||||
}
|
||||
@@ -307,7 +313,29 @@ void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
|
||||
}
|
||||
|
||||
void BrowserWindow::SetBrowserView(v8::Local<v8::Value> value) {
|
||||
TopLevelWindow::SetBrowserView(value);
|
||||
TopLevelWindow::ResetBrowserViews();
|
||||
TopLevelWindow::AddBrowserView(value);
|
||||
#if defined(OS_MACOSX)
|
||||
UpdateDraggableRegions(nullptr, draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::AddBrowserView(v8::Local<v8::Value> value) {
|
||||
TopLevelWindow::AddBrowserView(value);
|
||||
#if defined(OS_MACOSX)
|
||||
UpdateDraggableRegions(nullptr, draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::RemoveBrowserView(v8::Local<v8::Value> value) {
|
||||
TopLevelWindow::RemoveBrowserView(value);
|
||||
#if defined(OS_MACOSX)
|
||||
UpdateDraggableRegions(nullptr, draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::ResetBrowserViews() {
|
||||
TopLevelWindow::ResetBrowserViews();
|
||||
#if defined(OS_MACOSX)
|
||||
UpdateDraggableRegions(nullptr, draggable_regions_);
|
||||
#endif
|
||||
@@ -315,7 +343,7 @@ void BrowserWindow::SetBrowserView(v8::Local<v8::Value> value) {
|
||||
|
||||
void BrowserWindow::SetVibrancy(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> value) {
|
||||
std::string type = mate::V8ToString(value);
|
||||
std::string type = gin::V8ToString(isolate, value);
|
||||
|
||||
auto* render_view_host = web_contents()->GetRenderViewHost();
|
||||
if (render_view_host) {
|
||||
@@ -323,7 +351,8 @@ void BrowserWindow::SetVibrancy(v8::Isolate* isolate,
|
||||
render_view_host->GetProcess()->GetID(),
|
||||
render_view_host->GetRoutingID());
|
||||
if (impl)
|
||||
impl->SetBackgroundOpaque(type.empty() ? !window_->transparent() : false);
|
||||
impl->owner_delegate()->SetBackgroundOpaque(
|
||||
type.empty() ? !window_->transparent() : false);
|
||||
}
|
||||
|
||||
TopLevelWindow::SetVibrancy(isolate, value);
|
||||
@@ -385,7 +414,9 @@ void BrowserWindow::Cleanup() {
|
||||
if (host)
|
||||
host->GetWidget()->RemoveInputEventObserver(this);
|
||||
|
||||
api_web_contents_->DestroyWebContents(true /* async */);
|
||||
// Destroy WebContents asynchronously unless app is shutting down,
|
||||
// because destroy() might be called inside WebContents's event handler.
|
||||
api_web_contents_->DestroyWebContents(!Browser::Get()->is_shutting_down());
|
||||
Observe(nullptr);
|
||||
}
|
||||
|
||||
@@ -451,4 +482,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)
|
||||
|
||||
@@ -72,6 +72,9 @@ class BrowserWindow : public TopLevelWindow,
|
||||
void Blur() override;
|
||||
void SetBackgroundColor(const std::string& color_name) override;
|
||||
void SetBrowserView(v8::Local<v8::Value> value) override;
|
||||
void AddBrowserView(v8::Local<v8::Value> value) override;
|
||||
void RemoveBrowserView(v8::Local<v8::Value> value) override;
|
||||
void ResetBrowserViews() override;
|
||||
void SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value) override;
|
||||
|
||||
// BrowserWindow APIs.
|
||||
@@ -82,7 +85,7 @@ class BrowserWindow : public TopLevelWindow,
|
||||
|
||||
private:
|
||||
#if defined(OS_MACOSX)
|
||||
void OverrideNSWindowContentView(brightray::InspectableWebContents* iwc);
|
||||
void OverrideNSWindowContentView(InspectableWebContents* iwc);
|
||||
#endif
|
||||
|
||||
// Helpers.
|
||||
@@ -113,7 +116,7 @@ class BrowserWindow : public TopLevelWindow,
|
||||
#endif
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
api::WebContents* api_web_contents_;
|
||||
base::WeakPtr<api::WebContents> api_web_contents_;
|
||||
|
||||
base::WeakPtrFactory<BrowserWindow> weak_factory_;
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
#include "atom/browser/native_browser_view.h"
|
||||
#include "atom/browser/native_window_mac.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "atom/common/draggable_region.h"
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
|
||||
@interface NSView (WebContentsView)
|
||||
- (void)setMouseDownCanMoveWindow:(BOOL)can_move;
|
||||
@@ -55,15 +55,20 @@ std::vector<gfx::Rect> CalculateNonDraggableRegions(
|
||||
|
||||
} // namespace
|
||||
|
||||
void BrowserWindow::OverrideNSWindowContentView(
|
||||
brightray::InspectableWebContents* iwc) {
|
||||
void BrowserWindow::OverrideNSWindowContentView(InspectableWebContents* iwc) {
|
||||
// Make NativeWindow use a NSView as content view.
|
||||
static_cast<NativeWindowMac*>(window())->OverrideNSWindowContentView();
|
||||
// Add webview to contentView.
|
||||
NSView* webView = iwc->GetView()->GetNativeView();
|
||||
NSView* contentView = [window()->GetNativeWindow() contentView];
|
||||
NSView* webView = iwc->GetView()->GetNativeView().GetNativeNSView();
|
||||
NSView* contentView =
|
||||
[window()->GetNativeWindow().GetNativeNSWindow() contentView];
|
||||
[webView setFrame:[contentView bounds]];
|
||||
[contentView addSubview:webView];
|
||||
|
||||
// ensure that buttons view is floated to top of view hierarchy
|
||||
NSArray* subviews = [contentView subviews];
|
||||
NSView* last = subviews.lastObject;
|
||||
[contentView addSubview:webView positioned:NSWindowBelow relativeTo:last];
|
||||
|
||||
[contentView viewDidMoveToWindow];
|
||||
}
|
||||
|
||||
@@ -76,7 +81,7 @@ void BrowserWindow::UpdateDraggableRegions(
|
||||
// All ControlRegionViews should be added as children of the WebContentsView,
|
||||
// because WebContentsView will be removed and re-added when entering and
|
||||
// leaving fullscreen mode.
|
||||
NSView* webView = web_contents()->GetNativeView();
|
||||
NSView* webView = web_contents()->GetNativeView().GetNativeNSView();
|
||||
NSInteger webViewWidth = NSWidth([webView bounds]);
|
||||
NSInteger webViewHeight = NSHeight([webView bounds]);
|
||||
|
||||
@@ -104,8 +109,10 @@ void BrowserWindow::UpdateDraggableRegions(
|
||||
DraggableRegionsToSkRegion(regions), webViewWidth, webViewHeight);
|
||||
}
|
||||
|
||||
if (window_->browser_view())
|
||||
window_->browser_view()->UpdateDraggableRegions(drag_exclude_rects);
|
||||
auto browser_views = window_->browser_views();
|
||||
for (NativeBrowserView* view : browser_views) {
|
||||
(view)->UpdateDraggableRegions(drag_exclude_rects);
|
||||
}
|
||||
|
||||
// Create and add a ControlRegionView for each region that needs to be
|
||||
// excluded from the dragging.
|
||||
|
||||
@@ -7,13 +7,15 @@
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "content/public/browser/tracing_controller.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using content::TracingController;
|
||||
|
||||
namespace mate {
|
||||
@@ -23,15 +25,27 @@ struct Converter<base::trace_event::TraceConfig> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::trace_event::TraceConfig* out) {
|
||||
// (alexeykuzmin): A combination of "categoryFilter" and "traceOptions"
|
||||
// has to be checked first because none of the fields
|
||||
// in the `memory_dump_config` dict below are mandatory
|
||||
// and we cannot check the config format.
|
||||
Dictionary options;
|
||||
if (!ConvertFromV8(isolate, val, &options))
|
||||
return false;
|
||||
std::string category_filter, trace_options;
|
||||
if (!options.Get("categoryFilter", &category_filter) ||
|
||||
!options.Get("traceOptions", &trace_options))
|
||||
return false;
|
||||
*out = base::trace_event::TraceConfig(category_filter, trace_options);
|
||||
return true;
|
||||
if (ConvertFromV8(isolate, val, &options)) {
|
||||
std::string category_filter, trace_options;
|
||||
if (options.Get("categoryFilter", &category_filter) &&
|
||||
options.Get("traceOptions", &trace_options)) {
|
||||
*out = base::trace_event::TraceConfig(category_filter, trace_options);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
base::DictionaryValue memory_dump_config;
|
||||
if (ConvertFromV8(isolate, val, &memory_dump_config)) {
|
||||
*out = base::trace_event::TraceConfig(memory_dump_config);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -45,6 +59,11 @@ scoped_refptr<TracingController::TraceDataEndpoint> GetTraceDataEndpoint(
|
||||
const base::FilePath& path,
|
||||
const CompletionCallback& callback) {
|
||||
base::FilePath result_file_path = path;
|
||||
|
||||
// base::CreateTemporaryFile prevents blocking so we need to allow it
|
||||
// for now since offloading this to a different sequence would require
|
||||
// changing the api shape
|
||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
||||
if (result_file_path.empty() && !base::CreateTemporaryFile(&result_file_path))
|
||||
LOG(ERROR) << "Creating temporary file failed";
|
||||
|
||||
@@ -52,28 +71,76 @@ scoped_refptr<TracingController::TraceDataEndpoint> GetTraceDataEndpoint(
|
||||
result_file_path, base::Bind(callback, result_file_path));
|
||||
}
|
||||
|
||||
void StopRecording(const base::FilePath& path,
|
||||
const CompletionCallback& callback) {
|
||||
TracingController::GetInstance()->StopTracing(
|
||||
GetTraceDataEndpoint(path, callback));
|
||||
v8::Local<v8::Promise> StopRecording(v8::Isolate* isolate,
|
||||
const base::FilePath& path) {
|
||||
atom::util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
// TODO(zcbenz): Remove the use of CopyablePromise when the
|
||||
// CreateFileEndpoint API accepts OnceCallback.
|
||||
TracingController::GetInstance()->StopTracing(GetTraceDataEndpoint(
|
||||
path, base::Bind(atom::util::CopyablePromise::ResolveCopyablePromise<
|
||||
const base::FilePath&>,
|
||||
atom::util::CopyablePromise(promise))));
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> GetCategories(v8::Isolate* isolate) {
|
||||
atom::util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
// Note: This method always succeeds.
|
||||
TracingController::GetInstance()->GetCategories(base::BindOnce(
|
||||
atom::util::Promise::ResolvePromise<const std::set<std::string>&>,
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> StartTracing(
|
||||
v8::Isolate* isolate,
|
||||
const base::trace_event::TraceConfig& trace_config) {
|
||||
atom::util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
// Note: This method always succeeds.
|
||||
TracingController::GetInstance()->StartTracing(
|
||||
trace_config, base::BindOnce(atom::util::Promise::ResolveEmptyPromise,
|
||||
std::move(promise)));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void OnTraceBufferUsageAvailable(atom::util::Promise promise,
|
||||
float percent_full,
|
||||
size_t approximate_count) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate());
|
||||
dict.Set("percentage", percent_full);
|
||||
dict.Set("value", approximate_count);
|
||||
|
||||
promise.Resolve(dict.GetHandle());
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> GetTraceBufferUsage(v8::Isolate* isolate) {
|
||||
atom::util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
// Note: This method always succeeds.
|
||||
TracingController::GetInstance()->GetTraceBufferUsage(
|
||||
base::BindOnce(&OnTraceBufferUsageAvailable, std::move(promise)));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
auto controller = base::Unretained(TracingController::GetInstance());
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("getCategories",
|
||||
base::Bind(&TracingController::GetCategories, controller));
|
||||
dict.SetMethod("startRecording",
|
||||
base::Bind(&TracingController::StartTracing, controller));
|
||||
dict.SetMethod("getCategories", &GetCategories);
|
||||
dict.SetMethod("startRecording", &StartTracing);
|
||||
dict.SetMethod("stopRecording", &StopRecording);
|
||||
dict.SetMethod(
|
||||
"getTraceBufferUsage",
|
||||
base::Bind(&TracingController::GetTraceBufferUsage, controller));
|
||||
dict.SetMethod("getTraceBufferUsage", &GetTraceBufferUsage);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_content_tracing, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_content_tracing, Initialize)
|
||||
|
||||
@@ -12,9 +12,11 @@
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
@@ -134,74 +136,120 @@ inline net::CookieStore* GetCookieStore(
|
||||
return getter->GetURLRequestContext()->cookie_store();
|
||||
}
|
||||
|
||||
// Run |callback| on UI thread.
|
||||
void RunCallbackInUI(const base::Closure& callback) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
|
||||
}
|
||||
|
||||
// Remove cookies from |list| not matching |filter|, and pass it to |callback|.
|
||||
void FilterCookies(std::unique_ptr<base::DictionaryValue> filter,
|
||||
const Cookies::GetCallback& callback,
|
||||
const net::CookieList& list) {
|
||||
util::Promise promise,
|
||||
const net::CookieList& list,
|
||||
const net::CookieStatusList& excluded_list) {
|
||||
net::CookieList result;
|
||||
for (const auto& cookie : list) {
|
||||
if (MatchesCookie(filter.get(), cookie))
|
||||
result.push_back(cookie);
|
||||
}
|
||||
RunCallbackInUI(base::Bind(callback, Cookies::SUCCESS, result));
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::UI},
|
||||
base::BindOnce(util::Promise::ResolvePromise<const net::CookieList&>,
|
||||
std::move(promise), std::move(result)));
|
||||
}
|
||||
|
||||
// Receives cookies matching |filter| in IO thread.
|
||||
void GetCookiesOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
std::unique_ptr<base::DictionaryValue> filter,
|
||||
const Cookies::GetCallback& callback) {
|
||||
util::Promise promise) {
|
||||
std::string url;
|
||||
filter->GetString("url", &url);
|
||||
|
||||
auto filtered_callback =
|
||||
base::Bind(FilterCookies, base::Passed(&filter), callback);
|
||||
base::BindOnce(FilterCookies, std::move(filter), std::move(promise));
|
||||
|
||||
// Empty url will match all url cookies.
|
||||
if (url.empty())
|
||||
GetCookieStore(getter)->GetAllCookiesAsync(filtered_callback);
|
||||
GetCookieStore(getter)->GetAllCookiesAsync(std::move(filtered_callback));
|
||||
else
|
||||
GetCookieStore(getter)->GetAllCookiesForURLAsync(GURL(url),
|
||||
filtered_callback);
|
||||
GetCookieStore(getter)->GetAllCookiesForURLAsync(
|
||||
GURL(url), std::move(filtered_callback));
|
||||
}
|
||||
|
||||
// Removes cookie with |url| and |name| in IO thread.
|
||||
void RemoveCookieOnIOThread(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
const GURL& url,
|
||||
const std::string& name,
|
||||
const base::Closure& callback) {
|
||||
GetCookieStore(getter)->DeleteCookieAsync(
|
||||
url, name, base::BindOnce(RunCallbackInUI, callback));
|
||||
void RemoveCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
const GURL& url,
|
||||
const std::string& name,
|
||||
util::Promise promise) {
|
||||
net::CookieDeletionInfo cookie_info;
|
||||
cookie_info.url = url;
|
||||
cookie_info.name = name;
|
||||
GetCookieStore(getter)->DeleteAllMatchingInfoAsync(
|
||||
std::move(cookie_info),
|
||||
base::BindOnce(
|
||||
[](util::Promise promise, uint32_t num_deleted) {
|
||||
util::Promise::ResolveEmptyPromise(std::move(promise));
|
||||
},
|
||||
std::move(promise)));
|
||||
}
|
||||
|
||||
// Callback of SetCookie.
|
||||
void OnSetCookie(const Cookies::SetCallback& callback, bool success) {
|
||||
RunCallbackInUI(
|
||||
base::Bind(callback, success ? Cookies::SUCCESS : Cookies::FAILED));
|
||||
void OnSetCookie(util::Promise promise,
|
||||
net::CanonicalCookie::CookieInclusionStatus status) {
|
||||
std::string errmsg;
|
||||
switch (status) {
|
||||
case net::CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY:
|
||||
errmsg = "Failed to create httponly cookie";
|
||||
break;
|
||||
case net::CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY:
|
||||
errmsg = "Cannot create a secure cookie from an insecure URL";
|
||||
break;
|
||||
case net::CanonicalCookie::CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE:
|
||||
errmsg = "Failed to parse cookie";
|
||||
break;
|
||||
case net::CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN:
|
||||
errmsg = "Failed to get cookie domain";
|
||||
break;
|
||||
case net::CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_PREFIX:
|
||||
errmsg = "Failed because the cookie violated prefix rules.";
|
||||
break;
|
||||
case net::CanonicalCookie::CookieInclusionStatus::
|
||||
EXCLUDE_NONCOOKIEABLE_SCHEME:
|
||||
errmsg = "Cannot set cookie for current scheme";
|
||||
break;
|
||||
case net::CanonicalCookie::CookieInclusionStatus::INCLUDE:
|
||||
errmsg = "";
|
||||
break;
|
||||
default:
|
||||
errmsg = "Setting cookie failed";
|
||||
break;
|
||||
}
|
||||
if (errmsg.empty()) {
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::UI},
|
||||
base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise)));
|
||||
} else {
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::UI},
|
||||
base::BindOnce(util::Promise::RejectPromise, std::move(promise),
|
||||
std::move(errmsg)));
|
||||
}
|
||||
}
|
||||
|
||||
// Flushes cookie store in IO thread.
|
||||
void FlushCookieStoreOnIOThread(
|
||||
scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
const base::Closure& callback) {
|
||||
GetCookieStore(getter)->FlushStore(base::BindOnce(RunCallbackInUI, callback));
|
||||
util::Promise promise) {
|
||||
GetCookieStore(getter)->FlushStore(
|
||||
base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise)));
|
||||
}
|
||||
|
||||
// Sets cookie with |details| in IO thread.
|
||||
void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
std::unique_ptr<base::DictionaryValue> details,
|
||||
const Cookies::SetCallback& callback) {
|
||||
std::string url, name, value, domain, path;
|
||||
util::Promise promise) {
|
||||
std::string url_string, name, value, domain, path;
|
||||
bool secure = false;
|
||||
bool http_only = false;
|
||||
double creation_date;
|
||||
double expiration_date;
|
||||
double last_access_date;
|
||||
details->GetString("url", &url);
|
||||
details->GetString("url", &url_string);
|
||||
details->GetString("name", &name);
|
||||
details->GetString("value", &value);
|
||||
details->GetString("domain", &domain);
|
||||
@@ -230,26 +278,37 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
: base::Time::FromDoubleT(last_access_date);
|
||||
}
|
||||
|
||||
GURL url(url_string);
|
||||
std::unique_ptr<net::CanonicalCookie> canonical_cookie(
|
||||
net::CanonicalCookie::CreateSanitizedCookie(
|
||||
GURL(url), name, value, domain, path, creation_time, expiration_time,
|
||||
url, name, value, domain, path, creation_time, expiration_time,
|
||||
last_access_time, secure, http_only,
|
||||
net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT));
|
||||
auto completion_callback = base::BindOnce(OnSetCookie, callback);
|
||||
net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_DEFAULT));
|
||||
auto completion_callback = base::BindOnce(OnSetCookie, std::move(promise));
|
||||
if (!canonical_cookie || !canonical_cookie->IsCanonical()) {
|
||||
std::move(completion_callback).Run(false);
|
||||
std::move(completion_callback)
|
||||
.Run(net::CanonicalCookie::CookieInclusionStatus::
|
||||
EXCLUDE_FAILURE_TO_STORE);
|
||||
return;
|
||||
}
|
||||
if (url.empty()) {
|
||||
std::move(completion_callback).Run(false);
|
||||
if (!url.is_valid()) {
|
||||
std::move(completion_callback)
|
||||
.Run(net::CanonicalCookie::CookieInclusionStatus::
|
||||
EXCLUDE_INVALID_DOMAIN);
|
||||
return;
|
||||
}
|
||||
if (name.empty()) {
|
||||
std::move(completion_callback).Run(false);
|
||||
std::move(completion_callback)
|
||||
.Run(net::CanonicalCookie::CookieInclusionStatus::
|
||||
EXCLUDE_FAILURE_TO_STORE);
|
||||
return;
|
||||
}
|
||||
net::CookieOptions options;
|
||||
if (http_only) {
|
||||
options.set_include_httponly();
|
||||
}
|
||||
GetCookieStore(getter)->SetCanonicalCookieAsync(
|
||||
std::move(canonical_cookie), secure, http_only,
|
||||
std::move(canonical_cookie), url.scheme(), options,
|
||||
std::move(completion_callback));
|
||||
}
|
||||
|
||||
@@ -265,44 +324,61 @@ Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
|
||||
Cookies::~Cookies() {}
|
||||
|
||||
void Cookies::Get(const base::DictionaryValue& filter,
|
||||
const GetCallback& callback) {
|
||||
v8::Local<v8::Promise> Cookies::Get(const base::DictionaryValue& filter) {
|
||||
util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
auto copy = base::DictionaryValue::From(
|
||||
base::Value::ToUniquePtrValue(filter.Clone()));
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
content::BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(GetCookiesOnIO, base::RetainedRef(getter), std::move(copy),
|
||||
callback));
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Cookies::Remove(const GURL& url,
|
||||
const std::string& name,
|
||||
const base::Closure& callback) {
|
||||
v8::Local<v8::Promise> Cookies::Remove(const GURL& url,
|
||||
const std::string& name) {
|
||||
util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
content::BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(RemoveCookieOnIOThread, base::RetainedRef(getter), url,
|
||||
name, callback));
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(RemoveCookieOnIO, base::RetainedRef(getter), url, name,
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Cookies::Set(const base::DictionaryValue& details,
|
||||
const SetCallback& callback) {
|
||||
v8::Local<v8::Promise> Cookies::Set(const base::DictionaryValue& details) {
|
||||
util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
auto copy = base::DictionaryValue::From(
|
||||
base::Value::ToUniquePtrValue(details.Clone()));
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
content::BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(SetCookieOnIO, base::RetainedRef(getter), std::move(copy),
|
||||
callback));
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Cookies::FlushStore(const base::Closure& callback) {
|
||||
v8::Local<v8::Promise> Cookies::FlushStore() {
|
||||
util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
content::BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(FlushCookieStoreOnIOThread, base::RetainedRef(getter),
|
||||
callback));
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Cookies::OnCookieChanged(const CookieDetails* details) {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/net/cookie_details.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/callback_list.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/cookies/canonical_cookie.h"
|
||||
@@ -35,9 +36,6 @@ class Cookies : public mate::TrackableObject<Cookies> {
|
||||
FAILED,
|
||||
};
|
||||
|
||||
using GetCallback = base::Callback<void(Error, const net::CookieList&)>;
|
||||
using SetCallback = base::Callback<void(Error)>;
|
||||
|
||||
static mate::Handle<Cookies> Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context);
|
||||
|
||||
@@ -49,12 +47,10 @@ class Cookies : public mate::TrackableObject<Cookies> {
|
||||
Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
~Cookies() override;
|
||||
|
||||
void Get(const base::DictionaryValue& filter, const GetCallback& callback);
|
||||
void Remove(const GURL& url,
|
||||
const std::string& name,
|
||||
const base::Closure& callback);
|
||||
void Set(const base::DictionaryValue& details, const SetCallback& callback);
|
||||
void FlushStore(const base::Closure& callback);
|
||||
v8::Local<v8::Promise> Get(const base::DictionaryValue& filter);
|
||||
v8::Local<v8::Promise> Set(const base::DictionaryValue& details);
|
||||
v8::Local<v8::Promise> Remove(const GURL& url, const std::string& name);
|
||||
v8::Local<v8::Promise> FlushStore();
|
||||
|
||||
// CookieChangeNotifier subscription:
|
||||
void OnCookieChanged(const CookieDetails*);
|
||||
|
||||
@@ -10,14 +10,13 @@
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/json/json_reader.h"
|
||||
#include "base/json/json_writer.h"
|
||||
#include "content/public/browser/devtools_agent_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using content::DevToolsAgentHost;
|
||||
|
||||
namespace atom {
|
||||
@@ -45,7 +44,8 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
|
||||
std::unique_ptr<base::Value> parsed_message = base::JSONReader::Read(message);
|
||||
std::unique_ptr<base::Value> parsed_message =
|
||||
base::JSONReader::ReadDeprecated(message);
|
||||
if (!parsed_message || !parsed_message->is_dict())
|
||||
return;
|
||||
base::DictionaryValue* dict =
|
||||
@@ -61,23 +61,26 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
|
||||
params.Swap(params_value);
|
||||
Emit("message", method, params);
|
||||
} else {
|
||||
auto send_command_callback = pending_requests_[id];
|
||||
pending_requests_.erase(id);
|
||||
if (send_command_callback.is_null())
|
||||
auto it = pending_requests_.find(id);
|
||||
if (it == pending_requests_.end())
|
||||
return;
|
||||
base::DictionaryValue* error_body = nullptr;
|
||||
base::DictionaryValue error;
|
||||
bool has_error;
|
||||
if ((has_error = dict->GetDictionary("error", &error_body))) {
|
||||
error.Swap(error_body);
|
||||
}
|
||||
|
||||
base::DictionaryValue* result_body = nullptr;
|
||||
base::DictionaryValue result;
|
||||
if (dict->GetDictionary("result", &result_body))
|
||||
result.Swap(result_body);
|
||||
send_command_callback.Run(has_error ? error.Clone() : base::Value(),
|
||||
result);
|
||||
atom::util::Promise promise = std::move(it->second);
|
||||
pending_requests_.erase(it);
|
||||
|
||||
base::DictionaryValue* error = nullptr;
|
||||
if (dict->GetDictionary("error", &error)) {
|
||||
std::string message;
|
||||
error->GetString("message", &message);
|
||||
promise.RejectWithErrorMessage(message);
|
||||
} else {
|
||||
base::DictionaryValue* result_body = nullptr;
|
||||
base::DictionaryValue result;
|
||||
if (dict->GetDictionary("result", &result_body)) {
|
||||
result.Swap(result_body);
|
||||
}
|
||||
promise.Resolve(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,23 +128,27 @@ void Debugger::Detach() {
|
||||
AgentHostClosed(agent_host_.get());
|
||||
}
|
||||
|
||||
void Debugger::SendCommand(mate::Arguments* args) {
|
||||
if (!agent_host_)
|
||||
return;
|
||||
v8::Local<v8::Promise> Debugger::SendCommand(mate::Arguments* args) {
|
||||
atom::util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
if (!agent_host_) {
|
||||
promise.RejectWithErrorMessage("No target available");
|
||||
return handle;
|
||||
}
|
||||
|
||||
std::string method;
|
||||
if (!args->GetNext(&method)) {
|
||||
args->ThrowError();
|
||||
return;
|
||||
promise.RejectWithErrorMessage("Invalid method");
|
||||
return handle;
|
||||
}
|
||||
|
||||
base::DictionaryValue command_params;
|
||||
args->GetNext(&command_params);
|
||||
SendCommandCallback callback;
|
||||
args->GetNext(&callback);
|
||||
|
||||
base::DictionaryValue request;
|
||||
int request_id = ++previous_request_id_;
|
||||
pending_requests_[request_id] = callback;
|
||||
pending_requests_.emplace(request_id, std::move(promise));
|
||||
request.SetInteger("id", request_id);
|
||||
request.SetString("method", method);
|
||||
if (!command_params.empty())
|
||||
@@ -151,16 +158,13 @@ void Debugger::SendCommand(mate::Arguments* args) {
|
||||
std::string json_args;
|
||||
base::JSONWriter::Write(request, &json_args);
|
||||
agent_host_->DispatchProtocolMessage(this, json_args);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Debugger::ClearPendingRequests() {
|
||||
if (pending_requests_.empty())
|
||||
return;
|
||||
base::Value error(base::Value::Type::DICTIONARY);
|
||||
base::Value error_msg("target closed while handling command");
|
||||
error.SetKey("message", std::move(error_msg));
|
||||
for (const auto& it : pending_requests_)
|
||||
it.second.Run(error, base::Value());
|
||||
for (auto& it : pending_requests_)
|
||||
it.second.RejectWithErrorMessage("target closed while handling command");
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -194,9 +198,11 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary(isolate, exports)
|
||||
.Set("Debugger", Debugger::GetConstructor(isolate)->GetFunction());
|
||||
.Set("Debugger", Debugger::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_debugger, Initialize);
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_debugger, Initialize)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/devtools_agent_host_client.h"
|
||||
@@ -32,9 +33,6 @@ class Debugger : public mate::TrackableObject<Debugger>,
|
||||
public content::DevToolsAgentHostClient,
|
||||
public content::WebContentsObserver {
|
||||
public:
|
||||
using SendCommandCallback =
|
||||
base::Callback<void(const base::Value&, const base::Value&)>;
|
||||
|
||||
static mate::Handle<Debugger> Create(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents);
|
||||
|
||||
@@ -56,12 +54,12 @@ class Debugger : public mate::TrackableObject<Debugger>,
|
||||
content::RenderFrameHost* new_rfh) override;
|
||||
|
||||
private:
|
||||
using PendingRequestMap = std::map<int, SendCommandCallback>;
|
||||
using PendingRequestMap = std::map<int, atom::util::Promise>;
|
||||
|
||||
void Attach(mate::Arguments* args);
|
||||
bool IsAttached();
|
||||
void Detach();
|
||||
void SendCommand(mate::Arguments* args);
|
||||
v8::Local<v8::Promise> SendCommand(mate::Arguments* args);
|
||||
void ClearPendingRequests();
|
||||
|
||||
content::WebContents* web_contents_; // Weak Reference.
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
|
||||
#include "atom/common/api/atom_api_native_image.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "chrome/browser/media/webrtc/desktop_media_list.h"
|
||||
#include "chrome/browser/media/webrtc/window_icon_util.h"
|
||||
#include "content/public/browser/desktop_capture.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
|
||||
@@ -25,8 +27,6 @@
|
||||
#include "ui/display/win/display_info.h"
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
@@ -42,6 +42,12 @@ struct Converter<atom::api::DesktopCapturer::Source> {
|
||||
atom::api::NativeImage::Create(
|
||||
isolate, gfx::Image(source.media_list_source.thumbnail)));
|
||||
dict.Set("display_id", source.display_id);
|
||||
if (source.fetch_icon) {
|
||||
dict.Set(
|
||||
"appIcon",
|
||||
atom::api::NativeImage::Create(
|
||||
isolate, gfx::Image(GetWindowIcon(source.media_list_source.id))));
|
||||
}
|
||||
return ConvertToV8(isolate, dict);
|
||||
}
|
||||
};
|
||||
@@ -60,7 +66,9 @@ DesktopCapturer::~DesktopCapturer() {}
|
||||
|
||||
void DesktopCapturer::StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
const gfx::Size& thumbnail_size) {
|
||||
const gfx::Size& thumbnail_size,
|
||||
bool fetch_window_icons) {
|
||||
fetch_window_icons_ = fetch_window_icons;
|
||||
#if defined(OS_WIN)
|
||||
if (content::desktop_capture::CreateDesktopCaptureOptions()
|
||||
.allow_directx_capturer()) {
|
||||
@@ -79,10 +87,6 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
capture_screen_ = capture_screen;
|
||||
|
||||
{
|
||||
// Remove this once
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=795340 is fixed.
|
||||
base::ScopedAllowBaseSyncPrimitivesForTesting
|
||||
scoped_allow_base_sync_primitives;
|
||||
// Initialize the source list.
|
||||
// Apply the new thumbnail size and restart capture.
|
||||
if (capture_window) {
|
||||
@@ -128,24 +132,26 @@ bool DesktopCapturer::ShouldScheduleNextRefresh(DesktopMediaList* list) {
|
||||
}
|
||||
|
||||
void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
std::vector<DesktopCapturer::Source> window_sources;
|
||||
if (capture_window_ &&
|
||||
list->GetMediaListType() == content::DesktopMediaID::TYPE_WINDOW) {
|
||||
capture_window_ = false;
|
||||
const auto& media_list_sources = list->GetSources();
|
||||
std::vector<DesktopCapturer::Source> window_sources;
|
||||
window_sources.reserve(media_list_sources.size());
|
||||
for (const auto& media_list_source : media_list_sources) {
|
||||
window_sources.emplace_back(
|
||||
DesktopCapturer::Source{media_list_source, std::string()});
|
||||
window_sources.emplace_back(DesktopCapturer::Source{
|
||||
media_list_source, std::string(), fetch_window_icons_});
|
||||
}
|
||||
std::move(window_sources.begin(), window_sources.end(),
|
||||
std::back_inserter(captured_sources_));
|
||||
}
|
||||
|
||||
std::vector<DesktopCapturer::Source> screen_sources;
|
||||
if (capture_screen_ &&
|
||||
list->GetMediaListType() == content::DesktopMediaID::TYPE_SCREEN) {
|
||||
capture_screen_ = false;
|
||||
const auto& media_list_sources = list->GetSources();
|
||||
std::vector<DesktopCapturer::Source> screen_sources;
|
||||
screen_sources.reserve(media_list_sources.size());
|
||||
for (const auto& media_list_source : media_list_sources) {
|
||||
screen_sources.emplace_back(
|
||||
DesktopCapturer::Source{media_list_source, std::string()});
|
||||
@@ -159,8 +165,12 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
std::vector<std::string> device_names;
|
||||
// Crucially, this list of device names will be in the same order as
|
||||
// |media_list_sources|.
|
||||
webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(
|
||||
&device_names);
|
||||
if (!webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(
|
||||
&device_names)) {
|
||||
Emit("error", "Failed to get sources.");
|
||||
return;
|
||||
}
|
||||
|
||||
int device_name_index = 0;
|
||||
for (auto& source : screen_sources) {
|
||||
const auto& device_name = device_names[device_name_index++];
|
||||
@@ -170,13 +180,13 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
const int64_t device_id =
|
||||
display::win::DisplayInfo::DeviceIdFromDeviceName(
|
||||
wide_device_name.c_str());
|
||||
source.display_id = base::Int64ToString(device_id);
|
||||
source.display_id = base::NumberToString(device_id);
|
||||
}
|
||||
}
|
||||
#elif defined(OS_MACOSX)
|
||||
// On Mac, the IDs across the APIs match.
|
||||
for (auto& source : screen_sources) {
|
||||
source.display_id = base::Int64ToString(source.media_list_source.id.id);
|
||||
source.display_id = base::NumberToString(source.media_list_source.id.id);
|
||||
}
|
||||
#endif // defined(OS_WIN)
|
||||
// TODO(ajmacd): Add Linux support. The IDs across APIs differ but Chrome
|
||||
@@ -187,7 +197,7 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
}
|
||||
|
||||
if (!capture_window_ && !capture_screen_)
|
||||
Emit("finished", captured_sources_);
|
||||
Emit("finished", captured_sources_, fetch_window_icons_);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -216,9 +226,9 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("desktopCapturer", atom::api::DesktopCapturer::Create(isolate));
|
||||
dict.SetMethod("createDesktopCapturer", &atom::api::DesktopCapturer::Create);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_desktop_capturer, Initialize);
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_desktop_capturer, Initialize)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
|
||||
#include "chrome/browser/media/webrtc/native_desktop_media_list.h"
|
||||
#include "native_mate/handle.h"
|
||||
@@ -18,13 +18,16 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class DesktopCapturer : public mate::EventEmitter<DesktopCapturer>,
|
||||
class DesktopCapturer : public mate::TrackableObject<DesktopCapturer>,
|
||||
public DesktopMediaListObserver {
|
||||
public:
|
||||
struct Source {
|
||||
DesktopMediaList::Source media_list_source;
|
||||
// Will be an empty string if not available.
|
||||
std::string display_id;
|
||||
|
||||
// Whether or not this source should provide an icon.
|
||||
bool fetch_icon = false;
|
||||
};
|
||||
|
||||
static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
|
||||
@@ -34,7 +37,8 @@ class DesktopCapturer : public mate::EventEmitter<DesktopCapturer>,
|
||||
|
||||
void StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
const gfx::Size& thumbnail_size);
|
||||
const gfx::Size& thumbnail_size,
|
||||
bool fetch_window_icons);
|
||||
|
||||
protected:
|
||||
explicit DesktopCapturer(v8::Isolate* isolate);
|
||||
@@ -59,6 +63,7 @@ class DesktopCapturer : public mate::EventEmitter<DesktopCapturer>,
|
||||
std::vector<DesktopCapturer::Source> captured_sources_;
|
||||
bool capture_window_ = false;
|
||||
bool capture_screen_ = false;
|
||||
bool fetch_window_icons_ = false;
|
||||
#if defined(OS_WIN)
|
||||
bool using_directx_capturer_ = false;
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
@@ -12,114 +12,101 @@
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "atom/browser/ui/message_box.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_dialog_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<file_dialog::Filter> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
file_dialog::Filter* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
if (!dict.Get("name", &(out->first)))
|
||||
return false;
|
||||
if (!dict.Get("extensions", &(out->second)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<file_dialog::DialogSettings> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
file_dialog::DialogSettings* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
dict.Get("window", &(out->parent_window));
|
||||
dict.Get("title", &(out->title));
|
||||
dict.Get("message", &(out->message));
|
||||
dict.Get("buttonLabel", &(out->button_label));
|
||||
dict.Get("nameFieldLabel", &(out->name_field_label));
|
||||
dict.Get("defaultPath", &(out->default_path));
|
||||
dict.Get("filters", &(out->filters));
|
||||
dict.Get("properties", &(out->properties));
|
||||
dict.Get("showsTagField", &(out->shows_tag_field));
|
||||
#if defined(MAS_BUILD)
|
||||
dict.Get("securityScopedBookmarks", &(out->security_scoped_bookmarks));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void ShowMessageBox(int type,
|
||||
const std::vector<std::string>& buttons,
|
||||
int default_id,
|
||||
int cancel_id,
|
||||
int options,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon,
|
||||
atom::NativeWindow* window,
|
||||
mate::Arguments* args) {
|
||||
v8::Local<v8::Value> peek = args->PeekNext();
|
||||
atom::MessageBoxCallback callback;
|
||||
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(), peek,
|
||||
&callback)) {
|
||||
atom::ShowMessageBox(window, static_cast<atom::MessageBoxType>(type),
|
||||
buttons, default_id, cancel_id, options, title,
|
||||
message, detail, checkbox_label, checkbox_checked,
|
||||
icon, callback);
|
||||
} else {
|
||||
int chosen = atom::ShowMessageBox(
|
||||
window, static_cast<atom::MessageBoxType>(type), buttons, default_id,
|
||||
cancel_id, options, title, message, detail, icon);
|
||||
args->Return(chosen);
|
||||
}
|
||||
int ShowMessageBoxSync(int type,
|
||||
const std::vector<std::string>& buttons,
|
||||
int default_id,
|
||||
int cancel_id,
|
||||
int options,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon,
|
||||
atom::NativeWindow* window) {
|
||||
return atom::ShowMessageBoxSync(
|
||||
window, static_cast<atom::MessageBoxType>(type), buttons, default_id,
|
||||
cancel_id, options, title, message, detail, icon);
|
||||
}
|
||||
|
||||
void ShowOpenDialog(const file_dialog::DialogSettings& settings,
|
||||
mate::Arguments* args) {
|
||||
v8::Local<v8::Value> peek = args->PeekNext();
|
||||
file_dialog::OpenDialogCallback callback;
|
||||
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(
|
||||
args->isolate(), peek, &callback)) {
|
||||
file_dialog::ShowOpenDialog(settings, callback);
|
||||
} else {
|
||||
std::vector<base::FilePath> paths;
|
||||
if (file_dialog::ShowOpenDialog(settings, &paths))
|
||||
args->Return(paths);
|
||||
}
|
||||
void ResolvePromiseObject(atom::util::Promise promise,
|
||||
int result,
|
||||
bool checkbox_checked) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate());
|
||||
|
||||
dict.Set("response", result);
|
||||
dict.Set("checkboxChecked", checkbox_checked);
|
||||
|
||||
promise.Resolve(dict.GetHandle());
|
||||
}
|
||||
|
||||
void ShowSaveDialog(const file_dialog::DialogSettings& settings,
|
||||
mate::Arguments* args) {
|
||||
v8::Local<v8::Value> peek = args->PeekNext();
|
||||
file_dialog::SaveDialogCallback callback;
|
||||
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(
|
||||
args->isolate(), peek, &callback)) {
|
||||
file_dialog::ShowSaveDialog(settings, callback);
|
||||
} else {
|
||||
base::FilePath path;
|
||||
if (file_dialog::ShowSaveDialog(settings, &path))
|
||||
args->Return(path);
|
||||
}
|
||||
v8::Local<v8::Promise> ShowMessageBox(int type,
|
||||
const std::vector<std::string>& buttons,
|
||||
int default_id,
|
||||
int cancel_id,
|
||||
int options,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon,
|
||||
atom::NativeWindow* window,
|
||||
mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
atom::util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
atom::ShowMessageBox(
|
||||
window, static_cast<atom::MessageBoxType>(type), buttons, default_id,
|
||||
cancel_id, options, title, message, detail, checkbox_label,
|
||||
checkbox_checked, icon,
|
||||
base::BindOnce(&ResolvePromiseObject, std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void ShowOpenDialogSync(const file_dialog::DialogSettings& settings,
|
||||
mate::Arguments* args) {
|
||||
std::vector<base::FilePath> paths;
|
||||
if (file_dialog::ShowOpenDialogSync(settings, &paths))
|
||||
args->Return(paths);
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> ShowOpenDialog(
|
||||
const file_dialog::DialogSettings& settings,
|
||||
mate::Arguments* args) {
|
||||
atom::util::Promise promise(args->isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
file_dialog::ShowOpenDialog(settings, std::move(promise));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void ShowSaveDialogSync(const file_dialog::DialogSettings& settings,
|
||||
mate::Arguments* args) {
|
||||
base::FilePath path;
|
||||
if (file_dialog::ShowSaveDialogSync(settings, &path))
|
||||
args->Return(path);
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> ShowSaveDialog(
|
||||
const file_dialog::DialogSettings& settings,
|
||||
mate::Arguments* args) {
|
||||
atom::util::Promise promise(args->isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
file_dialog::ShowSaveDialog(settings, std::move(promise));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
@@ -127,9 +114,12 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("showMessageBoxSync", &ShowMessageBoxSync);
|
||||
dict.SetMethod("showMessageBox", &ShowMessageBox);
|
||||
dict.SetMethod("showErrorBox", &atom::ShowErrorBox);
|
||||
dict.SetMethod("showOpenDialogSync", &ShowOpenDialogSync);
|
||||
dict.SetMethod("showOpenDialog", &ShowOpenDialog);
|
||||
dict.SetMethod("showSaveDialogSync", &ShowSaveDialogSync);
|
||||
dict.SetMethod("showSaveDialog", &ShowSaveDialog);
|
||||
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||
dict.SetMethod("showCertificateTrustDialog",
|
||||
@@ -139,4 +129,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_dialog, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_dialog, Initialize)
|
||||
|
||||
@@ -8,15 +8,15 @@
|
||||
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_dialog_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/filename_util.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
@@ -102,7 +102,7 @@ bool DownloadItem::IsPaused() const {
|
||||
}
|
||||
|
||||
void DownloadItem::Resume() {
|
||||
download_item_->Resume();
|
||||
download_item_->Resume(true /* user_gesture */);
|
||||
}
|
||||
|
||||
bool DownloadItem::CanResume() const {
|
||||
@@ -165,6 +165,15 @@ base::FilePath DownloadItem::GetSavePath() const {
|
||||
return save_path_;
|
||||
}
|
||||
|
||||
file_dialog::DialogSettings DownloadItem::GetSaveDialogOptions() const {
|
||||
return dialog_options_;
|
||||
}
|
||||
|
||||
void DownloadItem::SetSaveDialogOptions(
|
||||
const file_dialog::DialogSettings& options) {
|
||||
dialog_options_ = options;
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetLastModifiedTime() const {
|
||||
return download_item_->GetLastModifiedTime();
|
||||
}
|
||||
@@ -200,6 +209,8 @@ void DownloadItem::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("isDone", &DownloadItem::IsDone)
|
||||
.SetMethod("setSavePath", &DownloadItem::SetSavePath)
|
||||
.SetMethod("getSavePath", &DownloadItem::GetSavePath)
|
||||
.SetMethod("setSaveDialogOptions", &DownloadItem::SetSaveDialogOptions)
|
||||
.SetMethod("getSaveDialogOptions", &DownloadItem::GetSaveDialogOptions)
|
||||
.SetMethod("getLastModifiedTime", &DownloadItem::GetLastModifiedTime)
|
||||
.SetMethod("getETag", &DownloadItem::GetETag)
|
||||
.SetMethod("getStartTime", &DownloadItem::GetStartTime);
|
||||
@@ -232,10 +243,11 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary(isolate, exports)
|
||||
.Set("DownloadItem",
|
||||
atom::api::DownloadItem::GetConstructor(isolate)->GetFunction());
|
||||
.Set("DownloadItem", atom::api::DownloadItem::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_download_item, Initialize);
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_download_item, Initialize)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "components/download/public/common/download_item.h"
|
||||
#include "native_mate/handle.h"
|
||||
@@ -44,6 +45,8 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
||||
bool IsDone() const;
|
||||
void SetSavePath(const base::FilePath& path);
|
||||
base::FilePath GetSavePath() const;
|
||||
file_dialog::DialogSettings GetSaveDialogOptions() const;
|
||||
void SetSaveDialogOptions(const file_dialog::DialogSettings& options);
|
||||
std::string GetLastModifiedTime() const;
|
||||
std::string GetETag() const;
|
||||
double GetStartTime() const;
|
||||
@@ -58,6 +61,7 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
||||
|
||||
private:
|
||||
base::FilePath save_path_;
|
||||
file_dialog::DialogSettings dialog_options_;
|
||||
download::DownloadItem* download_item_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DownloadItem);
|
||||
|
||||
26
atom/browser/api/atom_api_event.cc
Normal file
26
atom/browser/api/atom_api_event.cc
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace {
|
||||
|
||||
v8::Local<v8::Object> CreateWithSender(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> sender) {
|
||||
return mate::internal::CreateJSEvent(isolate, sender, nullptr, base::nullopt);
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("createWithSender", &CreateWithSender);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_event, Initialize)
|
||||
@@ -5,16 +5,45 @@
|
||||
#include "atom/browser/api/atom_api_global_shortcut.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/atom_api_system_preferences.h"
|
||||
#include "atom/common/native_mate_converters/accelerator_converter.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
#if defined(OS_MACOSX)
|
||||
#include "base/mac/mac_util.h"
|
||||
#endif
|
||||
|
||||
using extensions::GlobalShortcutListener;
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool RegisteringMediaKeyForUntrustedClient(const ui::Accelerator& accelerator) {
|
||||
if (base::mac::IsAtLeastOS10_14()) {
|
||||
constexpr ui::KeyboardCode mediaKeys[] = {
|
||||
ui::VKEY_MEDIA_PLAY_PAUSE, ui::VKEY_MEDIA_NEXT_TRACK,
|
||||
ui::VKEY_MEDIA_PREV_TRACK, ui::VKEY_MEDIA_STOP};
|
||||
|
||||
if (std::find(std::begin(mediaKeys), std::end(mediaKeys),
|
||||
accelerator.key_code()) != std::end(mediaKeys)) {
|
||||
bool trusted =
|
||||
atom::api::SystemPreferences::IsTrustedAccessibilityClient(false);
|
||||
if (!trusted)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -31,15 +60,43 @@ void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
|
||||
if (accelerator_callback_map_.find(accelerator) ==
|
||||
accelerator_callback_map_.end()) {
|
||||
// This should never occur, because if it does, GlobalGlobalShortcutListener
|
||||
// notifes us with wrong accelerator.
|
||||
// notifies us with wrong accelerator.
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
accelerator_callback_map_[accelerator].Run();
|
||||
}
|
||||
|
||||
bool GlobalShortcut::RegisterAll(
|
||||
const std::vector<ui::Accelerator>& accelerators,
|
||||
const base::Closure& callback) {
|
||||
std::vector<ui::Accelerator> registered;
|
||||
|
||||
for (auto& accelerator : accelerators) {
|
||||
#if defined(OS_MACOSX)
|
||||
if (RegisteringMediaKeyForUntrustedClient(accelerator))
|
||||
return false;
|
||||
|
||||
GlobalShortcutListener* listener = GlobalShortcutListener::GetInstance();
|
||||
if (!listener->RegisterAccelerator(accelerator, this)) {
|
||||
// unregister all shortcuts if any failed
|
||||
UnregisterSome(registered);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
registered.push_back(accelerator);
|
||||
accelerator_callback_map_[accelerator] = callback;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
|
||||
const base::Closure& callback) {
|
||||
#if defined(OS_MACOSX)
|
||||
if (RegisteringMediaKeyForUntrustedClient(accelerator))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(accelerator,
|
||||
this)) {
|
||||
return false;
|
||||
@@ -58,6 +115,13 @@ void GlobalShortcut::Unregister(const ui::Accelerator& accelerator) {
|
||||
this);
|
||||
}
|
||||
|
||||
void GlobalShortcut::UnregisterSome(
|
||||
const std::vector<ui::Accelerator>& accelerators) {
|
||||
for (auto& accelerator : accelerators) {
|
||||
Unregister(accelerator);
|
||||
}
|
||||
}
|
||||
|
||||
bool GlobalShortcut::IsRegistered(const ui::Accelerator& accelerator) {
|
||||
return ContainsKey(accelerator_callback_map_, accelerator);
|
||||
}
|
||||
@@ -77,6 +141,7 @@ void GlobalShortcut::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "GlobalShortcut"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("registerAll", &GlobalShortcut::RegisterAll)
|
||||
.SetMethod("register", &GlobalShortcut::Register)
|
||||
.SetMethod("isRegistered", &GlobalShortcut::IsRegistered)
|
||||
.SetMethod("unregister", &GlobalShortcut::Unregister)
|
||||
@@ -100,4 +165,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_global_shortcut, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_global_shortcut, Initialize)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "base/callback.h"
|
||||
@@ -33,10 +34,13 @@ class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
|
||||
private:
|
||||
typedef std::map<ui::Accelerator, base::Closure> AcceleratorCallbackMap;
|
||||
|
||||
bool RegisterAll(const std::vector<ui::Accelerator>& accelerators,
|
||||
const base::Closure& callback);
|
||||
bool Register(const ui::Accelerator& accelerator,
|
||||
const base::Closure& callback);
|
||||
bool IsRegistered(const ui::Accelerator& accelerator);
|
||||
void Unregister(const ui::Accelerator& accelerator);
|
||||
void UnregisterSome(const std::vector<ui::Accelerator>& accelerators);
|
||||
void UnregisterAll();
|
||||
|
||||
// GlobalShortcutListener::Observer implementation.
|
||||
|
||||
@@ -9,9 +9,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
@@ -62,7 +61,7 @@ struct Converter<in_app_purchase::Product> {
|
||||
dict.Set("formattedPrice", val.formattedPrice);
|
||||
|
||||
// Downloadable Content Information
|
||||
dict.Set("isDownloadable", val.downloadable);
|
||||
dict.Set("isDownloadable", val.isDownloadable);
|
||||
|
||||
return dict.GetHandle();
|
||||
}
|
||||
@@ -92,7 +91,7 @@ void InAppPurchase::BuildPrototype(v8::Isolate* isolate,
|
||||
&in_app_purchase::FinishAllTransactions)
|
||||
.SetMethod("finishTransactionByDate",
|
||||
&in_app_purchase::FinishTransactionByDate)
|
||||
.SetMethod("getProducts", &in_app_purchase::GetProducts);
|
||||
.SetMethod("getProducts", &InAppPurchase::GetProducts);
|
||||
}
|
||||
|
||||
InAppPurchase::InAppPurchase(v8::Isolate* isolate) {
|
||||
@@ -101,13 +100,37 @@ InAppPurchase::InAppPurchase(v8::Isolate* isolate) {
|
||||
|
||||
InAppPurchase::~InAppPurchase() {}
|
||||
|
||||
void InAppPurchase::PurchaseProduct(const std::string& product_id,
|
||||
mate::Arguments* args) {
|
||||
v8::Local<v8::Promise> InAppPurchase::PurchaseProduct(
|
||||
const std::string& product_id,
|
||||
mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
atom::util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
int quantity = 1;
|
||||
in_app_purchase::InAppPurchaseCallback callback;
|
||||
args->GetNext(&quantity);
|
||||
args->GetNext(&callback);
|
||||
in_app_purchase::PurchaseProduct(product_id, quantity, callback);
|
||||
|
||||
in_app_purchase::PurchaseProduct(
|
||||
product_id, quantity,
|
||||
base::BindOnce(atom::util::Promise::ResolvePromise<bool>,
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> InAppPurchase::GetProducts(
|
||||
const std::vector<std::string>& productIDs,
|
||||
mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
atom::util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
in_app_purchase::GetProducts(
|
||||
productIDs, base::BindOnce(atom::util::Promise::ResolvePromise<
|
||||
std::vector<in_app_purchase::Product>>,
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void InAppPurchase::OnTransactionsUpdated(
|
||||
@@ -132,11 +155,12 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("inAppPurchase", InAppPurchase::Create(isolate));
|
||||
dict.Set("InAppPurchase",
|
||||
InAppPurchase::GetConstructor(isolate)->GetFunction());
|
||||
dict.Set("InAppPurchase", InAppPurchase::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_in_app_purchase, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_in_app_purchase, Initialize)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "atom/browser/mac/in_app_purchase.h"
|
||||
#include "atom/browser/mac/in_app_purchase_observer.h"
|
||||
#include "atom/browser/mac/in_app_purchase_product.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -30,7 +31,11 @@ class InAppPurchase : public mate::EventEmitter<InAppPurchase>,
|
||||
explicit InAppPurchase(v8::Isolate* isolate);
|
||||
~InAppPurchase() override;
|
||||
|
||||
void PurchaseProduct(const std::string& product_id, mate::Arguments* args);
|
||||
v8::Local<v8::Promise> PurchaseProduct(const std::string& product_id,
|
||||
mate::Arguments* args);
|
||||
|
||||
v8::Local<v8::Promise> GetProducts(const std::vector<std::string>& productIDs,
|
||||
mate::Arguments* args);
|
||||
|
||||
// TransactionObserver:
|
||||
void OnTransactionsUpdated(
|
||||
|
||||
@@ -9,12 +9,11 @@
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -40,7 +39,10 @@ void Menu::AfterInit(v8::Isolate* isolate) {
|
||||
delegate.Get("isCommandIdChecked", &is_checked_);
|
||||
delegate.Get("isCommandIdEnabled", &is_enabled_);
|
||||
delegate.Get("isCommandIdVisible", &is_visible_);
|
||||
delegate.Get("shouldCommandIdWorkWhenHidden", &works_when_hidden_);
|
||||
delegate.Get("getAcceleratorForCommandId", &get_accelerator_);
|
||||
delegate.Get("shouldRegisterAcceleratorForCommandId",
|
||||
&should_register_accelerator_);
|
||||
delegate.Get("executeCommand", &execute_command_);
|
||||
delegate.Get("menuWillShow", &menu_will_show_);
|
||||
}
|
||||
@@ -63,6 +65,12 @@ bool Menu::IsCommandIdVisible(int command_id) const {
|
||||
return is_visible_.Run(GetWrapper(), command_id);
|
||||
}
|
||||
|
||||
bool Menu::ShouldCommandIdWorkWhenHidden(int command_id) const {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
return works_when_hidden_.Run(GetWrapper(), command_id);
|
||||
}
|
||||
|
||||
bool Menu::GetAcceleratorForCommandIdWithParams(
|
||||
int command_id,
|
||||
bool use_default_accelerator,
|
||||
@@ -74,6 +82,12 @@ bool Menu::GetAcceleratorForCommandIdWithParams(
|
||||
return mate::ConvertFromV8(isolate(), val, accelerator);
|
||||
}
|
||||
|
||||
bool Menu::ShouldRegisterAcceleratorForCommandId(int command_id) const {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
return should_register_accelerator_.Run(GetWrapper(), command_id);
|
||||
}
|
||||
|
||||
void Menu::ExecuteCommand(int command_id, int flags) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
@@ -82,7 +96,7 @@ void Menu::ExecuteCommand(int command_id, int flags) {
|
||||
command_id);
|
||||
}
|
||||
|
||||
void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
|
||||
void Menu::OnMenuWillShow(ui::SimpleMenuModel* source) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
menu_will_show_.Run(GetWrapper());
|
||||
@@ -155,6 +169,12 @@ base::string16 Menu::GetSublabelAt(int index) const {
|
||||
return model_->GetSublabelAt(index);
|
||||
}
|
||||
|
||||
base::string16 Menu::GetAcceleratorTextAt(int index) const {
|
||||
ui::Accelerator accelerator;
|
||||
model_->GetAcceleratorAtWithParams(index, true, &accelerator);
|
||||
return accelerator.GetShortcutText();
|
||||
}
|
||||
|
||||
bool Menu::IsItemCheckedAt(int index) const {
|
||||
return model_->IsItemCheckedAt(index);
|
||||
}
|
||||
@@ -167,6 +187,10 @@ bool Menu::IsVisibleAt(int index) const {
|
||||
return model_->IsVisibleAt(index);
|
||||
}
|
||||
|
||||
bool Menu::WorksWhenHiddenAt(int index) const {
|
||||
return model_->WorksWhenHiddenAt(index);
|
||||
}
|
||||
|
||||
void Menu::OnMenuWillClose() {
|
||||
Emit("menu-will-close");
|
||||
}
|
||||
@@ -195,8 +219,10 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getCommandIdAt", &Menu::GetCommandIdAt)
|
||||
.SetMethod("getLabelAt", &Menu::GetLabelAt)
|
||||
.SetMethod("getSublabelAt", &Menu::GetSublabelAt)
|
||||
.SetMethod("getAcceleratorTextAt", &Menu::GetAcceleratorTextAt)
|
||||
.SetMethod("isItemCheckedAt", &Menu::IsItemCheckedAt)
|
||||
.SetMethod("isEnabledAt", &Menu::IsEnabledAt)
|
||||
.SetMethod("worksWhenHiddenAt", &Menu::WorksWhenHiddenAt)
|
||||
.SetMethod("isVisibleAt", &Menu::IsVisibleAt)
|
||||
.SetMethod("popupAt", &Menu::PopupAt)
|
||||
.SetMethod("closePopupAt", &Menu::ClosePopupAt);
|
||||
@@ -218,7 +244,9 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
Menu::SetConstructor(isolate, base::Bind(&Menu::New));
|
||||
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("Menu", Menu::GetConstructor(isolate)->GetFunction());
|
||||
dict.Set(
|
||||
"Menu",
|
||||
Menu::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
#if defined(OS_MACOSX)
|
||||
dict.SetMethod("setApplicationMenu", &Menu::SetApplicationMenu);
|
||||
dict.SetMethod("sendActionToFirstResponder",
|
||||
@@ -228,4 +256,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_menu, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_menu, Initialize)
|
||||
|
||||
@@ -47,12 +47,14 @@ class Menu : public mate::TrackableObject<Menu>,
|
||||
bool IsCommandIdChecked(int command_id) const override;
|
||||
bool IsCommandIdEnabled(int command_id) const override;
|
||||
bool IsCommandIdVisible(int command_id) const override;
|
||||
bool ShouldCommandIdWorkWhenHidden(int command_id) const override;
|
||||
bool GetAcceleratorForCommandIdWithParams(
|
||||
int command_id,
|
||||
bool use_default_accelerator,
|
||||
ui::Accelerator* accelerator) const override;
|
||||
bool ShouldRegisterAcceleratorForCommandId(int command_id) const override;
|
||||
void ExecuteCommand(int command_id, int event_flags) override;
|
||||
void MenuWillShow(ui::SimpleMenuModel* source) override;
|
||||
void OnMenuWillShow(ui::SimpleMenuModel* source) override;
|
||||
|
||||
virtual void PopupAt(TopLevelWindow* window,
|
||||
int x,
|
||||
@@ -91,16 +93,20 @@ class Menu : public mate::TrackableObject<Menu>,
|
||||
int GetCommandIdAt(int index) const;
|
||||
base::string16 GetLabelAt(int index) const;
|
||||
base::string16 GetSublabelAt(int index) const;
|
||||
base::string16 GetAcceleratorTextAt(int index) const;
|
||||
bool IsItemCheckedAt(int index) const;
|
||||
bool IsEnabledAt(int index) const;
|
||||
bool IsVisibleAt(int index) const;
|
||||
bool WorksWhenHiddenAt(int index) const;
|
||||
|
||||
// Stored delegate methods.
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> is_checked_;
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> is_enabled_;
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> is_visible_;
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> works_when_hidden_;
|
||||
base::Callback<v8::Local<v8::Value>(v8::Local<v8::Value>, int, bool)>
|
||||
get_accelerator_;
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> should_register_accelerator_;
|
||||
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>, int)>
|
||||
execute_command_;
|
||||
base::Callback<void(v8::Local<v8::Value>)> menu_will_show_;
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/mac/scoped_sending_event.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace {
|
||||
@@ -43,7 +44,7 @@ void MenuMac::PopupAt(TopLevelWindow* window,
|
||||
auto popup = base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
|
||||
native_window->GetWeakPtr(), window->weak_map_id(), x,
|
||||
y, positioning_item, callback);
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, popup);
|
||||
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, popup);
|
||||
}
|
||||
|
||||
void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
@@ -54,7 +55,7 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
base::Closure callback) {
|
||||
if (!native_window)
|
||||
return;
|
||||
NSWindow* nswindow = native_window->GetNativeWindow();
|
||||
NSWindow* nswindow = native_window->GetNativeWindow().GetNativeNSWindow();
|
||||
|
||||
auto close_callback = base::Bind(
|
||||
&MenuMac::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
|
||||
@@ -97,7 +98,7 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
|
||||
[popup_controllers_[window_id] setCloseCallback:close_callback];
|
||||
// Make sure events can be pumped while the menu is up.
|
||||
base::MessageLoop::ScopedNestableTaskAllower allow;
|
||||
base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
|
||||
|
||||
// One of the events that could be pumped is |window.close()|.
|
||||
// User-initiated event-tracking loops protect against this by
|
||||
|
||||
@@ -52,7 +52,7 @@ void MenuViews::PopupAt(TopLevelWindow* window,
|
||||
std::make_unique<MenuRunner>(model(), flags, close_callback);
|
||||
menu_runners_[window_id]->RunMenuAt(
|
||||
native_window->widget(), NULL, gfx::Rect(location, gfx::Size()),
|
||||
views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE);
|
||||
views::MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_MOUSE);
|
||||
}
|
||||
|
||||
void MenuViews::ClosePopupAt(int32_t window_id) {
|
||||
|
||||
@@ -31,7 +31,9 @@ void Net::BuildPrototype(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Net::URLRequest(v8::Isolate* isolate) {
|
||||
return URLRequest::GetConstructor(isolate)->GetFunction();
|
||||
return URLRequest::GetConstructor(isolate)
|
||||
->GetFunction(isolate->GetCurrentContext())
|
||||
.ToLocalChecked();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
@@ -53,9 +55,10 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("net", Net::Create(isolate));
|
||||
dict.Set("Net", Net::GetConstructor(isolate)->GetFunction());
|
||||
dict.Set("Net",
|
||||
Net::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_net, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_net, Initialize)
|
||||
|
||||
@@ -7,18 +7,18 @@
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/net/system_network_context_manager.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/command_line.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "components/net_log/chrome_net_log.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -27,8 +27,8 @@ NetLog::NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
Init(isolate);
|
||||
|
||||
net_log_writer_ =
|
||||
atom::AtomBrowserMainParts::Get()->net_log()->net_export_file_writer();
|
||||
net_log_writer_ = g_browser_process->system_network_context_manager()
|
||||
->GetNetExportFileWriter();
|
||||
net_log_writer_->AddObserver(this);
|
||||
}
|
||||
|
||||
@@ -86,19 +86,18 @@ std::string NetLog::GetCurrentlyLoggingPath() const {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void NetLog::StopLogging(mate::Arguments* args) {
|
||||
net_log::NetExportFileWriter::FilePathCallback callback;
|
||||
if (!args->GetNext(&callback)) {
|
||||
args->ThrowError("Invalid callback function");
|
||||
return;
|
||||
}
|
||||
v8::Local<v8::Promise> NetLog::StopLogging(mate::Arguments* args) {
|
||||
util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
if (IsCurrentlyLogging()) {
|
||||
stop_callback_queue_.emplace_back(callback);
|
||||
stop_callback_queue_.emplace_back(std::move(promise));
|
||||
net_log_writer_->StopNetLog(nullptr);
|
||||
} else {
|
||||
callback.Run(base::FilePath());
|
||||
promise.Resolve(base::FilePath());
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void NetLog::OnNewState(const base::DictionaryValue& state) {
|
||||
@@ -108,9 +107,12 @@ void NetLog::OnNewState(const base::DictionaryValue& state) {
|
||||
return;
|
||||
|
||||
if (GetLoggingState() == "NOT_LOGGING") {
|
||||
for (auto& callback : stop_callback_queue_) {
|
||||
if (!callback.is_null())
|
||||
net_log_writer_->GetFilePathToCompletedLog(callback);
|
||||
for (auto& promise : stop_callback_queue_) {
|
||||
// TODO(zcbenz): Remove the use of CopyablePromise when the
|
||||
// GetFilePathToCompletedLog API accepts OnceCallback.
|
||||
net_log_writer_->GetFilePathToCompletedLog(base::Bind(
|
||||
util::CopyablePromise::ResolveCopyablePromise<const base::FilePath&>,
|
||||
util::CopyablePromise(promise)));
|
||||
}
|
||||
stop_callback_queue_.clear();
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/values.h"
|
||||
#include "components/net_log/net_export_file_writer.h"
|
||||
@@ -34,7 +35,7 @@ class NetLog : public mate::TrackableObject<NetLog>,
|
||||
std::string GetLoggingState() const;
|
||||
bool IsCurrentlyLogging() const;
|
||||
std::string GetCurrentlyLoggingPath() const;
|
||||
void StopLogging(mate::Arguments* args);
|
||||
v8::Local<v8::Promise> StopLogging(mate::Arguments* args);
|
||||
|
||||
protected:
|
||||
explicit NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
@@ -46,8 +47,7 @@ class NetLog : public mate::TrackableObject<NetLog>,
|
||||
private:
|
||||
AtomBrowserContext* browser_context_;
|
||||
net_log::NetExportFileWriter* net_log_writer_;
|
||||
std::list<net_log::NetExportFileWriter::FilePathCallback>
|
||||
stop_callback_queue_;
|
||||
std::list<atom::util::Promise> stop_callback_queue_;
|
||||
std::unique_ptr<base::DictionaryValue> net_log_state_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NetLog);
|
||||
|
||||
@@ -5,27 +5,25 @@
|
||||
#include "atom/browser/api/atom_api_notification.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/guid.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "brightray/browser/browser_client.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "url/gurl.h"
|
||||
// Must be the last in the includes list.
|
||||
// See https://github.com/electron/electron/issues/10363
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
template <>
|
||||
struct Converter<brightray::NotificationAction> {
|
||||
struct Converter<atom::NotificationAction> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
brightray::NotificationAction* out) {
|
||||
atom::NotificationAction* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
@@ -38,7 +36,7 @@ struct Converter<brightray::NotificationAction> {
|
||||
}
|
||||
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
brightray::NotificationAction val) {
|
||||
atom::NotificationAction val) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("text", val.text);
|
||||
dict.Set("type", val.type);
|
||||
@@ -56,7 +54,8 @@ Notification::Notification(v8::Isolate* isolate,
|
||||
mate::Arguments* args) {
|
||||
InitWith(isolate, wrapper);
|
||||
|
||||
presenter_ = brightray::BrowserClient::Get()->GetNotificationPresenter();
|
||||
presenter_ = static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())
|
||||
->GetNotificationPresenter();
|
||||
|
||||
mate::Dictionary opts;
|
||||
if (args->GetNext(&opts)) {
|
||||
@@ -119,7 +118,7 @@ base::string16 Notification::GetSound() const {
|
||||
return sound_;
|
||||
}
|
||||
|
||||
std::vector<brightray::NotificationAction> Notification::GetActions() const {
|
||||
std::vector<atom::NotificationAction> Notification::GetActions() const {
|
||||
return actions_;
|
||||
}
|
||||
|
||||
@@ -157,7 +156,7 @@ void Notification::SetSound(const base::string16& new_sound) {
|
||||
}
|
||||
|
||||
void Notification::SetActions(
|
||||
const std::vector<brightray::NotificationAction>& actions) {
|
||||
const std::vector<atom::NotificationAction>& actions) {
|
||||
actions_ = actions;
|
||||
}
|
||||
|
||||
@@ -200,7 +199,7 @@ void Notification::Show() {
|
||||
if (presenter_) {
|
||||
notification_ = presenter_->CreateNotification(this, base::GenerateGUID());
|
||||
if (notification_) {
|
||||
brightray::NotificationOptions options;
|
||||
atom::NotificationOptions options;
|
||||
options.title = title_;
|
||||
options.subtitle = subtitle_;
|
||||
options.msg = body_;
|
||||
@@ -218,7 +217,8 @@ void Notification::Show() {
|
||||
}
|
||||
|
||||
bool Notification::IsSupported() {
|
||||
return !!brightray::BrowserClient::Get()->GetNotificationPresenter();
|
||||
return !!static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())
|
||||
->GetNotificationPresenter();
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -261,12 +261,13 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
Notification::SetConstructor(isolate, base::Bind(&Notification::New));
|
||||
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("Notification",
|
||||
Notification::GetConstructor(isolate)->GetFunction());
|
||||
dict.Set("Notification", Notification::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
|
||||
dict.SetMethod("isSupported", &Notification::IsSupported);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_notification, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_common_notification, Initialize)
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/notifications/notification.h"
|
||||
#include "atom/browser/notifications/notification_delegate.h"
|
||||
#include "atom/browser/notifications/notification_presenter.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "brightray/browser/notification.h"
|
||||
#include "brightray/browser/notification_delegate.h"
|
||||
#include "brightray/browser/notification_presenter.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace atom {
|
||||
namespace api {
|
||||
|
||||
class Notification : public mate::TrackableObject<Notification>,
|
||||
public brightray::NotificationDelegate {
|
||||
public NotificationDelegate {
|
||||
public:
|
||||
static mate::WrappableBase* New(mate::Arguments* args);
|
||||
static bool IsSupported();
|
||||
@@ -55,7 +55,7 @@ class Notification : public mate::TrackableObject<Notification>,
|
||||
bool GetHasReply() const;
|
||||
base::string16 GetReplyPlaceholder() const;
|
||||
base::string16 GetSound() const;
|
||||
std::vector<brightray::NotificationAction> GetActions() const;
|
||||
std::vector<atom::NotificationAction> GetActions() const;
|
||||
base::string16 GetCloseButtonText() const;
|
||||
|
||||
// Prop Setters
|
||||
@@ -66,7 +66,7 @@ class Notification : public mate::TrackableObject<Notification>,
|
||||
void SetHasReply(bool new_has_reply);
|
||||
void SetReplyPlaceholder(const base::string16& new_reply_placeholder);
|
||||
void SetSound(const base::string16& sound);
|
||||
void SetActions(const std::vector<brightray::NotificationAction>& actions);
|
||||
void SetActions(const std::vector<atom::NotificationAction>& actions);
|
||||
void SetCloseButtonText(const base::string16& text);
|
||||
|
||||
private:
|
||||
@@ -80,12 +80,12 @@ class Notification : public mate::TrackableObject<Notification>,
|
||||
bool has_reply_ = false;
|
||||
base::string16 reply_placeholder_;
|
||||
base::string16 sound_;
|
||||
std::vector<brightray::NotificationAction> actions_;
|
||||
std::vector<atom::NotificationAction> actions_;
|
||||
base::string16 close_button_text_;
|
||||
|
||||
brightray::NotificationPresenter* presenter_;
|
||||
atom::NotificationPresenter* presenter_;
|
||||
|
||||
base::WeakPtr<brightray::Notification> notification_;
|
||||
base::WeakPtr<atom::Notification> notification_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Notification);
|
||||
};
|
||||
|
||||
@@ -6,12 +6,11 @@
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/power_monitor/power_monitor.h"
|
||||
#include "base/power_monitor/power_monitor_device_source.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
template <>
|
||||
struct Converter<ui::IdleState> {
|
||||
@@ -84,19 +83,19 @@ void PowerMonitor::OnResume() {
|
||||
Emit("resume");
|
||||
}
|
||||
|
||||
void PowerMonitor::QuerySystemIdleState(v8::Isolate* isolate,
|
||||
int idle_threshold,
|
||||
const ui::IdleCallback& callback) {
|
||||
ui::IdleState PowerMonitor::GetSystemIdleState(v8::Isolate* isolate,
|
||||
int idle_threshold) {
|
||||
if (idle_threshold > 0) {
|
||||
ui::CalculateIdleState(idle_threshold, callback);
|
||||
return ui::CalculateIdleState(idle_threshold);
|
||||
} else {
|
||||
isolate->ThrowException(v8::Exception::TypeError(mate::StringToV8(
|
||||
isolate, "Invalid idle threshold, must be greater than 0")));
|
||||
return ui::IDLE_STATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
void PowerMonitor::QuerySystemIdleTime(const ui::IdleTimeCallback& callback) {
|
||||
ui::CalculateIdleTime(callback);
|
||||
int PowerMonitor::GetSystemIdleTime() {
|
||||
return ui::CalculateIdleTime();
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -122,8 +121,8 @@ void PowerMonitor::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("blockShutdown", &PowerMonitor::BlockShutdown)
|
||||
.SetMethod("unblockShutdown", &PowerMonitor::UnblockShutdown)
|
||||
#endif
|
||||
.SetMethod("querySystemIdleState", &PowerMonitor::QuerySystemIdleState)
|
||||
.SetMethod("querySystemIdleTime", &PowerMonitor::QuerySystemIdleTime);
|
||||
.SetMethod("getSystemIdleState", &PowerMonitor::GetSystemIdleState)
|
||||
.SetMethod("getSystemIdleTime", &PowerMonitor::GetSystemIdleTime);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
@@ -141,10 +140,11 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("powerMonitor", PowerMonitor::Create(isolate));
|
||||
dict.Set("PowerMonitor",
|
||||
PowerMonitor::GetConstructor(isolate)->GetFunction());
|
||||
dict.Set("PowerMonitor", PowerMonitor::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_monitor, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_power_monitor, Initialize)
|
||||
|
||||
@@ -46,10 +46,8 @@ class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
|
||||
void OnResume() override;
|
||||
|
||||
private:
|
||||
void QuerySystemIdleState(v8::Isolate* isolate,
|
||||
int idle_threshold,
|
||||
const ui::IdleCallback& callback);
|
||||
void QuerySystemIdleTime(const ui::IdleTimeCallback& callback);
|
||||
ui::IdleState GetSystemIdleState(v8::Isolate* isolate, int idle_threshold);
|
||||
int GetSystemIdleTime();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Static callback invoked when a message comes in to our messaging window.
|
||||
|
||||
@@ -6,11 +6,14 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/task_scheduler/post_task.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "content/public/common/service_manager_connection.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "services/device/public/mojom/constants.mojom.h"
|
||||
#include "services/device/public/mojom/wake_lock_provider.mojom.h"
|
||||
#include "services/service_manager/public/cpp/connector.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
@@ -39,16 +42,19 @@ namespace atom {
|
||||
namespace api {
|
||||
|
||||
PowerSaveBlocker::PowerSaveBlocker(v8::Isolate* isolate)
|
||||
: current_blocker_type_(
|
||||
device::mojom::WakeLockType::kPreventAppSuspension) {
|
||||
: current_lock_type_(device::mojom::WakeLockType::kPreventAppSuspension),
|
||||
is_wake_lock_active_(false) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
PowerSaveBlocker::~PowerSaveBlocker() {}
|
||||
|
||||
void PowerSaveBlocker::UpdatePowerSaveBlocker() {
|
||||
if (power_save_blocker_types_.empty()) {
|
||||
power_save_blocker_.reset();
|
||||
if (wake_lock_types_.empty()) {
|
||||
if (is_wake_lock_active_) {
|
||||
GetWakeLock()->CancelWakeLock();
|
||||
is_wake_lock_active_ = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -58,45 +64,57 @@ void PowerSaveBlocker::UpdatePowerSaveBlocker() {
|
||||
// higher precedence level than |WakeLockType::kPreventAppSuspension|.
|
||||
//
|
||||
// Only the highest-precedence blocker type takes effect.
|
||||
device::mojom::WakeLockType new_blocker_type =
|
||||
device::mojom::WakeLockType new_lock_type =
|
||||
device::mojom::WakeLockType::kPreventAppSuspension;
|
||||
for (const auto& element : power_save_blocker_types_) {
|
||||
for (const auto& element : wake_lock_types_) {
|
||||
if (element.second == device::mojom::WakeLockType::kPreventDisplaySleep) {
|
||||
new_blocker_type = device::mojom::WakeLockType::kPreventDisplaySleep;
|
||||
new_lock_type = device::mojom::WakeLockType::kPreventDisplaySleep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!power_save_blocker_ || new_blocker_type != current_blocker_type_) {
|
||||
auto new_blocker = std::make_unique<device::PowerSaveBlocker>(
|
||||
new_blocker_type, device::mojom::WakeLockReason::kOther,
|
||||
ATOM_PRODUCT_NAME, base::ThreadTaskRunnerHandle::Get(),
|
||||
// This task runner may be used by some device service
|
||||
// implementation bits to interface with dbus client code, which in
|
||||
// turn imposes some subtle thread affinity on the clients. We
|
||||
// therefore require a single-thread runner.
|
||||
base::CreateSingleThreadTaskRunnerWithTraits(
|
||||
{base::MayBlock(), base::TaskPriority::BACKGROUND}));
|
||||
power_save_blocker_.swap(new_blocker);
|
||||
current_blocker_type_ = new_blocker_type;
|
||||
if (current_lock_type_ != new_lock_type) {
|
||||
GetWakeLock()->ChangeType(new_lock_type, base::DoNothing());
|
||||
current_lock_type_ = new_lock_type;
|
||||
}
|
||||
if (!is_wake_lock_active_) {
|
||||
GetWakeLock()->RequestWakeLock();
|
||||
is_wake_lock_active_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
device::mojom::WakeLock* PowerSaveBlocker::GetWakeLock() {
|
||||
if (!wake_lock_) {
|
||||
device::mojom::WakeLockProviderPtr wake_lock_provider;
|
||||
DCHECK(content::ServiceManagerConnection::GetForProcess());
|
||||
auto* connector =
|
||||
content::ServiceManagerConnection::GetForProcess()->GetConnector();
|
||||
connector->BindInterface(device::mojom::kServiceName,
|
||||
mojo::MakeRequest(&wake_lock_provider));
|
||||
|
||||
wake_lock_provider->GetWakeLockWithoutContext(
|
||||
device::mojom::WakeLockType::kPreventAppSuspension,
|
||||
device::mojom::WakeLockReason::kOther, ATOM_PRODUCT_NAME,
|
||||
mojo::MakeRequest(&wake_lock_));
|
||||
}
|
||||
return wake_lock_.get();
|
||||
}
|
||||
|
||||
int PowerSaveBlocker::Start(device::mojom::WakeLockType type) {
|
||||
static int count = 0;
|
||||
power_save_blocker_types_[count] = type;
|
||||
wake_lock_types_[count] = type;
|
||||
UpdatePowerSaveBlocker();
|
||||
return count++;
|
||||
}
|
||||
|
||||
bool PowerSaveBlocker::Stop(int id) {
|
||||
bool success = power_save_blocker_types_.erase(id) > 0;
|
||||
bool success = wake_lock_types_.erase(id) > 0;
|
||||
UpdatePowerSaveBlocker();
|
||||
return success;
|
||||
}
|
||||
|
||||
bool PowerSaveBlocker::IsStarted(int id) {
|
||||
return power_save_blocker_types_.find(id) != power_save_blocker_types_.end();
|
||||
return wake_lock_types_.find(id) != wake_lock_types_.end();
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -132,4 +150,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_save_blocker, Initialize);
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_power_save_blocker, Initialize)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "services/device/wake_lock/power_save_blocker/power_save_blocker.h"
|
||||
#include "services/device/public/mojom/wake_lock.mojom.h"
|
||||
|
||||
namespace mate {
|
||||
class Dictionary;
|
||||
@@ -37,14 +37,19 @@ class PowerSaveBlocker : public mate::TrackableObject<PowerSaveBlocker> {
|
||||
bool Stop(int id);
|
||||
bool IsStarted(int id);
|
||||
|
||||
std::unique_ptr<device::PowerSaveBlocker> power_save_blocker_;
|
||||
device::mojom::WakeLock* GetWakeLock();
|
||||
|
||||
// Current blocker type used by |power_save_blocker_|
|
||||
device::mojom::WakeLockType current_blocker_type_;
|
||||
// Current wake lock level.
|
||||
device::mojom::WakeLockType current_lock_type_;
|
||||
|
||||
// Whether the wake lock is currently active.
|
||||
bool is_wake_lock_active_;
|
||||
|
||||
// Map from id to the corresponding blocker type for each request.
|
||||
using WakeLockTypeMap = std::map<int, device::mojom::WakeLockType>;
|
||||
WakeLockTypeMap power_save_blocker_types_;
|
||||
WakeLockTypeMap wake_lock_types_;
|
||||
|
||||
device::mojom::WakeLockPtr wake_lock_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
|
||||
};
|
||||
|
||||
@@ -24,47 +24,119 @@
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// List of registered custom standard schemes.
|
||||
std::vector<std::string> g_standard_schemes;
|
||||
|
||||
struct SchemeOptions {
|
||||
bool standard = false;
|
||||
bool secure = false;
|
||||
bool bypassCSP = false;
|
||||
bool allowServiceWorkers = false;
|
||||
bool supportFetchAPI = false;
|
||||
bool corsEnabled = false;
|
||||
};
|
||||
|
||||
struct CustomScheme {
|
||||
std::string scheme;
|
||||
SchemeOptions options;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<CustomScheme> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
CustomScheme* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
if (!dict.Get("scheme", &(out->scheme)))
|
||||
return false;
|
||||
mate::Dictionary opt;
|
||||
// options are optional. Default values specified in SchemeOptions are used
|
||||
if (dict.Get("privileges", &opt)) {
|
||||
opt.Get("standard", &(out->options.standard));
|
||||
opt.Get("supportFetchAPI", &(out->options.supportFetchAPI));
|
||||
opt.Get("secure", &(out->options.secure));
|
||||
opt.Get("bypassCSP", &(out->options.bypassCSP));
|
||||
opt.Get("allowServiceWorkers", &(out->options.allowServiceWorkers));
|
||||
opt.Get("supportFetchAPI", &(out->options.supportFetchAPI));
|
||||
opt.Get("corsEnabled", &(out->options.corsEnabled));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
std::vector<std::string> GetStandardSchemes() {
|
||||
return g_standard_schemes;
|
||||
}
|
||||
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
|
||||
mate::Arguments* args) {
|
||||
g_standard_schemes = schemes;
|
||||
void RegisterSchemesAsPrivileged(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
std::vector<CustomScheme> custom_schemes;
|
||||
if (!mate::ConvertFromV8(args->isolate(), val, &custom_schemes)) {
|
||||
args->ThrowError("Argument must be an array of custom schemes.");
|
||||
return;
|
||||
}
|
||||
|
||||
mate::Dictionary opts;
|
||||
bool secure = false;
|
||||
args->GetNext(&opts) && opts.Get("secure", &secure);
|
||||
|
||||
// Dynamically register the schemes.
|
||||
auto* policy = content::ChildProcessSecurityPolicy::GetInstance();
|
||||
for (const std::string& scheme : schemes) {
|
||||
url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITH_HOST);
|
||||
if (secure) {
|
||||
url::AddSecureScheme(scheme.c_str());
|
||||
std::vector<std::string> secure_schemes, cspbypassing_schemes, fetch_schemes,
|
||||
service_worker_schemes, cors_schemes;
|
||||
for (const auto& custom_scheme : custom_schemes) {
|
||||
// Register scheme to privileged list (https, wss, data, chrome-extension)
|
||||
if (custom_scheme.options.standard) {
|
||||
auto* policy = content::ChildProcessSecurityPolicy::GetInstance();
|
||||
url::AddStandardScheme(custom_scheme.scheme.c_str(),
|
||||
url::SCHEME_WITH_HOST);
|
||||
g_standard_schemes.push_back(custom_scheme.scheme);
|
||||
policy->RegisterWebSafeScheme(custom_scheme.scheme);
|
||||
}
|
||||
if (custom_scheme.options.secure) {
|
||||
secure_schemes.push_back(custom_scheme.scheme);
|
||||
url::AddSecureScheme(custom_scheme.scheme.c_str());
|
||||
}
|
||||
if (custom_scheme.options.bypassCSP) {
|
||||
cspbypassing_schemes.push_back(custom_scheme.scheme);
|
||||
url::AddCSPBypassingScheme(custom_scheme.scheme.c_str());
|
||||
}
|
||||
if (custom_scheme.options.corsEnabled) {
|
||||
cors_schemes.push_back(custom_scheme.scheme);
|
||||
url::AddCorsEnabledScheme(custom_scheme.scheme.c_str());
|
||||
}
|
||||
if (custom_scheme.options.supportFetchAPI) {
|
||||
fetch_schemes.push_back(custom_scheme.scheme);
|
||||
}
|
||||
if (custom_scheme.options.allowServiceWorkers) {
|
||||
service_worker_schemes.push_back(custom_scheme.scheme);
|
||||
}
|
||||
policy->RegisterWebSafeScheme(scheme);
|
||||
}
|
||||
|
||||
// Add the schemes to command line switches, so child processes can also
|
||||
// register them.
|
||||
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
|
||||
atom::switches::kStandardSchemes, base::JoinString(schemes, ","));
|
||||
if (secure) {
|
||||
const auto AppendSchemesToCmdLine = [](const char* switch_name,
|
||||
std::vector<std::string> schemes) {
|
||||
// Add the schemes to command line switches, so child processes can also
|
||||
// register them.
|
||||
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
|
||||
atom::switches::kSecureSchemes, base::JoinString(schemes, ","));
|
||||
}
|
||||
switch_name, base::JoinString(schemes, ","));
|
||||
};
|
||||
|
||||
AppendSchemesToCmdLine(atom::switches::kSecureSchemes, secure_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kBypassCSPSchemes,
|
||||
cspbypassing_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kCORSSchemes, cors_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kFetchSchemes, fetch_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kServiceWorkerSchemes,
|
||||
service_worker_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kStandardSchemes, g_standard_schemes);
|
||||
}
|
||||
|
||||
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
@@ -73,20 +145,14 @@ Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
}
|
||||
|
||||
Protocol::~Protocol() {}
|
||||
|
||||
void Protocol::RegisterServiceWorkerSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes);
|
||||
}
|
||||
|
||||
void Protocol::UnregisterProtocol(const std::string& scheme,
|
||||
mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
args->GetNext(&callback);
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::PostTaskWithTraitsAndReplyWithResult(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&Protocol::UnregisterProtocolInIO,
|
||||
base::RetainedRef(getter), scheme),
|
||||
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||
@@ -103,22 +169,26 @@ Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
|
||||
return PROTOCOL_OK;
|
||||
}
|
||||
|
||||
void Protocol::IsProtocolHandled(const std::string& scheme,
|
||||
const BooleanCallback& callback) {
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Protocol::IsProtocolHandledInIO, base::RetainedRef(getter),
|
||||
scheme),
|
||||
callback);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Protocol::IsProtocolHandledInIO(
|
||||
bool IsProtocolHandledInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
const std::string& scheme) {
|
||||
return request_context_getter->job_factory()->IsHandledProtocol(scheme);
|
||||
bool is_handled =
|
||||
request_context_getter->job_factory()->IsHandledProtocol(scheme);
|
||||
return is_handled;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Protocol::IsProtocolHandled(const std::string& scheme) {
|
||||
util::Promise promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
|
||||
base::PostTaskWithTraitsAndReplyWithResult(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&IsProtocolHandledInIO, base::RetainedRef(getter), scheme),
|
||||
base::BindOnce(util::Promise::ResolvePromise<bool>, std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Protocol::UninterceptProtocol(const std::string& scheme,
|
||||
@@ -127,8 +197,8 @@ void Protocol::UninterceptProtocol(const std::string& scheme,
|
||||
args->GetNext(&callback);
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::PostTaskWithTraitsAndReplyWithResult(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&Protocol::UninterceptProtocolInIO,
|
||||
base::RetainedRef(getter), scheme),
|
||||
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||
@@ -188,8 +258,6 @@ void Protocol::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Protocol"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("registerServiceWorkerSchemes",
|
||||
&Protocol::RegisterServiceWorkerSchemes)
|
||||
.SetMethod("registerStringProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestStringJob>)
|
||||
.SetMethod("registerBufferProtocol",
|
||||
@@ -221,16 +289,16 @@ void Protocol::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
namespace {
|
||||
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
|
||||
mate::Arguments* args) {
|
||||
void RegisterSchemesAsPrivileged(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
if (atom::Browser::Get()->is_ready()) {
|
||||
args->ThrowError(
|
||||
"protocol.registerStandardSchemes should be called before "
|
||||
"protocol.registerSchemesAsPrivileged should be called before "
|
||||
"app is ready");
|
||||
return;
|
||||
}
|
||||
|
||||
atom::api::RegisterStandardSchemes(schemes, args);
|
||||
atom::api::RegisterSchemesAsPrivileged(val, args);
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
@@ -239,10 +307,10 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.SetMethod("registerStandardSchemes", &RegisterStandardSchemes);
|
||||
dict.SetMethod("registerSchemesAsPrivileged", &RegisterSchemesAsPrivileged);
|
||||
dict.SetMethod("getStandardSchemes", &atom::api::GetStandardSchemes);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_protocol, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_protocol, Initialize)
|
||||
|
||||
@@ -14,8 +14,11 @@
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/arguments.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
@@ -31,15 +34,15 @@ namespace atom {
|
||||
namespace api {
|
||||
|
||||
std::vector<std::string> GetStandardSchemes();
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
|
||||
mate::Arguments* args);
|
||||
|
||||
void RegisterSchemesAsPrivileged(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args);
|
||||
|
||||
class Protocol : public mate::TrackableObject<Protocol> {
|
||||
public:
|
||||
using Handler =
|
||||
base::Callback<void(const base::DictionaryValue&, v8::Local<v8::Value>)>;
|
||||
using CompletionCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
using BooleanCallback = base::Callback<void(bool)>;
|
||||
|
||||
static mate::Handle<Protocol> Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context);
|
||||
@@ -92,9 +95,6 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
||||
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
|
||||
};
|
||||
|
||||
// Register schemes that can handle service worker.
|
||||
void RegisterServiceWorkerSchemes(const std::vector<std::string>& schemes);
|
||||
|
||||
// Register the protocol with certain request job.
|
||||
template <typename RequestJob>
|
||||
void RegisterProtocol(const std::string& scheme,
|
||||
@@ -104,8 +104,8 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
||||
args->GetNext(&callback);
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::PostTaskWithTraitsAndReplyWithResult(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&Protocol::RegisterProtocolInIO<RequestJob>,
|
||||
base::RetainedRef(getter), isolate(), scheme, handler),
|
||||
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||
@@ -134,11 +134,7 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
||||
const std::string& scheme);
|
||||
|
||||
// Whether the protocol has handler registered.
|
||||
void IsProtocolHandled(const std::string& scheme,
|
||||
const BooleanCallback& callback);
|
||||
static bool IsProtocolHandledInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
const std::string& scheme);
|
||||
v8::Local<v8::Promise> IsProtocolHandled(const std::string& scheme);
|
||||
|
||||
// Replace the protocol handler with a new one.
|
||||
template <typename RequestJob>
|
||||
@@ -149,8 +145,8 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
||||
args->GetNext(&callback);
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::PostTaskWithTraitsAndReplyWithResult(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&Protocol::InterceptProtocolInIO<RequestJob>,
|
||||
base::RetainedRef(getter), isolate(), scheme, handler),
|
||||
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||
|
||||
@@ -7,12 +7,11 @@
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -26,7 +25,7 @@ bool IsWebContents(v8::Isolate* isolate, content::RenderProcessHost* process) {
|
||||
if (!web_contents)
|
||||
return false;
|
||||
|
||||
auto api_web_contents = WebContents::CreateFrom(isolate, web_contents);
|
||||
auto api_web_contents = WebContents::FromOrCreate(isolate, web_contents);
|
||||
auto type = api_web_contents->GetType();
|
||||
return type == WebContents::Type::BROWSER_WINDOW ||
|
||||
type == WebContents::Type::WEB_VIEW;
|
||||
@@ -87,5 +86,5 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_render_process_preferences,
|
||||
Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_render_process_preferences,
|
||||
Initialize)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "atom/browser/api/atom_api_browser_window.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/bind.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
@@ -21,8 +22,6 @@
|
||||
#include "ui/display/win/screen_win.h"
|
||||
#endif
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -164,9 +163,11 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("screen", Screen::Create(isolate));
|
||||
dict.Set("Screen", Screen::GetConstructor(isolate)->GetFunction());
|
||||
dict.Set(
|
||||
"Screen",
|
||||
Screen::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_screen, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_common_screen, Initialize)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_permission_manager.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/media/media_device_id_salt.h"
|
||||
#include "atom/browser/net/atom_cert_verifier.h"
|
||||
#include "atom/browser/session_preferences.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
@@ -27,11 +28,12 @@
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/guid.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "brightray/browser/media/media_device_id_salt.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "components/download/public/common/download_danger_type.h"
|
||||
@@ -39,15 +41,17 @@
|
||||
#include "components/prefs/value_map_pref_store.h"
|
||||
#include "components/proxy_config/proxy_config_dictionary.h"
|
||||
#include "components/proxy_config/proxy_config_pref_names.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/download_item_utils.h"
|
||||
#include "content/public/browser/download_manager_delegate.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/base/completion_repeating_callback.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/disk_cache/disk_cache.h"
|
||||
#include "net/dns/host_cache.h"
|
||||
#include "net/dns/host_cache.h" // nogncheck
|
||||
#include "net/http/http_auth_handler_factory.h"
|
||||
#include "net/http/http_auth_preferences.h"
|
||||
#include "net/http/http_cache.h"
|
||||
@@ -57,9 +61,6 @@
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using atom::api::Cookies;
|
||||
using content::BrowserThread;
|
||||
using content::StoragePartition;
|
||||
|
||||
@@ -209,27 +210,32 @@ const char kPersistPrefix[] = "persist:";
|
||||
// Referenced session objects.
|
||||
std::map<uint32_t, v8::Global<v8::Object>> g_sessions;
|
||||
|
||||
// Runs the callback in UI thread.
|
||||
void RunCallbackInUI(const base::Callback<void()>& callback) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
|
||||
}
|
||||
template <typename... T>
|
||||
void RunCallbackInUI(const base::Callback<void(T...)>& callback, T... result) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::BindOnce(callback, result...));
|
||||
void ResolveOrRejectPromiseInUI(util::Promise promise, int net_error) {
|
||||
if (net_error != net::OK) {
|
||||
std::string err_msg = net::ErrorToString(net_error);
|
||||
util::Promise::RejectPromise(std::move(promise), std::move(err_msg));
|
||||
} else {
|
||||
util::Promise::ResolveEmptyPromise(std::move(promise));
|
||||
}
|
||||
}
|
||||
|
||||
// Callback of HttpCache::GetBackend.
|
||||
void OnGetBackend(disk_cache::Backend** backend_ptr,
|
||||
Session::CacheAction action,
|
||||
const net::CompletionCallback& callback,
|
||||
const util::CopyablePromise& promise,
|
||||
int result) {
|
||||
if (result != net::OK) {
|
||||
RunCallbackInUI(callback, result);
|
||||
std::string err_msg =
|
||||
"Failed to retrieve cache backend: " + net::ErrorToString(result);
|
||||
util::Promise::RejectPromise(promise.GetPromise(), std::move(err_msg));
|
||||
} else if (backend_ptr && *backend_ptr) {
|
||||
if (action == Session::CacheAction::CLEAR) {
|
||||
(*backend_ptr)
|
||||
->DoomAllEntries(base::Bind(&RunCallbackInUI<int>, callback));
|
||||
auto success =
|
||||
(*backend_ptr)
|
||||
->DoomAllEntries(base::BindOnce(&ResolveOrRejectPromiseInUI,
|
||||
promise.GetPromise()));
|
||||
if (success != net::ERR_IO_PENDING)
|
||||
ResolveOrRejectPromiseInUI(promise.GetPromise(), success);
|
||||
} else if (action == Session::CacheAction::STATS) {
|
||||
base::StringPairs stats;
|
||||
(*backend_ptr)->GetStats(&stats);
|
||||
@@ -237,30 +243,35 @@ void OnGetBackend(disk_cache::Backend** backend_ptr,
|
||||
if (stat.first == "Current size") {
|
||||
int current_size;
|
||||
base::StringToInt(stat.second, ¤t_size);
|
||||
RunCallbackInUI(callback, current_size);
|
||||
util::Promise::ResolvePromise<int>(promise.GetPromise(),
|
||||
current_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RunCallbackInUI<int>(callback, net::ERR_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
void DoCacheActionInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
Session::CacheAction action,
|
||||
const net::CompletionCallback& callback) {
|
||||
util::Promise promise) {
|
||||
auto* request_context = context_getter->GetURLRequestContext();
|
||||
|
||||
auto* http_cache = request_context->http_transaction_factory()->GetCache();
|
||||
if (!http_cache)
|
||||
RunCallbackInUI<int>(callback, net::ERR_FAILED);
|
||||
if (!http_cache) {
|
||||
std::string err_msg =
|
||||
"Failed to retrieve cache: " + net::ErrorToString(net::ERR_FAILED);
|
||||
util::Promise::RejectPromise(std::move(promise), std::move(err_msg));
|
||||
return;
|
||||
}
|
||||
|
||||
// Call GetBackend and make the backend's ptr accessable in OnGetBackend.
|
||||
using BackendPtr = disk_cache::Backend*;
|
||||
auto** backend_ptr = new BackendPtr(nullptr);
|
||||
net::CompletionCallback on_get_backend =
|
||||
base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, callback);
|
||||
net::CompletionRepeatingCallback on_get_backend =
|
||||
base::Bind(&OnGetBackend, base::Owned(backend_ptr), action,
|
||||
util::CopyablePromise(promise));
|
||||
int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
|
||||
if (rv != net::ERR_IO_PENDING)
|
||||
on_get_backend.Run(net::OK);
|
||||
@@ -276,21 +287,22 @@ void SetCertVerifyProcInIO(
|
||||
|
||||
void ClearHostResolverCacheInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
const base::Closure& callback) {
|
||||
util::Promise promise) {
|
||||
auto* request_context = context_getter->GetURLRequestContext();
|
||||
auto* cache = request_context->host_resolver()->GetHostCache();
|
||||
if (cache) {
|
||||
cache->clear();
|
||||
DCHECK_EQ(0u, cache->size());
|
||||
if (!callback.is_null())
|
||||
RunCallbackInUI(callback);
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::UI},
|
||||
base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise)));
|
||||
}
|
||||
}
|
||||
|
||||
void ClearAuthCacheInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
const ClearAuthCacheOptions& options,
|
||||
const base::Closure& callback) {
|
||||
util::Promise promise) {
|
||||
auto* request_context = context_getter->GetURLRequestContext();
|
||||
auto* network_session =
|
||||
request_context->http_transaction_factory()->GetSession();
|
||||
@@ -310,8 +322,9 @@ void ClearAuthCacheInIO(
|
||||
}
|
||||
network_session->CloseAllConnections();
|
||||
}
|
||||
if (!callback.is_null())
|
||||
RunCallbackInUI(callback);
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::UI},
|
||||
base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise)));
|
||||
}
|
||||
|
||||
void AllowNTLMCredentialsForDomainsInIO(
|
||||
@@ -327,11 +340,6 @@ void AllowNTLMCredentialsForDomainsInIO(
|
||||
}
|
||||
}
|
||||
|
||||
void OnClearStorageDataDone(const base::Closure& callback) {
|
||||
if (!callback.is_null())
|
||||
callback.Run();
|
||||
}
|
||||
|
||||
void DownloadIdCallback(content::DownloadManager* download_manager,
|
||||
const base::FilePath& path,
|
||||
const std::vector<GURL>& url_chain,
|
||||
@@ -344,8 +352,8 @@ void DownloadIdCallback(content::DownloadManager* download_manager,
|
||||
uint32_t id) {
|
||||
download_manager->CreateDownloadItem(
|
||||
base::GenerateGUID(), id, path, path, url_chain, GURL(), GURL(), GURL(),
|
||||
GURL(), mime_type, mime_type, start_time, base::Time(), etag,
|
||||
last_modified, offset, length, std::string(),
|
||||
GURL(), base::nullopt, mime_type, mime_type, start_time, base::Time(),
|
||||
etag, last_modified, offset, length, std::string(),
|
||||
download::DownloadItem::INTERRUPTED,
|
||||
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
download::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, false, base::Time(),
|
||||
@@ -358,8 +366,9 @@ void DestroyGlobalHandle(v8::Isolate* isolate,
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
if (!global_handle.IsEmpty()) {
|
||||
v8::Local<v8::Value> local_handle = global_handle.Get(isolate);
|
||||
if (local_handle->IsObject()) {
|
||||
v8::Local<v8::Object> object = local_handle->ToObject();
|
||||
v8::Local<v8::Object> object;
|
||||
if (local_handle->IsObject() &&
|
||||
local_handle->ToObject(isolate->GetCurrentContext()).ToLocal(&object)) {
|
||||
void* ptr = object->GetAlignedPointerFromInternalField(0);
|
||||
if (!ptr)
|
||||
return;
|
||||
@@ -413,39 +422,59 @@ void Session::OnDownloadCreated(content::DownloadManager* manager,
|
||||
}
|
||||
}
|
||||
|
||||
void Session::ResolveProxy(
|
||||
const GURL& url,
|
||||
const ResolveProxyHelper::ResolveProxyCallback& callback) {
|
||||
browser_context_->GetResolveProxyHelper()->ResolveProxy(url, callback);
|
||||
v8::Local<v8::Promise> Session::ResolveProxy(mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
GURL url;
|
||||
args->GetNext(&url);
|
||||
|
||||
browser_context_->GetResolveProxyHelper()->ResolveProxy(
|
||||
url,
|
||||
base::Bind(util::CopyablePromise::ResolveCopyablePromise<std::string>,
|
||||
util::CopyablePromise(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
template <Session::CacheAction action>
|
||||
void Session::DoCacheAction(const net::CompletionCallback& callback) {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
v8::Local<v8::Promise> Session::DoCacheAction() {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&DoCacheActionInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
action, callback));
|
||||
action, std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Session::ClearStorageData(mate::Arguments* args) {
|
||||
// clearStorageData([options, callback])
|
||||
v8::Local<v8::Promise> Session::ClearStorageData(mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
ClearStorageDataOptions options;
|
||||
base::Closure callback;
|
||||
args->GetNext(&options);
|
||||
args->GetNext(&callback);
|
||||
|
||||
auto* storage_partition =
|
||||
content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
|
||||
if (options.storage_types & StoragePartition::REMOVE_DATA_MASK_COOKIES) {
|
||||
// Reset media device id salt when cookies are cleared.
|
||||
// https://w3c.github.io/mediacapture-main/#dom-mediadeviceinfo-deviceid
|
||||
brightray::MediaDeviceIDSalt::Reset(browser_context()->prefs());
|
||||
MediaDeviceIDSalt::Reset(browser_context()->prefs());
|
||||
}
|
||||
|
||||
storage_partition->ClearData(
|
||||
options.storage_types, options.quota_types, options.origin,
|
||||
content::StoragePartition::OriginMatcherFunction(), base::Time(),
|
||||
base::Time::Max(), base::Bind(&OnClearStorageDataDone, callback));
|
||||
options.storage_types, options.quota_types, options.origin, base::Time(),
|
||||
base::Time::Max(),
|
||||
base::Bind(util::CopyablePromise::ResolveEmptyCopyablePromise,
|
||||
util::CopyablePromise(promise)));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Session::FlushStorageData() {
|
||||
@@ -454,11 +483,17 @@ void Session::FlushStorageData() {
|
||||
storage_partition->Flush();
|
||||
}
|
||||
|
||||
void Session::SetProxy(const mate::Dictionary& options,
|
||||
const base::Closure& callback) {
|
||||
v8::Local<v8::Promise> Session::SetProxy(mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
mate::Dictionary options;
|
||||
args->GetNext(&options);
|
||||
|
||||
if (!browser_context_->in_memory_pref_store()) {
|
||||
callback.Run();
|
||||
return;
|
||||
promise.Resolve();
|
||||
return handle;
|
||||
}
|
||||
|
||||
std::string proxy_rules, bypass_list, pac_url;
|
||||
@@ -471,17 +506,22 @@ void Session::SetProxy(const mate::Dictionary& options,
|
||||
if (!pac_url.empty()) {
|
||||
browser_context_->in_memory_pref_store()->SetValue(
|
||||
proxy_config::prefs::kProxy,
|
||||
ProxyConfigDictionary::CreatePacScript(pac_url,
|
||||
true /* pac_mandatory */),
|
||||
std::make_unique<base::Value>(ProxyConfigDictionary::CreatePacScript(
|
||||
pac_url, true /* pac_mandatory */)),
|
||||
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
|
||||
} else {
|
||||
browser_context_->in_memory_pref_store()->SetValue(
|
||||
proxy_config::prefs::kProxy,
|
||||
ProxyConfigDictionary::CreateFixedServers(proxy_rules, bypass_list),
|
||||
std::make_unique<base::Value>(ProxyConfigDictionary::CreateFixedServers(
|
||||
proxy_rules, bypass_list)),
|
||||
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
|
||||
}
|
||||
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Session::SetDownloadPath(const base::FilePath& path) {
|
||||
@@ -532,8 +572,8 @@ void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
|
||||
return;
|
||||
}
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&SetCertVerifyProcInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
base::Bind(&WrapVerifyProc, proc)));
|
||||
@@ -541,14 +581,33 @@ void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
|
||||
|
||||
void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
AtomPermissionManager::RequestHandler handler;
|
||||
if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &handler))) {
|
||||
auto* permission_manager = static_cast<AtomPermissionManager*>(
|
||||
browser_context()->GetPermissionControllerDelegate());
|
||||
if (val->IsNull()) {
|
||||
permission_manager->SetPermissionRequestHandler(
|
||||
AtomPermissionManager::RequestHandler());
|
||||
return;
|
||||
}
|
||||
using StatusCallback =
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)>;
|
||||
using RequestHandler =
|
||||
base::Callback<void(content::WebContents*, content::PermissionType,
|
||||
StatusCallback, const base::Value&)>;
|
||||
auto handler = std::make_unique<RequestHandler>();
|
||||
if (!mate::ConvertFromV8(args->isolate(), val, handler.get())) {
|
||||
args->ThrowError("Must pass null or function");
|
||||
return;
|
||||
}
|
||||
auto* permission_manager = static_cast<AtomPermissionManager*>(
|
||||
browser_context()->GetPermissionControllerDelegate());
|
||||
permission_manager->SetPermissionRequestHandler(handler);
|
||||
permission_manager->SetPermissionRequestHandler(base::BindRepeating(
|
||||
[](RequestHandler* handler, content::WebContents* web_contents,
|
||||
content::PermissionType permission_type,
|
||||
AtomPermissionManager::StatusCallback callback,
|
||||
const base::Value& details) {
|
||||
handler->Run(web_contents, permission_type,
|
||||
base::AdaptCallbackForRepeating(std::move(callback)),
|
||||
details);
|
||||
},
|
||||
base::Owned(std::move(handler))));
|
||||
}
|
||||
|
||||
void Session::SetPermissionCheckHandler(v8::Local<v8::Value> val,
|
||||
@@ -563,36 +622,41 @@ void Session::SetPermissionCheckHandler(v8::Local<v8::Value> val,
|
||||
permission_manager->SetPermissionCheckHandler(handler);
|
||||
}
|
||||
|
||||
void Session::ClearHostResolverCache(mate::Arguments* args) {
|
||||
base::Closure callback;
|
||||
args->GetNext(&callback);
|
||||
v8::Local<v8::Promise> Session::ClearHostResolverCache(mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&ClearHostResolverCacheInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
callback));
|
||||
std::move(promise)));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Session::ClearAuthCache(mate::Arguments* args) {
|
||||
v8::Local<v8::Promise> Session::ClearAuthCache(mate::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
ClearAuthCacheOptions options;
|
||||
if (!args->GetNext(&options)) {
|
||||
args->ThrowError("Must specify options object");
|
||||
return;
|
||||
promise.RejectWithErrorMessage("Must specify options object");
|
||||
return handle;
|
||||
}
|
||||
base::Closure callback;
|
||||
args->GetNext(&callback);
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&ClearAuthCacheInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
options, callback));
|
||||
options, std::move(promise)));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Session::AllowNTLMCredentialsForDomains(const std::string& domains) {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&AllowNTLMCredentialsForDomainsInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
domains));
|
||||
@@ -616,16 +680,17 @@ std::string Session::GetUserAgent() {
|
||||
return browser_context_->GetUserAgent();
|
||||
}
|
||||
|
||||
void Session::GetBlobData(const std::string& uuid,
|
||||
const AtomBlobReader::CompletionCallback& callback) {
|
||||
if (callback.is_null())
|
||||
return;
|
||||
v8::Local<v8::Promise> Session::GetBlobData(v8::Isolate* isolate,
|
||||
const std::string& uuid) {
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
AtomBlobReader* blob_reader = browser_context()->GetBlobReader();
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&AtomBlobReader::StartReading,
|
||||
base::Unretained(blob_reader), uuid, callback));
|
||||
base::Unretained(blob_reader), uuid, std::move(promise)));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Session::CreateInterruptedDownload(const mate::Dictionary& options) {
|
||||
@@ -783,6 +848,9 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
namespace {
|
||||
|
||||
using atom::api::Cookies;
|
||||
using atom::api::NetLog;
|
||||
using atom::api::Protocol;
|
||||
using atom::api::Session;
|
||||
|
||||
v8::Local<v8::Value> FromPartition(const std::string& partition,
|
||||
@@ -802,11 +870,21 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("Session", Session::GetConstructor(isolate)->GetFunction());
|
||||
dict.Set("Cookies", Cookies::GetConstructor(isolate)->GetFunction());
|
||||
dict.Set(
|
||||
"Session",
|
||||
Session::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
dict.Set(
|
||||
"Cookies",
|
||||
Cookies::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
dict.Set(
|
||||
"NetLog",
|
||||
NetLog::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
dict.Set(
|
||||
"Protocol",
|
||||
Protocol::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
dict.SetMethod("fromPartition", &FromPartition);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_session, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_session, Initialize)
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/atom_blob_reader.h"
|
||||
#include "atom/browser/net/resolve_proxy_helper.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/base/completion_callback.h"
|
||||
|
||||
class GURL;
|
||||
|
||||
@@ -62,13 +62,12 @@ class Session : public mate::TrackableObject<Session>,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
// Methods.
|
||||
void ResolveProxy(const GURL& url,
|
||||
const ResolveProxyHelper::ResolveProxyCallback& callback);
|
||||
v8::Local<v8::Promise> ResolveProxy(mate::Arguments* args);
|
||||
template <CacheAction action>
|
||||
void DoCacheAction(const net::CompletionCallback& callback);
|
||||
void ClearStorageData(mate::Arguments* args);
|
||||
v8::Local<v8::Promise> DoCacheAction();
|
||||
v8::Local<v8::Promise> ClearStorageData(mate::Arguments* args);
|
||||
void FlushStorageData();
|
||||
void SetProxy(const mate::Dictionary& options, const base::Closure& callback);
|
||||
v8::Local<v8::Promise> SetProxy(mate::Arguments* args);
|
||||
void SetDownloadPath(const base::FilePath& path);
|
||||
void EnableNetworkEmulation(const mate::Dictionary& options);
|
||||
void DisableNetworkEmulation();
|
||||
@@ -77,13 +76,13 @@ class Session : public mate::TrackableObject<Session>,
|
||||
mate::Arguments* args);
|
||||
void SetPermissionCheckHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args);
|
||||
void ClearHostResolverCache(mate::Arguments* args);
|
||||
void ClearAuthCache(mate::Arguments* args);
|
||||
v8::Local<v8::Promise> ClearHostResolverCache(mate::Arguments* args);
|
||||
v8::Local<v8::Promise> ClearAuthCache(mate::Arguments* args);
|
||||
void AllowNTLMCredentialsForDomains(const std::string& domains);
|
||||
void SetUserAgent(const std::string& user_agent, mate::Arguments* args);
|
||||
std::string GetUserAgent();
|
||||
void GetBlobData(const std::string& uuid,
|
||||
const AtomBlobReader::CompletionCallback& callback);
|
||||
v8::Local<v8::Promise> GetBlobData(v8::Isolate* isolate,
|
||||
const std::string& uuid);
|
||||
void CreateInterruptedDownload(const mate::Dictionary& options);
|
||||
void SetPreloads(const std::vector<base::FilePath::StringType>& preloads);
|
||||
std::vector<base::FilePath::StringType> GetPreloads() const;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/animation/animation.h"
|
||||
#include "ui/gfx/color_utils.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -37,6 +38,25 @@ bool SystemPreferences::IsInvertedColorScheme() {
|
||||
return color_utils::IsInvertedColorScheme();
|
||||
}
|
||||
|
||||
#if !defined(OS_WIN)
|
||||
bool SystemPreferences::IsHighContrastColorScheme() {
|
||||
return false;
|
||||
}
|
||||
#endif // !defined(OS_WIN)
|
||||
|
||||
v8::Local<v8::Value> SystemPreferences::GetAnimationSettings(
|
||||
v8::Isolate* isolate) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("shouldRenderRichAnimation",
|
||||
gfx::Animation::ShouldRenderRichAnimation());
|
||||
dict.Set("scrollAnimationsEnabledBySystem",
|
||||
gfx::Animation::ScrollAnimationsEnabledBySystem());
|
||||
dict.Set("prefersReducedMotion", gfx::Animation::PrefersReducedMotion());
|
||||
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<SystemPreferences> SystemPreferences::Create(
|
||||
v8::Isolate* isolate) {
|
||||
@@ -49,10 +69,13 @@ void SystemPreferences::BuildPrototype(
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "SystemPreferences"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("getAccentColor", &SystemPreferences::GetAccentColor)
|
||||
.SetMethod("isAeroGlassEnabled", &SystemPreferences::IsAeroGlassEnabled)
|
||||
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||
.SetMethod("getColor", &SystemPreferences::GetColor)
|
||||
.SetMethod("getAccentColor", &SystemPreferences::GetAccentColor)
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("isAeroGlassEnabled", &SystemPreferences::IsAeroGlassEnabled)
|
||||
#elif defined(OS_MACOSX)
|
||||
.SetMethod("postNotification", &SystemPreferences::PostNotification)
|
||||
.SetMethod("subscribeNotification",
|
||||
@@ -83,10 +106,22 @@ void SystemPreferences::BuildPrototype(
|
||||
&SystemPreferences::GetAppLevelAppearance)
|
||||
.SetMethod("setAppLevelAppearance",
|
||||
&SystemPreferences::SetAppLevelAppearance)
|
||||
.SetMethod("getSystemColor", &SystemPreferences::GetSystemColor)
|
||||
.SetMethod("canPromptTouchID", &SystemPreferences::CanPromptTouchID)
|
||||
.SetMethod("promptTouchID", &SystemPreferences::PromptTouchID)
|
||||
.SetMethod("isTrustedAccessibilityClient",
|
||||
&SystemPreferences::IsTrustedAccessibilityClient)
|
||||
.SetMethod("getMediaAccessStatus",
|
||||
&SystemPreferences::GetMediaAccessStatus)
|
||||
.SetMethod("askForMediaAccess", &SystemPreferences::AskForMediaAccess)
|
||||
#endif
|
||||
.SetMethod("isInvertedColorScheme",
|
||||
&SystemPreferences::IsInvertedColorScheme)
|
||||
.SetMethod("isDarkMode", &SystemPreferences::IsDarkMode);
|
||||
.SetMethod("isHighContrastColorScheme",
|
||||
&SystemPreferences::IsHighContrastColorScheme)
|
||||
.SetMethod("isDarkMode", &SystemPreferences::IsDarkMode)
|
||||
.SetMethod("getAnimationSettings",
|
||||
&SystemPreferences::GetAnimationSettings);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
@@ -104,10 +139,11 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("systemPreferences", SystemPreferences::Create(isolate));
|
||||
dict.Set("SystemPreferences",
|
||||
SystemPreferences::GetConstructor(isolate)->GetFunction());
|
||||
dict.Set("SystemPreferences", SystemPreferences::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_system_preferences, Initialize);
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_system_preferences, Initialize)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/values.h"
|
||||
#include "native_mate/handle.h"
|
||||
@@ -48,11 +49,12 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool IsAeroGlassEnabled();
|
||||
|
||||
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||
std::string GetAccentColor();
|
||||
std::string GetColor(const std::string& color, mate::Arguments* args);
|
||||
#endif
|
||||
#if defined(OS_WIN)
|
||||
bool IsAeroGlassEnabled();
|
||||
|
||||
void InitializeWindow();
|
||||
|
||||
@@ -67,7 +69,8 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
||||
base::Callback<void(const std::string&, const base::DictionaryValue&)>;
|
||||
|
||||
void PostNotification(const std::string& name,
|
||||
const base::DictionaryValue& user_info);
|
||||
const base::DictionaryValue& user_info,
|
||||
mate::Arguments* args);
|
||||
int SubscribeNotification(const std::string& name,
|
||||
const NotificationCallback& callback);
|
||||
void UnsubscribeNotification(int id);
|
||||
@@ -90,6 +93,21 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
||||
void RemoveUserDefault(const std::string& name);
|
||||
bool IsSwipeTrackingFromScrollEventsEnabled();
|
||||
|
||||
std::string GetSystemColor(const std::string& color, mate::Arguments* args);
|
||||
|
||||
bool CanPromptTouchID();
|
||||
v8::Local<v8::Promise> PromptTouchID(v8::Isolate* isolate,
|
||||
const std::string& reason);
|
||||
|
||||
static bool IsTrustedAccessibilityClient(bool prompt);
|
||||
|
||||
// TODO(codebytere): Write tests for these methods once we
|
||||
// are running tests on a Mojave machine
|
||||
std::string GetMediaAccessStatus(const std::string& media_type,
|
||||
mate::Arguments* args);
|
||||
v8::Local<v8::Promise> AskForMediaAccess(v8::Isolate* isolate,
|
||||
const std::string& media_type);
|
||||
|
||||
// TODO(MarshallOfSound): Write tests for these methods once we
|
||||
// are running tests on a Mojave machine
|
||||
v8::Local<v8::Value> GetEffectiveAppearance(v8::Isolate* isolate);
|
||||
@@ -98,15 +116,14 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
||||
#endif
|
||||
bool IsDarkMode();
|
||||
bool IsInvertedColorScheme();
|
||||
bool IsHighContrastColorScheme();
|
||||
v8::Local<v8::Value> GetAnimationSettings(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
explicit SystemPreferences(v8::Isolate* isolate);
|
||||
~SystemPreferences() override;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void DoPostNotification(const std::string& name,
|
||||
const base::DictionaryValue& user_info,
|
||||
NotificationCenterKind kind);
|
||||
int DoSubscribeNotification(const std::string& name,
|
||||
const NotificationCallback& callback,
|
||||
NotificationCenterKind kind);
|
||||
@@ -139,6 +156,8 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
||||
|
||||
bool invertered_color_scheme_;
|
||||
|
||||
bool high_contrast_color_scheme_;
|
||||
|
||||
std::unique_ptr<gfx::ScopedSysColorChangeListener> color_change_listener_;
|
||||
#endif
|
||||
DISALLOW_COPY_AND_ASSIGN(SystemPreferences);
|
||||
|
||||
@@ -6,13 +6,22 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <LocalAuthentication/LocalAuthentication.h>
|
||||
#import <Security/Security.h>
|
||||
|
||||
#include "atom/browser/mac/atom_application.h"
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
#include "atom/browser/ui/cocoa/NSColor+Hex.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "base/mac/scoped_cftyperef.h"
|
||||
#include "base/mac/sdk_forward_declarations.h"
|
||||
#include "base/sequenced_task_runner.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/threading/sequenced_task_runner_handle.h"
|
||||
#include "base/values.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/base/mac/url_conversions.h"
|
||||
@@ -53,11 +62,11 @@ struct Converter<NSAppearance*> {
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
if (val.name == NSAppearanceNameAqua) {
|
||||
if ([val.name isEqualToString:NSAppearanceNameAqua]) {
|
||||
return mate::ConvertToV8(isolate, "light");
|
||||
}
|
||||
if (@available(macOS 10.14, *)) {
|
||||
if (val.name == NSAppearanceNameDarkAqua) {
|
||||
if ([val.name isEqualToString:NSAppearanceNameDarkAqua]) {
|
||||
return mate::ConvertToV8(isolate, "dark");
|
||||
}
|
||||
}
|
||||
@@ -78,12 +87,45 @@ int g_next_id = 0;
|
||||
// The map to convert |id| to |int|.
|
||||
std::map<int, id> g_id_map;
|
||||
|
||||
AVMediaType ParseMediaType(const std::string& media_type) {
|
||||
if (media_type == "camera") {
|
||||
return AVMediaTypeVideo;
|
||||
} else if (media_type == "microphone") {
|
||||
return AVMediaTypeAudio;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
std::string ConvertAuthorizationStatus(AVAuthorizationStatusMac status) {
|
||||
switch (status) {
|
||||
case AVAuthorizationStatusNotDeterminedMac:
|
||||
return "not-determined";
|
||||
case AVAuthorizationStatusRestrictedMac:
|
||||
return "restricted";
|
||||
case AVAuthorizationStatusDeniedMac:
|
||||
return "denied";
|
||||
case AVAuthorizationStatusAuthorizedMac:
|
||||
return "granted";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void SystemPreferences::PostNotification(
|
||||
const std::string& name,
|
||||
const base::DictionaryValue& user_info) {
|
||||
DoPostNotification(name, user_info, kNSDistributedNotificationCenter);
|
||||
void SystemPreferences::PostNotification(const std::string& name,
|
||||
const base::DictionaryValue& user_info,
|
||||
mate::Arguments* args) {
|
||||
bool immediate = false;
|
||||
args->GetNext(&immediate);
|
||||
|
||||
NSDistributedNotificationCenter* center =
|
||||
[NSDistributedNotificationCenter defaultCenter];
|
||||
[center postNotificationName:base::SysUTF8ToNSString(name)
|
||||
object:nil
|
||||
userInfo:DictionaryValueToNSDictionary(user_info)
|
||||
deliverImmediately:immediate];
|
||||
}
|
||||
|
||||
int SystemPreferences::SubscribeNotification(
|
||||
@@ -100,7 +142,10 @@ void SystemPreferences::UnsubscribeNotification(int request_id) {
|
||||
void SystemPreferences::PostLocalNotification(
|
||||
const std::string& name,
|
||||
const base::DictionaryValue& user_info) {
|
||||
DoPostNotification(name, user_info, kNSNotificationCenter);
|
||||
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
||||
[center postNotificationName:base::SysUTF8ToNSString(name)
|
||||
object:nil
|
||||
userInfo:DictionaryValueToNSDictionary(user_info)];
|
||||
}
|
||||
|
||||
int SystemPreferences::SubscribeLocalNotification(
|
||||
@@ -116,7 +161,11 @@ void SystemPreferences::UnsubscribeLocalNotification(int request_id) {
|
||||
void SystemPreferences::PostWorkspaceNotification(
|
||||
const std::string& name,
|
||||
const base::DictionaryValue& user_info) {
|
||||
DoPostNotification(name, user_info, kNSWorkspaceNotificationCenter);
|
||||
NSNotificationCenter* center =
|
||||
[[NSWorkspace sharedWorkspace] notificationCenter];
|
||||
[center postNotificationName:base::SysUTF8ToNSString(name)
|
||||
object:nil
|
||||
userInfo:DictionaryValueToNSDictionary(user_info)];
|
||||
}
|
||||
|
||||
int SystemPreferences::SubscribeWorkspaceNotification(
|
||||
@@ -130,29 +179,6 @@ void SystemPreferences::UnsubscribeWorkspaceNotification(int request_id) {
|
||||
DoUnsubscribeNotification(request_id, kNSWorkspaceNotificationCenter);
|
||||
}
|
||||
|
||||
void SystemPreferences::DoPostNotification(
|
||||
const std::string& name,
|
||||
const base::DictionaryValue& user_info,
|
||||
NotificationCenterKind kind) {
|
||||
NSNotificationCenter* center;
|
||||
switch (kind) {
|
||||
case kNSDistributedNotificationCenter:
|
||||
center = [NSDistributedNotificationCenter defaultCenter];
|
||||
break;
|
||||
case kNSNotificationCenter:
|
||||
center = [NSNotificationCenter defaultCenter];
|
||||
break;
|
||||
case kNSWorkspaceNotificationCenter:
|
||||
center = [[NSWorkspace sharedWorkspace] notificationCenter];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
[center postNotificationName:base::SysUTF8ToNSString(name)
|
||||
object:nil
|
||||
userInfo:DictionaryValueToNSDictionary(user_info)];
|
||||
}
|
||||
|
||||
int SystemPreferences::DoSubscribeNotification(
|
||||
const std::string& name,
|
||||
const NotificationCallback& callback,
|
||||
@@ -360,6 +386,239 @@ void SystemPreferences::SetUserDefault(const std::string& name,
|
||||
}
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetAccentColor() {
|
||||
NSColor* sysColor = nil;
|
||||
if (@available(macOS 10.14, *))
|
||||
sysColor = [NSColor controlAccentColor];
|
||||
|
||||
return base::SysNSStringToUTF8([sysColor RGBAValue]);
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetSystemColor(const std::string& color,
|
||||
mate::Arguments* args) {
|
||||
NSColor* sysColor = nil;
|
||||
if (color == "blue") {
|
||||
sysColor = [NSColor systemBlueColor];
|
||||
} else if (color == "brown") {
|
||||
sysColor = [NSColor systemBrownColor];
|
||||
} else if (color == "gray") {
|
||||
sysColor = [NSColor systemGrayColor];
|
||||
} else if (color == "green") {
|
||||
sysColor = [NSColor systemGreenColor];
|
||||
} else if (color == "orange") {
|
||||
sysColor = [NSColor systemOrangeColor];
|
||||
} else if (color == "pink") {
|
||||
sysColor = [NSColor systemPinkColor];
|
||||
} else if (color == "purple") {
|
||||
sysColor = [NSColor systemPurpleColor];
|
||||
} else if (color == "red") {
|
||||
sysColor = [NSColor systemRedColor];
|
||||
} else if (color == "yellow") {
|
||||
sysColor = [NSColor systemYellowColor];
|
||||
} else {
|
||||
args->ThrowError("Unknown system color: " + color);
|
||||
return "";
|
||||
}
|
||||
|
||||
return base::SysNSStringToUTF8([sysColor hexadecimalValue]);
|
||||
}
|
||||
|
||||
bool SystemPreferences::CanPromptTouchID() {
|
||||
if (@available(macOS 10.12.2, *)) {
|
||||
base::scoped_nsobject<LAContext> context([[LAContext alloc] init]);
|
||||
if (![context
|
||||
canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
|
||||
error:nil])
|
||||
return false;
|
||||
if (@available(macOS 10.13.2, *))
|
||||
return [context biometryType] == LABiometryTypeTouchID;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> SystemPreferences::PromptTouchID(
|
||||
v8::Isolate* isolate,
|
||||
const std::string& reason) {
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
if (@available(macOS 10.12.2, *)) {
|
||||
base::scoped_nsobject<LAContext> context([[LAContext alloc] init]);
|
||||
base::ScopedCFTypeRef<SecAccessControlRef> access_control =
|
||||
base::ScopedCFTypeRef<SecAccessControlRef>(
|
||||
SecAccessControlCreateWithFlags(
|
||||
kCFAllocatorDefault,
|
||||
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
|
||||
kSecAccessControlPrivateKeyUsage |
|
||||
kSecAccessControlUserPresence,
|
||||
nullptr));
|
||||
|
||||
scoped_refptr<base::SequencedTaskRunner> runner =
|
||||
base::SequencedTaskRunnerHandle::Get();
|
||||
|
||||
__block util::Promise p = std::move(promise);
|
||||
[context
|
||||
evaluateAccessControl:access_control
|
||||
operation:LAAccessControlOperationUseKeySign
|
||||
localizedReason:[NSString stringWithUTF8String:reason.c_str()]
|
||||
reply:^(BOOL success, NSError* error) {
|
||||
if (!success) {
|
||||
std::string err_msg = std::string(
|
||||
[error.localizedDescription UTF8String]);
|
||||
runner->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(util::Promise::RejectPromise,
|
||||
std::move(p),
|
||||
std::move(err_msg)));
|
||||
} else {
|
||||
runner->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(
|
||||
util::Promise::ResolveEmptyPromise,
|
||||
std::move(p)));
|
||||
}
|
||||
}];
|
||||
} else {
|
||||
promise.RejectWithErrorMessage(
|
||||
"This API is not available on macOS versions older than 10.12.2");
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
// static
|
||||
bool SystemPreferences::IsTrustedAccessibilityClient(bool prompt) {
|
||||
NSDictionary* options = @{(id)kAXTrustedCheckOptionPrompt : @(prompt)};
|
||||
return AXIsProcessTrustedWithOptions((CFDictionaryRef)options);
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetColor(const std::string& color,
|
||||
mate::Arguments* args) {
|
||||
NSColor* sysColor = nil;
|
||||
if (color == "alternate-selected-control-text") {
|
||||
sysColor = [NSColor alternateSelectedControlTextColor];
|
||||
} else if (color == "control-background") {
|
||||
sysColor = [NSColor controlBackgroundColor];
|
||||
} else if (color == "control") {
|
||||
sysColor = [NSColor controlColor];
|
||||
} else if (color == "control-text") {
|
||||
sysColor = [NSColor controlTextColor];
|
||||
} else if (color == "disabled-control") {
|
||||
sysColor = [NSColor disabledControlTextColor];
|
||||
} else if (color == "find-highlight") {
|
||||
if (@available(macOS 10.14, *))
|
||||
sysColor = [NSColor findHighlightColor];
|
||||
} else if (color == "grid") {
|
||||
sysColor = [NSColor gridColor];
|
||||
} else if (color == "header-text") {
|
||||
sysColor = [NSColor headerTextColor];
|
||||
} else if (color == "highlight") {
|
||||
sysColor = [NSColor highlightColor];
|
||||
} else if (color == "keyboard-focus-indicator") {
|
||||
sysColor = [NSColor keyboardFocusIndicatorColor];
|
||||
} else if (color == "label") {
|
||||
sysColor = [NSColor labelColor];
|
||||
} else if (color == "link") {
|
||||
sysColor = [NSColor linkColor];
|
||||
} else if (color == "placeholder-text") {
|
||||
sysColor = [NSColor placeholderTextColor];
|
||||
} else if (color == "quaternary-label") {
|
||||
sysColor = [NSColor quaternaryLabelColor];
|
||||
} else if (color == "scrubber-textured-background") {
|
||||
if (@available(macOS 10.12.2, *))
|
||||
sysColor = [NSColor scrubberTexturedBackgroundColor];
|
||||
} else if (color == "secondary-label") {
|
||||
sysColor = [NSColor secondaryLabelColor];
|
||||
} else if (color == "selected-content-background") {
|
||||
if (@available(macOS 10.14, *))
|
||||
sysColor = [NSColor selectedContentBackgroundColor];
|
||||
} else if (color == "selected-control") {
|
||||
sysColor = [NSColor selectedControlColor];
|
||||
} else if (color == "selected-control-text") {
|
||||
sysColor = [NSColor selectedControlTextColor];
|
||||
} else if (color == "selected-menu-item-text") {
|
||||
sysColor = [NSColor selectedMenuItemTextColor];
|
||||
} else if (color == "selected-text-background") {
|
||||
sysColor = [NSColor selectedTextBackgroundColor];
|
||||
} else if (color == "selected-text") {
|
||||
sysColor = [NSColor selectedTextColor];
|
||||
} else if (color == "separator") {
|
||||
if (@available(macOS 10.14, *))
|
||||
sysColor = [NSColor separatorColor];
|
||||
} else if (color == "shadow") {
|
||||
sysColor = [NSColor shadowColor];
|
||||
} else if (color == "tertiary-label") {
|
||||
sysColor = [NSColor tertiaryLabelColor];
|
||||
} else if (color == "text-background") {
|
||||
sysColor = [NSColor textBackgroundColor];
|
||||
} else if (color == "text") {
|
||||
sysColor = [NSColor textColor];
|
||||
} else if (color == "under-page-background") {
|
||||
sysColor = [NSColor underPageBackgroundColor];
|
||||
} else if (color == "unemphasized-selected-content-background") {
|
||||
if (@available(macOS 10.14, *))
|
||||
sysColor = [NSColor unemphasizedSelectedContentBackgroundColor];
|
||||
} else if (color == "unemphasized-selected-text-background") {
|
||||
if (@available(macOS 10.14, *))
|
||||
sysColor = [NSColor unemphasizedSelectedTextBackgroundColor];
|
||||
} else if (color == "unemphasized-selected-text") {
|
||||
if (@available(macOS 10.14, *))
|
||||
sysColor = [NSColor unemphasizedSelectedTextColor];
|
||||
} else if (color == "window-background") {
|
||||
sysColor = [NSColor windowBackgroundColor];
|
||||
} else if (color == "window-frame-text") {
|
||||
sysColor = [NSColor windowFrameTextColor];
|
||||
} else {
|
||||
args->ThrowError("Unknown color: " + color);
|
||||
return "";
|
||||
}
|
||||
|
||||
return base::SysNSStringToUTF8([sysColor hexadecimalValue]);
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetMediaAccessStatus(
|
||||
const std::string& media_type,
|
||||
mate::Arguments* args) {
|
||||
if (auto type = ParseMediaType(media_type)) {
|
||||
if (@available(macOS 10.14, *)) {
|
||||
return ConvertAuthorizationStatus(
|
||||
[AVCaptureDevice authorizationStatusForMediaType:type]);
|
||||
} else {
|
||||
// access always allowed pre-10.14 Mojave
|
||||
return ConvertAuthorizationStatus(AVAuthorizationStatusAuthorizedMac);
|
||||
}
|
||||
} else {
|
||||
args->ThrowError("Invalid media type");
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> SystemPreferences::AskForMediaAccess(
|
||||
v8::Isolate* isolate,
|
||||
const std::string& media_type) {
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
if (auto type = ParseMediaType(media_type)) {
|
||||
if (@available(macOS 10.14, *)) {
|
||||
__block util::Promise p = std::move(promise);
|
||||
[AVCaptureDevice requestAccessForMediaType:type
|
||||
completionHandler:^(BOOL granted) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
p.Resolve(!!granted);
|
||||
});
|
||||
}];
|
||||
} else {
|
||||
// access always allowed pre-10.14 Mojave
|
||||
promise.Resolve(true);
|
||||
}
|
||||
} else {
|
||||
promise.RejectWithErrorMessage("Invalid media type");
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void SystemPreferences::RemoveUserDefault(const std::string& name) {
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults removeObjectForKey:base::SysUTF8ToNSString(name)];
|
||||
|
||||
@@ -20,6 +20,18 @@ namespace {
|
||||
const wchar_t kSystemPreferencesWindowClass[] =
|
||||
L"Electron_SystemPreferencesHostWindow";
|
||||
|
||||
bool g_is_high_contract_color_scheme = false;
|
||||
bool g_is_high_contract_color_scheme_initialized = false;
|
||||
|
||||
void UpdateHighContrastColorScheme() {
|
||||
HIGHCONTRAST high_contrast = {0};
|
||||
high_contrast.cbSize = sizeof(HIGHCONTRAST);
|
||||
g_is_high_contract_color_scheme =
|
||||
SystemParametersInfo(SPI_GETHIGHCONTRAST, 0, &high_contrast, 0) &&
|
||||
((high_contrast.dwFlags & HCF_HIGHCONTRASTON) != 0);
|
||||
g_is_high_contract_color_scheme_initialized = true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace api {
|
||||
@@ -28,6 +40,12 @@ bool SystemPreferences::IsAeroGlassEnabled() {
|
||||
return ui::win::IsAeroGlassEnabled();
|
||||
}
|
||||
|
||||
bool SystemPreferences::IsHighContrastColorScheme() {
|
||||
if (!g_is_high_contract_color_scheme_initialized)
|
||||
UpdateHighContrastColorScheme();
|
||||
return g_is_high_contract_color_scheme;
|
||||
}
|
||||
|
||||
std::string hexColorDWORDToRGBA(DWORD color) {
|
||||
DWORD rgba = color << 8 | color >> 24;
|
||||
std::ostringstream stream;
|
||||
@@ -119,6 +137,7 @@ std::string SystemPreferences::GetColor(const std::string& color,
|
||||
|
||||
void SystemPreferences::InitializeWindow() {
|
||||
invertered_color_scheme_ = IsInvertedColorScheme();
|
||||
high_contrast_color_scheme_ = IsHighContrastColorScheme();
|
||||
|
||||
// Wait until app is ready before creating sys color listener
|
||||
// Creating this listener before the app is ready causes global shortcuts
|
||||
@@ -169,6 +188,9 @@ LRESULT CALLBACK SystemPreferences::WndProc(HWND hwnd,
|
||||
Emit("accent-color-changed", hexColorDWORDToRGBA(new_color));
|
||||
current_color_ = new_color_string;
|
||||
}
|
||||
} else if (message == WM_SYSCOLORCHANGE ||
|
||||
(message == WM_SETTINGCHANGE && wparam == SPI_SETHIGHCONTRAST)) {
|
||||
UpdateHighContrastColorScheme();
|
||||
}
|
||||
return ::DefWindowProc(hwnd, message, wparam, lparam);
|
||||
}
|
||||
@@ -179,6 +201,13 @@ void SystemPreferences::OnSysColorChange() {
|
||||
invertered_color_scheme_ = new_invertered_color_scheme;
|
||||
Emit("inverted-color-scheme-changed", new_invertered_color_scheme);
|
||||
}
|
||||
|
||||
bool new_high_contrast_color_scheme = IsHighContrastColorScheme();
|
||||
if (new_high_contrast_color_scheme != high_contrast_color_scheme_) {
|
||||
high_contrast_color_scheme_ = new_high_contrast_color_scheme;
|
||||
Emit("high-contrast-color-scheme-changed", new_high_contrast_color_scheme);
|
||||
}
|
||||
|
||||
Emit("color-changed");
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "gin/converter.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "native_mate/persistent_dictionary.h"
|
||||
|
||||
@@ -32,8 +34,6 @@
|
||||
#include "ui/base/win/shell.h"
|
||||
#endif
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
namespace mate {
|
||||
|
||||
@@ -158,7 +158,7 @@ void TopLevelWindow::OnWindowClosed() {
|
||||
Emit("closed");
|
||||
|
||||
RemoveFromParentChildWindows();
|
||||
ResetBrowserView();
|
||||
TopLevelWindow::ResetBrowserViews();
|
||||
|
||||
// Destroy the native class when window is closed.
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, GetDestroyClosure());
|
||||
@@ -266,7 +266,7 @@ void TopLevelWindow::OnWindowAlwaysOnTopChanged() {
|
||||
Emit("always-on-top-changed", IsAlwaysOnTop());
|
||||
}
|
||||
|
||||
void TopLevelWindow::OnExecuteWindowsCommand(const std::string& command_name) {
|
||||
void TopLevelWindow::OnExecuteAppCommand(const std::string& command_name) {
|
||||
Emit("app-command", command_name);
|
||||
}
|
||||
|
||||
@@ -293,6 +293,7 @@ void TopLevelWindow::OnWindowMessage(UINT message,
|
||||
#endif
|
||||
|
||||
void TopLevelWindow::SetContentView(mate::Handle<View> view) {
|
||||
ResetBrowserViews();
|
||||
content_view_.Reset(isolate(), view.ToV8());
|
||||
window_->SetContentView(view->view());
|
||||
}
|
||||
@@ -546,11 +547,9 @@ std::vector<int> TopLevelWindow::GetPosition() {
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||
void TopLevelWindow::MoveTop() {
|
||||
window_->MoveTop();
|
||||
}
|
||||
#endif
|
||||
|
||||
void TopLevelWindow::SetTitle(const std::string& title) {
|
||||
window_->SetTitle(title);
|
||||
@@ -568,6 +567,14 @@ void TopLevelWindow::SetSkipTaskbar(bool skip) {
|
||||
window_->SetSkipTaskbar(skip);
|
||||
}
|
||||
|
||||
void TopLevelWindow::SetExcludedFromShownWindowsMenu(bool excluded) {
|
||||
window_->SetExcludedFromShownWindowsMenu(excluded);
|
||||
}
|
||||
|
||||
bool TopLevelWindow::IsExcludedFromShownWindowsMenu() {
|
||||
return window_->IsExcludedFromShownWindowsMenu();
|
||||
}
|
||||
|
||||
void TopLevelWindow::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||
window_->SetSimpleFullScreen(simple_fullscreen);
|
||||
}
|
||||
@@ -641,9 +648,11 @@ void TopLevelWindow::SetFocusable(bool focusable) {
|
||||
}
|
||||
|
||||
void TopLevelWindow::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
|
||||
auto context = isolate->GetCurrentContext();
|
||||
mate::Handle<Menu> menu;
|
||||
if (value->IsObject() &&
|
||||
mate::V8ToString(value->ToObject()->GetConstructorName()) == "Menu" &&
|
||||
v8::Local<v8::Object> object;
|
||||
if (value->IsObject() && value->ToObject(context).ToLocal(&object) &&
|
||||
gin::V8ToString(isolate, object->GetConstructorName()) == "Menu" &&
|
||||
mate::ConvertFromV8(isolate, value, &menu) && !menu.IsEmpty()) {
|
||||
menu_.Reset(isolate, menu.ToV8());
|
||||
window_->SetMenu(menu->model());
|
||||
@@ -656,6 +665,11 @@ void TopLevelWindow::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
|
||||
}
|
||||
}
|
||||
|
||||
void TopLevelWindow::RemoveMenu() {
|
||||
menu_.Reset();
|
||||
window_->SetMenu(nullptr);
|
||||
}
|
||||
|
||||
void TopLevelWindow::SetParentWindow(v8::Local<v8::Value> value,
|
||||
mate::Arguments* args) {
|
||||
if (IsModal()) {
|
||||
@@ -669,6 +683,7 @@ void TopLevelWindow::SetParentWindow(v8::Local<v8::Value> value,
|
||||
parent_window_.Reset();
|
||||
window_->SetParentWindow(nullptr);
|
||||
} else if (mate::ConvertFromV8(isolate(), value, &parent)) {
|
||||
RemoveFromParentChildWindows();
|
||||
parent_window_.Reset(isolate(), value);
|
||||
window_->SetParentWindow(parent->window_.get());
|
||||
parent->child_windows_.Set(isolate(), weak_map_id(), GetWrapper());
|
||||
@@ -678,21 +693,43 @@ void TopLevelWindow::SetParentWindow(v8::Local<v8::Value> value,
|
||||
}
|
||||
|
||||
void TopLevelWindow::SetBrowserView(v8::Local<v8::Value> value) {
|
||||
ResetBrowserView();
|
||||
ResetBrowserViews();
|
||||
AddBrowserView(value);
|
||||
}
|
||||
|
||||
void TopLevelWindow::AddBrowserView(v8::Local<v8::Value> value) {
|
||||
mate::Handle<BrowserView> browser_view;
|
||||
if (value->IsNull() || value->IsUndefined()) {
|
||||
window_->SetBrowserView(nullptr);
|
||||
} else if (mate::ConvertFromV8(isolate(), value, &browser_view)) {
|
||||
window_->SetBrowserView(browser_view->view());
|
||||
browser_view->web_contents()->SetOwnerWindow(window_.get());
|
||||
browser_view_.Reset(isolate(), value);
|
||||
if (value->IsObject() &&
|
||||
mate::ConvertFromV8(isolate(), value, &browser_view)) {
|
||||
auto get_that_view = browser_views_.find(browser_view->weak_map_id());
|
||||
if (get_that_view == browser_views_.end()) {
|
||||
window_->AddBrowserView(browser_view->view());
|
||||
browser_view->web_contents()->SetOwnerWindow(window_.get());
|
||||
browser_views_[browser_view->weak_map_id()].Reset(isolate(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TopLevelWindow::RemoveBrowserView(v8::Local<v8::Value> value) {
|
||||
mate::Handle<BrowserView> browser_view;
|
||||
if (value->IsObject() &&
|
||||
mate::ConvertFromV8(isolate(), value, &browser_view)) {
|
||||
auto get_that_view = browser_views_.find(browser_view->weak_map_id());
|
||||
if (get_that_view != browser_views_.end()) {
|
||||
window_->RemoveBrowserView(browser_view->view());
|
||||
browser_view->web_contents()->SetOwnerWindow(nullptr);
|
||||
|
||||
(*get_that_view).second.Reset(isolate(), value);
|
||||
browser_views_.erase(get_that_view);
|
||||
}
|
||||
}
|
||||
}
|
||||
v8::Local<v8::Value> TopLevelWindow::GetNativeWindowHandle() {
|
||||
gfx::AcceleratedWidget handle = window_->GetAcceleratedWidget();
|
||||
return ToBuffer(isolate(), static_cast<void*>(&handle), sizeof(handle));
|
||||
// TODO(MarshallOfSound): Replace once
|
||||
// https://chromium-review.googlesource.com/c/chromium/src/+/1253094/ has
|
||||
// landed
|
||||
NativeWindowHandle handle = window_->GetNativeWindowHandle();
|
||||
return ToBuffer(isolate(), &handle, sizeof(handle));
|
||||
}
|
||||
|
||||
void TopLevelWindow::SetProgressBar(double progress, mate::Arguments* args) {
|
||||
@@ -737,7 +774,7 @@ void TopLevelWindow::SetAutoHideCursor(bool auto_hide) {
|
||||
|
||||
void TopLevelWindow::SetVibrancy(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> value) {
|
||||
std::string type = mate::V8ToString(value);
|
||||
std::string type = gin::V8ToString(isolate, value);
|
||||
window_->SetVibrancy(type);
|
||||
}
|
||||
|
||||
@@ -841,12 +878,29 @@ std::vector<v8::Local<v8::Object>> TopLevelWindow::GetChildWindows() const {
|
||||
return child_windows_.Values(isolate());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> TopLevelWindow::GetBrowserView() const {
|
||||
if (browser_view_.IsEmpty()) {
|
||||
v8::Local<v8::Value> TopLevelWindow::GetBrowserView(
|
||||
mate::Arguments* args) const {
|
||||
if (browser_views_.size() == 0) {
|
||||
return v8::Null(isolate());
|
||||
} else if (browser_views_.size() == 1) {
|
||||
auto first_view = browser_views_.begin();
|
||||
return v8::Local<v8::Value>::New(isolate(), (*first_view).second);
|
||||
} else {
|
||||
args->ThrowError(
|
||||
"BrowserWindow have multiple BrowserViews, "
|
||||
"Use getBrowserViews() instead");
|
||||
return v8::Null(isolate());
|
||||
}
|
||||
}
|
||||
|
||||
return v8::Local<v8::Value>::New(isolate(), browser_view_);
|
||||
std::vector<v8::Local<v8::Value>> TopLevelWindow::GetBrowserViews() const {
|
||||
std::vector<v8::Local<v8::Value>> ret;
|
||||
|
||||
for (auto const& views_iter : browser_views_) {
|
||||
ret.push_back(v8::Local<v8::Value>::New(isolate(), views_iter.second));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool TopLevelWindow::IsModal() const {
|
||||
@@ -938,17 +992,21 @@ int32_t TopLevelWindow::GetID() const {
|
||||
return weak_map_id();
|
||||
}
|
||||
|
||||
void TopLevelWindow::ResetBrowserView() {
|
||||
if (browser_view_.IsEmpty())
|
||||
return;
|
||||
void TopLevelWindow::ResetBrowserViews() {
|
||||
for (auto& item : browser_views_) {
|
||||
mate::Handle<BrowserView> browser_view;
|
||||
if (mate::ConvertFromV8(isolate(),
|
||||
v8::Local<v8::Value>::New(isolate(), item.second),
|
||||
&browser_view) &&
|
||||
!browser_view.IsEmpty()) {
|
||||
window_->RemoveBrowserView(browser_view->view());
|
||||
browser_view->web_contents()->SetOwnerWindow(nullptr);
|
||||
}
|
||||
|
||||
mate::Handle<BrowserView> browser_view;
|
||||
if (mate::ConvertFromV8(isolate(), GetBrowserView(), &browser_view) &&
|
||||
!browser_view.IsEmpty()) {
|
||||
browser_view->web_contents()->SetOwnerWindow(nullptr);
|
||||
item.second.Reset();
|
||||
}
|
||||
|
||||
browser_view_.Reset();
|
||||
browser_views_.clear();
|
||||
}
|
||||
|
||||
void TopLevelWindow::RemoveFromParentChildWindows() {
|
||||
@@ -1015,9 +1073,7 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setResizable", &TopLevelWindow::SetResizable)
|
||||
.SetMethod("isResizable", &TopLevelWindow::IsResizable)
|
||||
.SetMethod("setMovable", &TopLevelWindow::SetMovable)
|
||||
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||
.SetMethod("moveTop", &TopLevelWindow::MoveTop)
|
||||
#endif
|
||||
.SetMethod("isMovable", &TopLevelWindow::IsMovable)
|
||||
.SetMethod("setMinimizable", &TopLevelWindow::SetMinimizable)
|
||||
.SetMethod("isMinimizable", &TopLevelWindow::IsMinimizable)
|
||||
@@ -1056,10 +1112,11 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setContentProtection", &TopLevelWindow::SetContentProtection)
|
||||
.SetMethod("setFocusable", &TopLevelWindow::SetFocusable)
|
||||
.SetMethod("setMenu", &TopLevelWindow::SetMenu)
|
||||
#if !defined(OS_WIN)
|
||||
.SetMethod("removeMenu", &TopLevelWindow::RemoveMenu)
|
||||
.SetMethod("setParentWindow", &TopLevelWindow::SetParentWindow)
|
||||
#endif
|
||||
.SetMethod("setBrowserView", &TopLevelWindow::SetBrowserView)
|
||||
.SetMethod("addBrowserView", &TopLevelWindow::AddBrowserView)
|
||||
.SetMethod("removeBrowserView", &TopLevelWindow::RemoveBrowserView)
|
||||
.SetMethod("getNativeWindowHandle",
|
||||
&TopLevelWindow::GetNativeWindowHandle)
|
||||
.SetMethod("setProgressBar", &TopLevelWindow::SetProgressBar)
|
||||
@@ -1085,6 +1142,9 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("addTabbedWindow", &TopLevelWindow::AddTabbedWindow)
|
||||
.SetMethod("setWindowButtonVisibility",
|
||||
&TopLevelWindow::SetWindowButtonVisibility)
|
||||
.SetProperty("excludedFromShownWindowsMenu",
|
||||
&TopLevelWindow::IsExcludedFromShownWindowsMenu,
|
||||
&TopLevelWindow::SetExcludedFromShownWindowsMenu)
|
||||
#endif
|
||||
.SetMethod("setAutoHideMenuBar", &TopLevelWindow::SetAutoHideMenuBar)
|
||||
.SetMethod("isMenuBarAutoHide", &TopLevelWindow::IsMenuBarAutoHide)
|
||||
@@ -1097,6 +1157,7 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getParentWindow", &TopLevelWindow::GetParentWindow)
|
||||
.SetMethod("getChildWindows", &TopLevelWindow::GetChildWindows)
|
||||
.SetMethod("getBrowserView", &TopLevelWindow::GetBrowserView)
|
||||
.SetMethod("getBrowserViews", &TopLevelWindow::GetBrowserViews)
|
||||
.SetMethod("isModal", &TopLevelWindow::IsModal)
|
||||
.SetMethod("setThumbarButtons", &TopLevelWindow::SetThumbarButtons)
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
@@ -1131,8 +1192,9 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
TopLevelWindow::SetConstructor(isolate, base::Bind(&TopLevelWindow::New));
|
||||
|
||||
mate::Dictionary constructor(
|
||||
isolate, TopLevelWindow::GetConstructor(isolate)->GetFunction());
|
||||
mate::Dictionary constructor(isolate, TopLevelWindow::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
constructor.SetMethod("fromId",
|
||||
&mate::TrackableObject<TopLevelWindow>::FromWeakMapID);
|
||||
constructor.SetMethod("getAllWindows",
|
||||
@@ -1144,4 +1206,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_top_level_window, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_top_level_window, Initialize)
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/native_window_observer.h"
|
||||
#include "atom/common/api/atom_api_native_image.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
@@ -78,7 +80,7 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
|
||||
void OnWindowEnterHtmlFullScreen() override;
|
||||
void OnWindowLeaveHtmlFullScreen() override;
|
||||
void OnWindowAlwaysOnTopChanged() override;
|
||||
void OnExecuteWindowsCommand(const std::string& command_name) override;
|
||||
void OnExecuteAppCommand(const std::string& command_name) override;
|
||||
void OnTouchBarItemResult(const std::string& item_id,
|
||||
const base::DictionaryValue& details) override;
|
||||
void OnNewWindowForTab() override;
|
||||
@@ -124,9 +126,7 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
|
||||
void SetResizable(bool resizable);
|
||||
bool IsResizable();
|
||||
void SetMovable(bool movable);
|
||||
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||
void MoveTop();
|
||||
#endif
|
||||
bool IsMovable();
|
||||
void SetMinimizable(bool minimizable);
|
||||
bool IsMinimizable();
|
||||
@@ -145,6 +145,8 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
|
||||
std::string GetTitle();
|
||||
void FlashFrame(bool flash);
|
||||
void SetSkipTaskbar(bool skip);
|
||||
void SetExcludedFromShownWindowsMenu(bool excluded);
|
||||
bool IsExcludedFromShownWindowsMenu();
|
||||
void SetSimpleFullScreen(bool simple_fullscreen);
|
||||
bool IsSimpleFullScreen();
|
||||
void SetKiosk(bool kiosk);
|
||||
@@ -163,8 +165,13 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
|
||||
void SetContentProtection(bool enable);
|
||||
void SetFocusable(bool focusable);
|
||||
void SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> menu);
|
||||
void RemoveMenu();
|
||||
void SetParentWindow(v8::Local<v8::Value> value, mate::Arguments* args);
|
||||
virtual void SetBrowserView(v8::Local<v8::Value> value);
|
||||
virtual void AddBrowserView(v8::Local<v8::Value> value);
|
||||
virtual void RemoveBrowserView(v8::Local<v8::Value> value);
|
||||
virtual std::vector<v8::Local<v8::Value>> GetBrowserViews() const;
|
||||
virtual void ResetBrowserViews();
|
||||
v8::Local<v8::Value> GetNativeWindowHandle();
|
||||
void SetProgressBar(double progress, mate::Arguments* args);
|
||||
void SetOverlayIcon(const gfx::Image& overlay,
|
||||
@@ -195,7 +202,7 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
|
||||
v8::Local<v8::Value> GetContentView() const;
|
||||
v8::Local<v8::Value> GetParentWindow() const;
|
||||
std::vector<v8::Local<v8::Object>> GetChildWindows() const;
|
||||
v8::Local<v8::Value> GetBrowserView() const;
|
||||
v8::Local<v8::Value> GetBrowserView(mate::Arguments* args) const;
|
||||
bool IsModal() const;
|
||||
|
||||
// Extra APIs added in JS.
|
||||
@@ -226,8 +233,8 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
|
||||
|
||||
template <typename... Args>
|
||||
void EmitEventSoon(base::StringPiece eventName) {
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::UI, FROM_HERE,
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(base::IgnoreResult(&TopLevelWindow::Emit<Args...>),
|
||||
weak_factory_.GetWeakPtr(), eventName));
|
||||
}
|
||||
@@ -238,7 +245,7 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
|
||||
#endif
|
||||
|
||||
v8::Global<v8::Value> content_view_;
|
||||
v8::Global<v8::Value> browser_view_;
|
||||
std::map<int32_t, v8::Global<v8::Value>> browser_views_;
|
||||
v8::Global<v8::Value> menu_;
|
||||
v8::Global<v8::Value> parent_window_;
|
||||
KeyWeakMap<int> child_windows_;
|
||||
|
||||
@@ -59,11 +59,7 @@ Tray::Tray(v8::Isolate* isolate,
|
||||
InitWith(isolate, wrapper);
|
||||
}
|
||||
|
||||
Tray::~Tray() {
|
||||
// Destroy the native tray in next tick.
|
||||
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
|
||||
tray_icon_.release());
|
||||
}
|
||||
Tray::~Tray() = default;
|
||||
|
||||
// static
|
||||
mate::WrappableBase* Tray::New(mate::Handle<NativeImage> image,
|
||||
@@ -159,7 +155,17 @@ void Tray::SetToolTip(const std::string& tool_tip) {
|
||||
}
|
||||
|
||||
void Tray::SetTitle(const std::string& title) {
|
||||
#if defined(OS_MACOSX)
|
||||
tray_icon_->SetTitle(title);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string Tray::GetTitle() {
|
||||
#if defined(OS_MACOSX)
|
||||
return tray_icon_->GetTitle();
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
void Tray::SetHighlightMode(TrayIcon::HighlightMode mode) {
|
||||
@@ -227,6 +233,7 @@ void Tray::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setPressedImage", &Tray::SetPressedImage)
|
||||
.SetMethod("setToolTip", &Tray::SetToolTip)
|
||||
.SetMethod("setTitle", &Tray::SetTitle)
|
||||
.SetMethod("getTitle", &Tray::GetTitle)
|
||||
.SetMethod("setHighlightMode", &Tray::SetHighlightMode)
|
||||
.SetMethod("setIgnoreDoubleClickEvents",
|
||||
&Tray::SetIgnoreDoubleClickEvents)
|
||||
@@ -254,9 +261,11 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
Tray::SetConstructor(isolate, base::Bind(&Tray::New));
|
||||
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("Tray", Tray::GetConstructor(isolate)->GetFunction());
|
||||
dict.Set(
|
||||
"Tray",
|
||||
Tray::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_tray, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_tray, Initialize)
|
||||
|
||||
@@ -69,6 +69,7 @@ class Tray : public mate::TrackableObject<Tray>, public TrayIconObserver {
|
||||
void SetPressedImage(v8::Isolate* isolate, mate::Handle<NativeImage> image);
|
||||
void SetToolTip(const std::string& tool_tip);
|
||||
void SetTitle(const std::string& title);
|
||||
std::string GetTitle();
|
||||
void SetHighlightMode(TrayIcon::HighlightMode mode);
|
||||
void SetIgnoreDoubleClickEvents(bool ignore);
|
||||
bool GetIgnoreDoubleClickEvents();
|
||||
|
||||
@@ -354,7 +354,7 @@ void URLRequest::OnReceivedRedirect(
|
||||
}
|
||||
|
||||
void URLRequest::OnAuthenticationRequired(
|
||||
scoped_refptr<const net::AuthChallengeInfo> auth_info) {
|
||||
const net::AuthChallengeInfo& auth_info) {
|
||||
if (request_state_.Canceled() || request_state_.Closed()) {
|
||||
return;
|
||||
}
|
||||
@@ -364,7 +364,7 @@ void URLRequest::OnAuthenticationRequired(
|
||||
return;
|
||||
}
|
||||
|
||||
Emit("login", auth_info.get(),
|
||||
Emit("login", auth_info,
|
||||
base::Bind(&AtomURLRequest::PassLoginInformation, atom_request_));
|
||||
}
|
||||
|
||||
|
||||
@@ -105,8 +105,7 @@ class URLRequest : public mate::EventEmitter<URLRequest> {
|
||||
const std::string& method,
|
||||
const GURL& url,
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers);
|
||||
void OnAuthenticationRequired(
|
||||
scoped_refptr<const net::AuthChallengeInfo> auth_info);
|
||||
void OnAuthenticationRequired(const net::AuthChallengeInfo& auth_info);
|
||||
void OnResponseStarted(
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers);
|
||||
void OnResponseData(scoped_refptr<const net::IOBufferWithSize> data);
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
|
||||
#include "atom/browser/api/atom_api_view.h"
|
||||
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -76,8 +75,9 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
View::SetConstructor(isolate, base::Bind(&View::New));
|
||||
|
||||
mate::Dictionary constructor(isolate,
|
||||
View::GetConstructor(isolate)->GetFunction());
|
||||
mate::Dictionary constructor(
|
||||
isolate,
|
||||
View::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("View", constructor);
|
||||
@@ -85,4 +85,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_view, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_view, Initialize)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,7 @@
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_WEB_CONTENTS_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_WEB_CONTENTS_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -15,24 +16,29 @@
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
#include "atom/browser/ui/autofill_popup.h"
|
||||
#include "base/observer_list.h"
|
||||
#include "base/observer_list_types.h"
|
||||
#include "content/common/cursors/webcursor.h"
|
||||
#include "content/public/browser/keyboard_event_processing_result.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/browser/web_contents_binding_set.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "content/public/common/favicon_url.h"
|
||||
#include "electron/atom/common/api/api.mojom.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "printing/backend/print_backend.h"
|
||||
#include "printing/buildflags/buildflags.h"
|
||||
#include "services/service_manager/public/cpp/binder_registry.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
#include "atom/browser/printing/print_preview_message_handler.h"
|
||||
#include "printing/backend/print_backend.h"
|
||||
#endif
|
||||
|
||||
namespace blink {
|
||||
struct WebDeviceEmulationParams;
|
||||
}
|
||||
|
||||
namespace brightray {
|
||||
class InspectableWebContents;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
class Dictionary;
|
||||
@@ -46,12 +52,12 @@ namespace atom {
|
||||
|
||||
class AtomBrowserContext;
|
||||
class AtomJavaScriptDialogManager;
|
||||
class InspectableWebContents;
|
||||
class WebContentsZoomController;
|
||||
class WebViewGuestDelegate;
|
||||
class FrameSubscriber;
|
||||
|
||||
#if BUILDFLAG(ENABLE_OSR)
|
||||
class OffScreenWebContentsView;
|
||||
class OffScreenRenderWidgetHostView;
|
||||
#endif
|
||||
|
||||
@@ -59,16 +65,20 @@ namespace api {
|
||||
|
||||
// Certain events are only in WebContentsDelegate, provide our own Observer to
|
||||
// dispatch those events.
|
||||
class ExtendedWebContentsObserver {
|
||||
class ExtendedWebContentsObserver : public base::CheckedObserver {
|
||||
public:
|
||||
virtual void OnCloseContents() {}
|
||||
virtual void OnRendererResponsive() {}
|
||||
|
||||
protected:
|
||||
~ExtendedWebContentsObserver() override {}
|
||||
};
|
||||
|
||||
// Wrapper around the content::WebContents.
|
||||
class WebContents : public mate::TrackableObject<WebContents>,
|
||||
public CommonWebContentsDelegate,
|
||||
public content::WebContentsObserver {
|
||||
public content::WebContentsObserver,
|
||||
public mojom::ElectronBrowser {
|
||||
public:
|
||||
enum Type {
|
||||
BACKGROUND_PAGE, // A DevTools extension background page.
|
||||
@@ -79,29 +89,51 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
OFF_SCREEN, // Used for offscreen rendering
|
||||
};
|
||||
|
||||
// For node.js callback function type: function(error, buffer)
|
||||
using PrintToPDFCallback =
|
||||
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>;
|
||||
|
||||
// Create from an existing WebContents.
|
||||
static mate::Handle<WebContents> CreateFrom(
|
||||
v8::Isolate* isolate,
|
||||
content::WebContents* web_contents);
|
||||
static mate::Handle<WebContents> CreateFrom(
|
||||
v8::Isolate* isolate,
|
||||
content::WebContents* web_contents,
|
||||
Type type);
|
||||
|
||||
// Create a new WebContents.
|
||||
// Create a new WebContents and return the V8 wrapper of it.
|
||||
static mate::Handle<WebContents> Create(v8::Isolate* isolate,
|
||||
const mate::Dictionary& options);
|
||||
|
||||
// Create a new V8 wrapper for an existing |web_content|.
|
||||
//
|
||||
// The lifetime of |web_contents| will be managed by this class.
|
||||
static mate::Handle<WebContents> CreateAndTake(
|
||||
v8::Isolate* isolate,
|
||||
std::unique_ptr<content::WebContents> web_contents,
|
||||
Type type);
|
||||
|
||||
// Get the V8 wrapper of |web_content|, return empty handle if not wrapped.
|
||||
static mate::Handle<WebContents> From(v8::Isolate* isolate,
|
||||
content::WebContents* web_content);
|
||||
|
||||
// Get the V8 wrapper of the |web_contents|, or create one if not existed.
|
||||
//
|
||||
// The lifetime of |web_contents| is NOT managed by this class, and the type
|
||||
// of this wrapper is always REMOTE.
|
||||
static mate::Handle<WebContents> FromOrCreate(
|
||||
v8::Isolate* isolate,
|
||||
content::WebContents* web_contents);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
// Notifies to destroy any guest web contents before destroying self.
|
||||
base::WeakPtr<WebContents> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
|
||||
|
||||
// Destroy the managed content::WebContents instance.
|
||||
//
|
||||
// Note: The |async| should only be |true| when users are expecting to use the
|
||||
// webContents immediately after the call. Always pass |false| if you are not
|
||||
// sure.
|
||||
// See https://github.com/electron/electron/issues/8930.
|
||||
//
|
||||
// Note: When destroying a webContents member inside a destructor, the |async|
|
||||
// should always be |false|, otherwise the destroy task might be delayed after
|
||||
// normal shutdown procedure, resulting in an assertion.
|
||||
// The normal pattern for calling this method in destructor is:
|
||||
// api_web_contents_->DestroyWebContents(!Browser::Get()->is_shutting_down())
|
||||
// See https://github.com/electron/electron/issues/15133.
|
||||
void DestroyWebContents(bool async);
|
||||
|
||||
void SetBackgroundThrottling(bool allowed);
|
||||
int GetProcessID() const;
|
||||
base::ProcessId GetOSProcessID() const;
|
||||
Type GetType() const;
|
||||
@@ -124,9 +156,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void SetUserAgent(const std::string& user_agent, mate::Arguments* args);
|
||||
std::string GetUserAgent();
|
||||
void InsertCSS(const std::string& css);
|
||||
bool SavePage(const base::FilePath& full_file_path,
|
||||
const content::SavePageType& save_type,
|
||||
const SavePageHandler::SavePageCallback& callback);
|
||||
v8::Local<v8::Promise> SavePage(const base::FilePath& full_file_path,
|
||||
const content::SavePageType& save_type);
|
||||
void OpenDevTools(mate::Arguments* args);
|
||||
void CloseDevTools();
|
||||
bool IsDevToolsOpened();
|
||||
@@ -135,22 +166,22 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void EnableDeviceEmulation(const blink::WebDeviceEmulationParams& params);
|
||||
void DisableDeviceEmulation();
|
||||
void InspectElement(int x, int y);
|
||||
void InspectSharedWorker();
|
||||
void InspectServiceWorker();
|
||||
void HasServiceWorker(const base::Callback<void(bool)>&);
|
||||
void UnregisterServiceWorker(const base::Callback<void(bool)>&);
|
||||
void SetIgnoreMenuShortcuts(bool ignore);
|
||||
void SetAudioMuted(bool muted);
|
||||
bool IsAudioMuted();
|
||||
bool IsCurrentlyAudible();
|
||||
void Print(mate::Arguments* args);
|
||||
std::vector<printing::PrinterBasicInfo> GetPrinterList();
|
||||
void SetEmbedder(const WebContents* embedder);
|
||||
void SetDevToolsWebContents(const WebContents* devtools);
|
||||
v8::Local<v8::Value> GetNativeView() const;
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
void Print(mate::Arguments* args);
|
||||
std::vector<printing::PrinterBasicInfo> GetPrinterList();
|
||||
// Print current page as PDF.
|
||||
void PrintToPDF(const base::DictionaryValue& setting,
|
||||
const PrintToPDFCallback& callback);
|
||||
v8::Local<v8::Promise> PrintToPDF(const base::DictionaryValue& settings);
|
||||
#endif
|
||||
|
||||
// DevTools workspace api.
|
||||
void AddWorkSpace(mate::Arguments* args, const base::FilePath& path);
|
||||
@@ -190,6 +221,12 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
const base::ListValue& args,
|
||||
int32_t sender_id = 0);
|
||||
|
||||
bool SendIPCMessageToFrame(bool internal,
|
||||
bool send_to_all,
|
||||
int32_t frame_id,
|
||||
const std::string& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
// Send WebInputEvent to the page.
|
||||
void SendInputEvent(v8::Isolate* isolate, v8::Local<v8::Value> input_event);
|
||||
|
||||
@@ -202,12 +239,13 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
|
||||
// Captures the page with |rect|, |callback| would be called when capturing is
|
||||
// done.
|
||||
void CapturePage(mate::Arguments* args);
|
||||
v8::Local<v8::Promise> CapturePage(mate::Arguments* args);
|
||||
|
||||
// Methods for creating <webview>.
|
||||
bool IsGuest() const;
|
||||
void AttachToIframe(content::WebContents* embedder_web_contents,
|
||||
int embedder_frame_id);
|
||||
void DetachFromOuterFrame();
|
||||
|
||||
// Methods for offscreen rendering
|
||||
bool IsOffScreen() const;
|
||||
@@ -249,6 +287,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate) const;
|
||||
v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate) const;
|
||||
|
||||
bool IsRemoteModuleEnabled() const;
|
||||
|
||||
// Returns the owner window.
|
||||
v8::Local<v8::Value> GetOwnerBrowserWindow() const;
|
||||
|
||||
@@ -256,8 +296,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// the specified URL.
|
||||
void GrantOriginAccess(const GURL& url);
|
||||
|
||||
bool TakeHeapSnapshot(const base::FilePath& file_path,
|
||||
const std::string& channel);
|
||||
void TakeHeapSnapshot(const base::FilePath& file_path,
|
||||
base::Callback<void(bool)>);
|
||||
|
||||
// Properties.
|
||||
int32_t ID() const;
|
||||
@@ -272,27 +312,34 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
observers_.AddObserver(obs);
|
||||
}
|
||||
void RemoveObserver(ExtendedWebContentsObserver* obs) {
|
||||
observers_.RemoveObserver(obs);
|
||||
// Trying to remove from an empty collection leads to an access violation
|
||||
if (observers_.might_have_observers())
|
||||
observers_.RemoveObserver(obs);
|
||||
}
|
||||
|
||||
bool EmitNavigationEvent(const std::string& event,
|
||||
content::NavigationHandle* navigation_handle);
|
||||
|
||||
protected:
|
||||
// Does not manage lifetime of |web_contents|.
|
||||
WebContents(v8::Isolate* isolate, content::WebContents* web_contents);
|
||||
// Takes over ownership of |web_contents|.
|
||||
WebContents(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents,
|
||||
std::unique_ptr<content::WebContents> web_contents,
|
||||
Type type);
|
||||
// Creates a new content::WebContents.
|
||||
WebContents(v8::Isolate* isolate, const mate::Dictionary& options);
|
||||
~WebContents() override;
|
||||
|
||||
void InitWithSessionAndOptions(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents,
|
||||
mate::Handle<class Session> session,
|
||||
const mate::Dictionary& options);
|
||||
void InitWithSessionAndOptions(
|
||||
v8::Isolate* isolate,
|
||||
std::unique_ptr<content::WebContents> web_contents,
|
||||
mate::Handle<class Session> session,
|
||||
const mate::Dictionary& options);
|
||||
|
||||
// content::WebContentsDelegate:
|
||||
bool DidAddMessageToConsole(content::WebContents* source,
|
||||
int32_t level,
|
||||
blink::mojom::ConsoleMessageLevel level,
|
||||
const base::string16& message,
|
||||
int32_t line_no,
|
||||
const base::string16& source_id) override;
|
||||
@@ -319,7 +366,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void CloseContents(content::WebContents* source) override;
|
||||
void ActivateContents(content::WebContents* contents) override;
|
||||
void UpdateTargetURL(content::WebContents* source, const GURL& url) override;
|
||||
void HandleKeyboardEvent(
|
||||
bool HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
|
||||
@@ -337,7 +384,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void RendererResponsive(
|
||||
content::WebContents* source,
|
||||
content::RenderWidgetHost* render_widget_host) override;
|
||||
bool HandleContextMenu(const content::ContextMenuParams& params) override;
|
||||
bool HandleContextMenu(content::RenderFrameHost* render_frame_host,
|
||||
const content::ContextMenuParams& params) override;
|
||||
bool OnGoToEntryOffset(int offset) override;
|
||||
void FindReply(content::WebContents* web_contents,
|
||||
int request_id,
|
||||
@@ -347,7 +395,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
bool final_update) override;
|
||||
bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& security_origin,
|
||||
content::MediaStreamType type) override;
|
||||
blink::MediaStreamType type) override;
|
||||
void RequestMediaAccessPermission(
|
||||
content::WebContents* web_contents,
|
||||
const content::MediaStreamRequest& request,
|
||||
@@ -363,10 +411,14 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void OnAudioStateChanged(bool audible) override;
|
||||
|
||||
// content::WebContentsObserver:
|
||||
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
|
||||
void BeforeUnloadFired(bool proceed,
|
||||
const base::TimeTicks& proceed_time) override;
|
||||
void RenderViewCreated(content::RenderViewHost*) override;
|
||||
void RenderViewHostChanged(content::RenderViewHost* old_host,
|
||||
content::RenderViewHost* new_host) override;
|
||||
void RenderViewDeleted(content::RenderViewHost*) override;
|
||||
void RenderProcessGone(base::TerminationStatus status) override;
|
||||
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
|
||||
void DocumentLoadedInFrame(
|
||||
content::RenderFrameHost* render_frame_host) override;
|
||||
void DidFinishLoad(content::RenderFrameHost* render_frame_host,
|
||||
@@ -395,17 +447,22 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void PluginCrashed(const base::FilePath& plugin_path,
|
||||
base::ProcessId plugin_pid) override;
|
||||
void MediaStartedPlaying(const MediaPlayerInfo& video_type,
|
||||
const MediaPlayerId& id) override;
|
||||
const content::MediaPlayerId& id) override;
|
||||
void MediaStoppedPlaying(
|
||||
const MediaPlayerInfo& video_type,
|
||||
const MediaPlayerId& id,
|
||||
const content::MediaPlayerId& id,
|
||||
content::WebContentsObserver::MediaStoppedReason reason) override;
|
||||
void DidChangeThemeColor(SkColor theme_color) override;
|
||||
void DidChangeThemeColor(base::Optional<SkColor> theme_color) override;
|
||||
void OnInterfaceRequestFromFrame(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const std::string& interface_name,
|
||||
mojo::ScopedMessagePipeHandle* interface_pipe) override;
|
||||
void DidAcquireFullscreen(content::RenderFrameHost* rfh) override;
|
||||
|
||||
// brightray::InspectableWebContentsDelegate:
|
||||
// InspectableWebContentsDelegate:
|
||||
void DevToolsReloadPage() override;
|
||||
|
||||
// brightray::InspectableWebContentsViewDelegate:
|
||||
// InspectableWebContentsViewDelegate:
|
||||
void DevToolsFocused() override;
|
||||
void DevToolsOpened() override;
|
||||
void DevToolsClosed() override;
|
||||
@@ -421,35 +478,37 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
struct FrameDispatchHelper;
|
||||
AtomBrowserContext* GetBrowserContext() const;
|
||||
|
||||
// Binds the given request for the ElectronBrowser API. When the
|
||||
// RenderFrameHost is destroyed, all related bindings will be removed.
|
||||
void BindElectronBrowser(mojom::ElectronBrowserRequest request,
|
||||
content::RenderFrameHost* render_frame_host);
|
||||
void OnElectronBrowserConnectionError();
|
||||
|
||||
uint32_t GetNextRequestId() { return ++request_id_; }
|
||||
|
||||
#if BUILDFLAG(ENABLE_OSR)
|
||||
OffScreenWebContentsView* GetOffScreenWebContentsView() const;
|
||||
OffScreenWebContentsView* GetOffScreenWebContentsView() const override;
|
||||
OffScreenRenderWidgetHostView* GetOffScreenRenderWidgetHostView() const;
|
||||
#endif
|
||||
|
||||
// mojom::ElectronBrowser
|
||||
void Message(bool internal,
|
||||
const std::string& channel,
|
||||
base::Value arguments) override;
|
||||
void MessageSync(bool internal,
|
||||
const std::string& channel,
|
||||
base::Value arguments,
|
||||
MessageSyncCallback callback) override;
|
||||
void MessageTo(bool internal,
|
||||
bool send_to_all,
|
||||
int32_t web_contents_id,
|
||||
const std::string& channel,
|
||||
base::Value arguments) override;
|
||||
void MessageHost(const std::string& channel, base::Value arguments) override;
|
||||
|
||||
// Called when we receive a CursorChange message from chromium.
|
||||
void OnCursorChange(const content::WebCursor& cursor);
|
||||
|
||||
// Called when received a message from renderer.
|
||||
void OnRendererMessage(content::RenderFrameHost* frame_host,
|
||||
const std::string& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
// Called when received a synchronous message from renderer.
|
||||
void OnRendererMessageSync(content::RenderFrameHost* frame_host,
|
||||
const std::string& channel,
|
||||
const base::ListValue& args,
|
||||
IPC::Message* message);
|
||||
|
||||
// Called when received a message from renderer to be forwarded.
|
||||
void OnRendererMessageTo(content::RenderFrameHost* frame_host,
|
||||
bool internal,
|
||||
bool send_to_all,
|
||||
int32_t web_contents_id,
|
||||
const std::string& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
// Called when received a synchronous message from renderer to
|
||||
// set temporary zoom level.
|
||||
void OnSetTemporaryZoomLevel(content::RenderFrameHost* frame_host,
|
||||
@@ -470,7 +529,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
|
||||
std::unique_ptr<AtomJavaScriptDialogManager> dialog_manager_;
|
||||
std::unique_ptr<WebViewGuestDelegate> guest_delegate_;
|
||||
|
||||
std::unique_ptr<FrameSubscriber> frame_subscriber_;
|
||||
|
||||
// The host webcontents that may contain this webcontents.
|
||||
@@ -494,6 +552,17 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// Observers of this WebContents.
|
||||
base::ObserverList<ExtendedWebContentsObserver> observers_;
|
||||
|
||||
// The ID of the process of the currently committed RenderViewHost.
|
||||
// -1 means no speculative RVH has been committed yet.
|
||||
int currently_committed_process_id_ = -1;
|
||||
|
||||
service_manager::BinderRegistryWithArgs<content::RenderFrameHost*> registry_;
|
||||
mojo::BindingSet<mojom::ElectronBrowser, content::RenderFrameHost*> bindings_;
|
||||
std::map<content::RenderFrameHost*, std::vector<mojo::BindingId>>
|
||||
frame_to_bindings_map_;
|
||||
|
||||
base::WeakPtrFactory<WebContents> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContents);
|
||||
};
|
||||
|
||||
|
||||
62
atom/browser/api/atom_api_web_contents_impl.cc
Normal file
62
atom/browser/api/atom_api_web_contents_impl.cc
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
|
||||
#include "content/browser/frame_host/frame_tree.h" // nogncheck
|
||||
#include "content/browser/frame_host/frame_tree_node.h" // nogncheck
|
||||
#include "content/browser/web_contents/web_contents_impl.h" // nogncheck
|
||||
#include "content/public/browser/guest_mode.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_OSR)
|
||||
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
||||
#include "atom/browser/osr/osr_web_contents_view.h"
|
||||
#endif
|
||||
|
||||
// Including both web_contents_impl.h and node.h would introduce a error, we
|
||||
// have to isolate the usage of WebContentsImpl into a clean file to fix it:
|
||||
// error C2371: 'ssize_t': redefinition; different basic types
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
void WebContents::DetachFromOuterFrame() {
|
||||
// See detach_webview_frame.patch on how to detach.
|
||||
DCHECK(content::GuestMode::IsCrossProcessFrameGuest(web_contents()));
|
||||
int frame_tree_node_id =
|
||||
static_cast<content::WebContentsImpl*>(web_contents())
|
||||
->GetOuterDelegateFrameTreeNodeId();
|
||||
if (frame_tree_node_id != content::FrameTreeNode::kFrameTreeNodeInvalidId) {
|
||||
auto* node = content::FrameTreeNode::GloballyFindByID(frame_tree_node_id);
|
||||
DCHECK(node->parent());
|
||||
node->frame_tree()->RemoveFrame(node);
|
||||
}
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_OSR)
|
||||
OffScreenWebContentsView* WebContents::GetOffScreenWebContentsView() const {
|
||||
if (IsOffScreen()) {
|
||||
const auto* impl =
|
||||
static_cast<const content::WebContentsImpl*>(web_contents());
|
||||
return static_cast<OffScreenWebContentsView*>(impl->GetView());
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
OffScreenRenderWidgetHostView* WebContents::GetOffScreenRenderWidgetHostView()
|
||||
const {
|
||||
if (IsOffScreen()) {
|
||||
return static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents()->GetRenderWidgetHostView());
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
@@ -17,7 +17,7 @@ bool WebContents::IsFocused() const {
|
||||
return false;
|
||||
|
||||
if (GetType() != BACKGROUND_PAGE) {
|
||||
auto window = [web_contents()->GetNativeView() window];
|
||||
auto window = [web_contents()->GetNativeView().GetNativeNSView() window];
|
||||
// On Mac the render widget host view does not lose focus when the window
|
||||
// loses focus so check if the top level window is the key window.
|
||||
if (window && ![window isKeyWindow])
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
|
||||
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
||||
#include "atom/browser/osr/osr_web_contents_view.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
|
||||
// Including both web_contents_impl.h and node.h would introduce a error, we
|
||||
// have to isolate the usage of WebContentsImpl into a clean file to fix it:
|
||||
// error C2371: 'ssize_t': redefinition; different basic types
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
OffScreenWebContentsView* WebContents::GetOffScreenWebContentsView() const {
|
||||
const auto* impl =
|
||||
static_cast<const content::WebContentsImpl*>(web_contents());
|
||||
return static_cast<OffScreenWebContentsView*>(impl->GetView());
|
||||
}
|
||||
|
||||
OffScreenRenderWidgetHostView* WebContents::GetOffScreenRenderWidgetHostView()
|
||||
const {
|
||||
return static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents()->GetRenderWidgetHostView());
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
@@ -5,8 +5,10 @@
|
||||
#include "atom/browser/api/atom_api_web_contents_view.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "atom/common/api/constructor.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "content/public/browser/web_contents_user_data.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
@@ -14,8 +16,6 @@
|
||||
#include "atom/browser/ui/cocoa/delayed_native_view_host.h"
|
||||
#endif
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Used to indicate whether a WebContents already has a view.
|
||||
@@ -30,12 +30,14 @@ class WebContentsViewRelay
|
||||
|
||||
atom::api::WebContentsView* view_ = nullptr;
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_DECL();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContentsViewRelay);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
WEB_CONTENTS_USER_DATA_KEY_IMPL(WebContentsViewRelay)
|
||||
|
||||
DEFINE_WEB_CONTENTS_USER_DATA_KEY(WebContentsViewRelay);
|
||||
} // namespace
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -43,7 +45,7 @@ namespace api {
|
||||
|
||||
WebContentsView::WebContentsView(v8::Isolate* isolate,
|
||||
mate::Handle<WebContents> web_contents,
|
||||
brightray::InspectableWebContents* iwc)
|
||||
InspectableWebContents* iwc)
|
||||
#if defined(OS_MACOSX)
|
||||
: View(new DelayedNativeViewHost(iwc->GetView()->GetNativeView())),
|
||||
#else
|
||||
@@ -64,8 +66,11 @@ WebContentsView::WebContentsView(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
WebContentsView::~WebContentsView() {
|
||||
if (api_web_contents_)
|
||||
api_web_contents_->DestroyWebContents(false /* async */);
|
||||
if (api_web_contents_) { // destroy() is called
|
||||
// Destroy WebContents asynchronously unless app is shutting down,
|
||||
// because destroy() might be called inside WebContents's event handler.
|
||||
api_web_contents_->DestroyWebContents(!Browser::Get()->is_shutting_down());
|
||||
}
|
||||
}
|
||||
|
||||
void WebContentsView::WebContentsDestroyed() {
|
||||
@@ -125,4 +130,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_web_contents_view, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_web_contents_view, Initialize)
|
||||
|
||||
@@ -9,12 +9,10 @@
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace brightray {
|
||||
class InspectableWebContents;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class InspectableWebContents;
|
||||
|
||||
namespace api {
|
||||
|
||||
class WebContents;
|
||||
@@ -30,7 +28,7 @@ class WebContentsView : public View, public content::WebContentsObserver {
|
||||
protected:
|
||||
WebContentsView(v8::Isolate* isolate,
|
||||
mate::Handle<WebContents> web_contents,
|
||||
brightray::InspectableWebContents* iwc);
|
||||
InspectableWebContents* iwc);
|
||||
~WebContentsView() override;
|
||||
|
||||
// content::WebContentsObserver:
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
@@ -29,7 +31,7 @@ struct Converter<URLPattern> {
|
||||
if (!ConvertFromV8(isolate, val, &pattern))
|
||||
return false;
|
||||
*out = URLPattern(URLPattern::SCHEME_ALL);
|
||||
return out->Parse(pattern) == URLPattern::PARSE_SUCCESS;
|
||||
return out->Parse(pattern) == URLPattern::ParseResult::kSuccess;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -97,8 +99,8 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
|
||||
browser_context_->GetRequestContext());
|
||||
if (!url_request_context_getter)
|
||||
return;
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&CallNetworkDelegateMethod<Method, Event, Listener>,
|
||||
base::RetainedRef(url_request_context_getter), method,
|
||||
type, std::move(patterns), std::move(listener)));
|
||||
|
||||
@@ -7,14 +7,11 @@
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/native_mate_converters/content_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
// Must be the last in the includes list.
|
||||
// See https://github.com/electron/electron/issues/10363
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using atom::WebContentsPreferences;
|
||||
|
||||
namespace {
|
||||
@@ -55,4 +52,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_web_view_manager, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_web_view_manager, Initialize)
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "atom/browser/api/event.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
@@ -20,11 +22,11 @@ Event::Event(v8::Isolate* isolate) {
|
||||
Event::~Event() {}
|
||||
|
||||
void Event::SetSenderAndMessage(content::RenderFrameHost* sender,
|
||||
IPC::Message* message) {
|
||||
base::Optional<MessageSyncCallback> callback) {
|
||||
DCHECK(!sender_);
|
||||
DCHECK(!message_);
|
||||
DCHECK(!callback_);
|
||||
sender_ = sender;
|
||||
message_ = message;
|
||||
callback_ = std::move(callback);
|
||||
|
||||
Observe(content::WebContents::FromRenderFrameHost(sender));
|
||||
}
|
||||
@@ -33,7 +35,7 @@ void Event::RenderFrameDeleted(content::RenderFrameHost* rfh) {
|
||||
if (sender_ != rfh)
|
||||
return;
|
||||
sender_ = nullptr;
|
||||
message_ = nullptr;
|
||||
callback_.reset();
|
||||
}
|
||||
|
||||
void Event::RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
|
||||
@@ -46,22 +48,23 @@ void Event::FrameDeleted(content::RenderFrameHost* rfh) {
|
||||
if (sender_ != rfh)
|
||||
return;
|
||||
sender_ = nullptr;
|
||||
message_ = nullptr;
|
||||
callback_.reset();
|
||||
}
|
||||
|
||||
void Event::PreventDefault(v8::Isolate* isolate) {
|
||||
GetWrapper()->Set(StringToV8(isolate, "defaultPrevented"), v8::True(isolate));
|
||||
GetWrapper()
|
||||
->Set(isolate->GetCurrentContext(),
|
||||
StringToV8(isolate, "defaultPrevented"), v8::True(isolate))
|
||||
.Check();
|
||||
}
|
||||
|
||||
bool Event::SendReply(const base::ListValue& result) {
|
||||
if (message_ == nullptr || sender_ == nullptr)
|
||||
if (!callback_ || sender_ == nullptr)
|
||||
return false;
|
||||
|
||||
AtomFrameHostMsg_Message_Sync::WriteReplyParams(message_, result);
|
||||
bool success = sender_->Send(message_);
|
||||
message_ = nullptr;
|
||||
sender_ = nullptr;
|
||||
return success;
|
||||
std::move(*callback_).Run(result.Clone());
|
||||
callback_.reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
#ifndef ATOM_BROWSER_API_EVENT_H_
|
||||
#define ATOM_BROWSER_API_EVENT_H_
|
||||
|
||||
#include "base/optional.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "electron/atom/common/api/api.mojom.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
|
||||
@@ -17,6 +19,7 @@ namespace mate {
|
||||
|
||||
class Event : public Wrappable<Event>, public content::WebContentsObserver {
|
||||
public:
|
||||
using MessageSyncCallback = atom::mojom::ElectronBrowser::MessageSyncCallback;
|
||||
static Handle<Event> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
@@ -24,7 +27,7 @@ class Event : public Wrappable<Event>, public content::WebContentsObserver {
|
||||
|
||||
// Pass the sender and message to be replied.
|
||||
void SetSenderAndMessage(content::RenderFrameHost* sender,
|
||||
IPC::Message* message);
|
||||
base::Optional<MessageSyncCallback> callback);
|
||||
|
||||
// event.PreventDefault().
|
||||
void PreventDefault(v8::Isolate* isolate);
|
||||
@@ -45,7 +48,7 @@ class Event : public Wrappable<Event>, public content::WebContentsObserver {
|
||||
private:
|
||||
// Replyer for the synchronous messages.
|
||||
content::RenderFrameHost* sender_ = nullptr;
|
||||
IPC::Message* message_ = nullptr;
|
||||
base::Optional<MessageSyncCallback> callback_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Event);
|
||||
};
|
||||
|
||||
@@ -4,14 +4,16 @@
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/api/event.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "native_mate/arguments.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "ui/events/event_constants.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace {
|
||||
@@ -34,28 +36,34 @@ v8::Local<v8::Object> CreateEventObject(v8::Isolate* isolate) {
|
||||
}
|
||||
|
||||
return v8::Local<v8::ObjectTemplate>::New(isolate, event_template)
|
||||
->NewInstance();
|
||||
->NewInstance(isolate->GetCurrentContext())
|
||||
.ToLocalChecked();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace internal {
|
||||
|
||||
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
content::RenderFrameHost* sender,
|
||||
IPC::Message* message) {
|
||||
v8::Local<v8::Object> CreateJSEvent(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
content::RenderFrameHost* sender,
|
||||
base::Optional<atom::mojom::ElectronBrowser::MessageSyncCallback>
|
||||
callback) {
|
||||
v8::Local<v8::Object> event;
|
||||
bool use_native_event = sender && message;
|
||||
bool use_native_event = sender && callback;
|
||||
|
||||
if (use_native_event) {
|
||||
mate::Handle<mate::Event> native_event = mate::Event::Create(isolate);
|
||||
native_event->SetSenderAndMessage(sender, message);
|
||||
native_event->SetSenderAndMessage(sender, std::move(callback));
|
||||
event = v8::Local<v8::Object>::Cast(native_event.ToV8());
|
||||
} else {
|
||||
event = CreateEventObject(isolate);
|
||||
}
|
||||
mate::Dictionary(isolate, event).Set("sender", object);
|
||||
mate::Dictionary dict(isolate, event);
|
||||
dict.Set("sender", object);
|
||||
if (sender)
|
||||
dict.Set("frameId", sender->GetRoutingID());
|
||||
return event;
|
||||
}
|
||||
|
||||
@@ -74,6 +82,7 @@ v8::Local<v8::Object> CreateEventFromFlags(v8::Isolate* isolate, int flags) {
|
||||
obj.Set("ctrlKey", static_cast<bool>(flags & ui::EF_CONTROL_DOWN));
|
||||
obj.Set("altKey", static_cast<bool>(flags & ui::EF_ALT_DOWN));
|
||||
obj.Set("metaKey", static_cast<bool>(flags & ui::EF_COMMAND_DOWN));
|
||||
obj.Set("triggeredByAccelerator", static_cast<bool>(flags));
|
||||
return obj.GetHandle();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,27 +5,28 @@
|
||||
#ifndef ATOM_BROWSER_API_EVENT_EMITTER_H_
|
||||
#define ATOM_BROWSER_API_EVENT_EMITTER_H_
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/api/event_emitter_caller.h"
|
||||
#include "base/optional.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "electron/atom/common/api/api.mojom.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
|
||||
namespace content {
|
||||
class RenderFrameHost;
|
||||
}
|
||||
|
||||
namespace IPC {
|
||||
class Message;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace internal {
|
||||
|
||||
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
content::RenderFrameHost* sender,
|
||||
IPC::Message* message);
|
||||
v8::Local<v8::Object> CreateJSEvent(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
content::RenderFrameHost* sender,
|
||||
base::Optional<atom::mojom::ElectronBrowser::MessageSyncCallback> callback);
|
||||
v8::Local<v8::Object> CreateCustomEvent(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
v8::Local<v8::Object> event);
|
||||
@@ -68,23 +69,25 @@ class EventEmitter : public Wrappable<T> {
|
||||
// this.emit(name, new Event(), args...);
|
||||
template <typename... Args>
|
||||
bool Emit(const base::StringPiece& name, const Args&... args) {
|
||||
return EmitWithSender(name, nullptr, nullptr, args...);
|
||||
return EmitWithSender(name, nullptr, base::nullopt, args...);
|
||||
}
|
||||
|
||||
// this.emit(name, new Event(sender, message), args...);
|
||||
template <typename... Args>
|
||||
bool EmitWithSender(const base::StringPiece& name,
|
||||
content::RenderFrameHost* sender,
|
||||
IPC::Message* message,
|
||||
const Args&... args) {
|
||||
bool EmitWithSender(
|
||||
const base::StringPiece& name,
|
||||
content::RenderFrameHost* sender,
|
||||
base::Optional<atom::mojom::ElectronBrowser::MessageSyncCallback>
|
||||
callback,
|
||||
const Args&... args) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
v8::Local<v8::Object> wrapper = GetWrapper();
|
||||
if (wrapper.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
v8::Local<v8::Object> event =
|
||||
internal::CreateJSEvent(isolate(), wrapper, sender, message);
|
||||
v8::Local<v8::Object> event = internal::CreateJSEvent(
|
||||
isolate(), wrapper, sender, std::move(callback));
|
||||
return EmitWithEvent(name, event, args...);
|
||||
}
|
||||
|
||||
@@ -97,11 +100,17 @@ class EventEmitter : public Wrappable<T> {
|
||||
bool EmitWithEvent(const base::StringPiece& name,
|
||||
v8::Local<v8::Object> event,
|
||||
const Args&... args) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
EmitEvent(isolate(), GetWrapper(), name, event, args...);
|
||||
return event->Get(StringToV8(isolate(), "defaultPrevented"))
|
||||
->BooleanValue();
|
||||
auto context = isolate()->GetCurrentContext();
|
||||
v8::Local<v8::Value> defaultPrevented;
|
||||
if (event->Get(context, StringToV8(isolate(), "defaultPrevented"))
|
||||
.ToLocal(&defaultPrevented)) {
|
||||
return defaultPrevented->BooleanValue(isolate());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(EventEmitter);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user