mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
1423 Commits
v2.0.0-bet
...
v3.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64c8c27575 | ||
|
|
e76a976347 | ||
|
|
8d27657fa5 | ||
|
|
5e81d8dad9 | ||
|
|
b23acab456 | ||
|
|
8950caaa85 | ||
|
|
1b920c25af | ||
|
|
8fd31a3e07 | ||
|
|
893f866c05 | ||
|
|
d36b14a322 | ||
|
|
27a33cc1cf | ||
|
|
7835bceabd | ||
|
|
af4f08e030 | ||
|
|
03dac078d7 | ||
|
|
d3d44bdbc6 | ||
|
|
a370b6982d | ||
|
|
03ef5c25f7 | ||
|
|
3bc6652833 | ||
|
|
664371245a | ||
|
|
08270e6817 | ||
|
|
8f74a77a64 | ||
|
|
85c8ada99a | ||
|
|
b15a3ee2be | ||
|
|
7b043ac554 | ||
|
|
89a6f1efbb | ||
|
|
ce592a5705 | ||
|
|
12087b74e8 | ||
|
|
d365078022 | ||
|
|
3dbd84c224 | ||
|
|
2e479ff799 | ||
|
|
a341ae450a | ||
|
|
0aec308681 | ||
|
|
8e9c5b8338 | ||
|
|
6bc1e37156 | ||
|
|
7da7dd85e3 | ||
|
|
ccf8a797dc | ||
|
|
3301e05f33 | ||
|
|
b1c22ba531 | ||
|
|
873f39b159 | ||
|
|
11864e9e08 | ||
|
|
c8a21dbb92 | ||
|
|
97058837e7 | ||
|
|
ff539c1d61 | ||
|
|
9237d40e09 | ||
|
|
4721dc0856 | ||
|
|
1f7fd985dd | ||
|
|
d432e420ae | ||
|
|
635c3f53d8 | ||
|
|
ba703deee2 | ||
|
|
b03178105d | ||
|
|
ef0a6d9a1c | ||
|
|
4c7af6a429 | ||
|
|
d1886c5d22 | ||
|
|
c558dc2d7d | ||
|
|
be68cfd4ea | ||
|
|
115a15c356 | ||
|
|
d4fb904450 | ||
|
|
c7f7bdab8a | ||
|
|
de7cb9524a | ||
|
|
5d17e48490 | ||
|
|
058c03fdab | ||
|
|
bd0d6b1a02 | ||
|
|
0783eb9881 | ||
|
|
4e3aa2e061 | ||
|
|
92f3d47ab3 | ||
|
|
2a7ec7e051 | ||
|
|
bf465dc233 | ||
|
|
00cf45609f | ||
|
|
26f4190102 | ||
|
|
5d6382270a | ||
|
|
2162c996eb | ||
|
|
2945be4b9b | ||
|
|
c066a51bfe | ||
|
|
ff7dfe4a11 | ||
|
|
6d17663a0b | ||
|
|
bd4334e2b4 | ||
|
|
0f937c2300 | ||
|
|
2ecdf4a0eb | ||
|
|
44b0245ac4 | ||
|
|
c4d6484264 | ||
|
|
ef2ad40bd9 | ||
|
|
2642e064a2 | ||
|
|
daf23288bc | ||
|
|
8eec8e150d | ||
|
|
2af61cbe95 | ||
|
|
32ffb0ba17 | ||
|
|
69caea38c1 | ||
|
|
b5bfd9867b | ||
|
|
fb2afe8656 | ||
|
|
c926f3f6dc | ||
|
|
5aa247a627 | ||
|
|
67d202eaf6 | ||
|
|
98033e4f45 | ||
|
|
3d89185396 | ||
|
|
1f430259ce | ||
|
|
ff86cf5f6a | ||
|
|
274a53654c | ||
|
|
8f5fafb636 | ||
|
|
bfbd4a2540 | ||
|
|
1926eab172 | ||
|
|
9818378e2d | ||
|
|
ad2d35c7cf | ||
|
|
13d3a055fa | ||
|
|
07b93d475d | ||
|
|
c9da2d7669 | ||
|
|
a9a5766804 | ||
|
|
a62cb1e84c | ||
|
|
2bdb7a5047 | ||
|
|
29f70d7e35 | ||
|
|
91af624cb1 | ||
|
|
b08df88b7c | ||
|
|
b659ff2de3 | ||
|
|
3ad6abc5cc | ||
|
|
a880e0222f | ||
|
|
95c69e660c | ||
|
|
4333020157 | ||
|
|
f4ff97038c | ||
|
|
967577c335 | ||
|
|
8bd5c1f858 | ||
|
|
2955b0168c | ||
|
|
04b7c77951 | ||
|
|
136cf389e8 | ||
|
|
8d9775b0b1 | ||
|
|
9237d46dba | ||
|
|
8f8d198c5a | ||
|
|
fcdbb8c4a7 | ||
|
|
b49b071a1f | ||
|
|
1feb45da29 | ||
|
|
2c43dbdb25 | ||
|
|
7eff91dde1 | ||
|
|
780483ff35 | ||
|
|
c2f770df02 | ||
|
|
74e6e063d4 | ||
|
|
7702cc1090 | ||
|
|
97319e5a3a | ||
|
|
041c952574 | ||
|
|
6c9b6f9cac | ||
|
|
c4884da601 | ||
|
|
59b05ed661 | ||
|
|
e3204a5ec1 | ||
|
|
adf49daaac | ||
|
|
9431677e79 | ||
|
|
0141c083d0 | ||
|
|
96b2c08293 | ||
|
|
d6f2c26b0f | ||
|
|
d478906f9c | ||
|
|
85526c7f21 | ||
|
|
f6ae438005 | ||
|
|
5e51e608db | ||
|
|
97248a7a56 | ||
|
|
8639466c75 | ||
|
|
31e2166cea | ||
|
|
c2f4144996 | ||
|
|
f63e5ffa65 | ||
|
|
32e40cb4c3 | ||
|
|
8585372e11 | ||
|
|
2e2289d701 | ||
|
|
f6229d9489 | ||
|
|
bace4890c8 | ||
|
|
0a3211c387 | ||
|
|
7d27c91400 | ||
|
|
93edf2edd3 | ||
|
|
ec993214a2 | ||
|
|
509120acde | ||
|
|
b472a69279 | ||
|
|
7f3620bee3 | ||
|
|
21d4ef5eab | ||
|
|
4f6b6b044f | ||
|
|
02026279be | ||
|
|
6fd1f7ecb1 | ||
|
|
922cf08ab4 | ||
|
|
7f8cd51f63 | ||
|
|
31e5b046a4 | ||
|
|
957f008726 | ||
|
|
4cada5e845 | ||
|
|
2069eb1972 | ||
|
|
e15ffd96eb | ||
|
|
e57f7edd37 | ||
|
|
df62fb7788 | ||
|
|
9b09d103fd | ||
|
|
453edb42b4 | ||
|
|
1b2a85436c | ||
|
|
c7d4d2d18f | ||
|
|
d1a0eb3d11 | ||
|
|
a0e37d1383 | ||
|
|
128a03450a | ||
|
|
d34c7396ef | ||
|
|
cdbd4792e3 | ||
|
|
b0f6c3ab65 | ||
|
|
d2508faea8 | ||
|
|
9bda7d0b73 | ||
|
|
fc12b5cab3 | ||
|
|
04a7a34c42 | ||
|
|
f643ce4f66 | ||
|
|
3044607746 | ||
|
|
10df019075 | ||
|
|
295c823a1b | ||
|
|
d367b75680 | ||
|
|
e683af1eb6 | ||
|
|
794fe741e9 | ||
|
|
c598272891 | ||
|
|
137aaf2429 | ||
|
|
13f97b4cae | ||
|
|
9e8f83e25c | ||
|
|
e177117fa5 | ||
|
|
dd6c776a19 | ||
|
|
36c1e4cd75 | ||
|
|
faef453df5 | ||
|
|
cba3a9fcce | ||
|
|
9a79889692 | ||
|
|
0219ef0feb | ||
|
|
be29a1973b | ||
|
|
0fdcc5d485 | ||
|
|
a3bc989426 | ||
|
|
c58fa02e58 | ||
|
|
d2a950e054 | ||
|
|
5151a04613 | ||
|
|
bbc8d50799 | ||
|
|
bcbcb4c643 | ||
|
|
d5d5386017 | ||
|
|
f0e2da7089 | ||
|
|
906ef3da6a | ||
|
|
2720fa751b | ||
|
|
42c37cc26d | ||
|
|
56ae882bb8 | ||
|
|
9d18be8fde | ||
|
|
ed1f8d3646 | ||
|
|
efdf4f44c8 | ||
|
|
650631421f | ||
|
|
518f0005ad | ||
|
|
5a28759fea | ||
|
|
6c604e1eb3 | ||
|
|
25e5c174f5 | ||
|
|
b70ca6309c | ||
|
|
8f4d6a1995 | ||
|
|
ad74fb9210 | ||
|
|
da7cfba357 | ||
|
|
10c5141da0 | ||
|
|
10160b369b | ||
|
|
76f26341bf | ||
|
|
8200a132be | ||
|
|
c4f80a6d89 | ||
|
|
10e0d9b198 | ||
|
|
e70b93ad91 | ||
|
|
bc8525d2f3 | ||
|
|
c882b37a40 | ||
|
|
d9ec885dbc | ||
|
|
f43eafb94e | ||
|
|
de5bdc8be4 | ||
|
|
b7d00e26bf | ||
|
|
9b37e7d988 | ||
|
|
0b12e425bd | ||
|
|
a64def5745 | ||
|
|
0c69b0e224 | ||
|
|
03a63a485f | ||
|
|
e96d8b664d | ||
|
|
1fae6a321c | ||
|
|
f4a9575193 | ||
|
|
792bb9b4a8 | ||
|
|
67558d65a6 | ||
|
|
caed1c37e0 | ||
|
|
de6a5de914 | ||
|
|
cd428a047f | ||
|
|
417fe29dc0 | ||
|
|
a7d2f7531c | ||
|
|
c786abf1e9 | ||
|
|
622544a902 | ||
|
|
6481161ef2 | ||
|
|
6e11494d0b | ||
|
|
7886cfe408 | ||
|
|
368734b8ab | ||
|
|
e240a16a20 | ||
|
|
4a08779bc8 | ||
|
|
3ca288aba4 | ||
|
|
6c0b5cd76c | ||
|
|
c3ccd42a23 | ||
|
|
f9278e518c | ||
|
|
40bf582c81 | ||
|
|
81398c1fde | ||
|
|
08ee965270 | ||
|
|
65b8dd48d8 | ||
|
|
91d16c9b3a | ||
|
|
60ba2013c4 | ||
|
|
b9413fe59d | ||
|
|
ca8843102a | ||
|
|
9b9a818c43 | ||
|
|
7e4c0b304b | ||
|
|
90c3d87e21 | ||
|
|
dd444fd429 | ||
|
|
58b9203b9b | ||
|
|
ddaf2cfdc5 | ||
|
|
1321e8a6df | ||
|
|
6d7e281dc8 | ||
|
|
32ff2ff8fb | ||
|
|
a45b1a9205 | ||
|
|
123b35a7f1 | ||
|
|
77ae8b65f7 | ||
|
|
5656cb34b8 | ||
|
|
7616cb38a7 | ||
|
|
a9eb267f92 | ||
|
|
496dbb6b7e | ||
|
|
3e6e01eb94 | ||
|
|
42d84bbd70 | ||
|
|
650f7a920a | ||
|
|
7b17f15703 | ||
|
|
8f00240c73 | ||
|
|
3ac4c1f03f | ||
|
|
a45862c93f | ||
|
|
623ed84b23 | ||
|
|
000bbd45b8 | ||
|
|
016ac8ff6e | ||
|
|
aaef07e637 | ||
|
|
101cd90d37 | ||
|
|
32ebd9e221 | ||
|
|
bbd6b478ac | ||
|
|
7ca1b0704d | ||
|
|
1ac0ab2b71 | ||
|
|
d6ffbc0148 | ||
|
|
4a38c2d800 | ||
|
|
f6648a0d4d | ||
|
|
82d204e932 | ||
|
|
97414cc931 | ||
|
|
5451635df0 | ||
|
|
1de1ca906a | ||
|
|
28f6e10e5a | ||
|
|
ac33694028 | ||
|
|
9e3011dbcd | ||
|
|
c97706de50 | ||
|
|
844ef4291c | ||
|
|
43ca4d5bfd | ||
|
|
3f7bb61b7f | ||
|
|
39b30b76ea | ||
|
|
37d64e6a00 | ||
|
|
4236c17654 | ||
|
|
24db18f34e | ||
|
|
405adb938b | ||
|
|
4068a62fa6 | ||
|
|
c4b8e106c0 | ||
|
|
f1e2304585 | ||
|
|
77f427acc8 | ||
|
|
e1f25253db | ||
|
|
a218c9696c | ||
|
|
5df0362361 | ||
|
|
2f7c413199 | ||
|
|
66058c8cfe | ||
|
|
d386ec0a2b | ||
|
|
3ad0639b2e | ||
|
|
ea7e273a06 | ||
|
|
383b21e20a | ||
|
|
a5bdb8103b | ||
|
|
0cbffb15cc | ||
|
|
27cb84eee0 | ||
|
|
b268e37663 | ||
|
|
c9f20516ac | ||
|
|
a1683eb4e8 | ||
|
|
eab4227cbf | ||
|
|
11fc8374c0 | ||
|
|
8968c447f4 | ||
|
|
7b47d69efe | ||
|
|
3da6450b0c | ||
|
|
2ea26cd4d7 | ||
|
|
100291ec42 | ||
|
|
2047929cb5 | ||
|
|
7732da41ba | ||
|
|
93fc60720a | ||
|
|
bb150185ac | ||
|
|
c75f6f408e | ||
|
|
4bb3e0da15 | ||
|
|
576bf8f6c0 | ||
|
|
1a11bb936b | ||
|
|
4602d940cf | ||
|
|
38f18d9aa2 | ||
|
|
b7bc3ec20d | ||
|
|
409ff41c03 | ||
|
|
23f7ccbdda | ||
|
|
2c4bbacec1 | ||
|
|
343c42e4ef | ||
|
|
37168c0a95 | ||
|
|
d3c6aa12d1 | ||
|
|
bb36a26950 | ||
|
|
6b77fa5b3b | ||
|
|
5e320994f4 | ||
|
|
160b165358 | ||
|
|
7fc8814d13 | ||
|
|
4e580d5b39 | ||
|
|
a315d6330c | ||
|
|
48c3340d95 | ||
|
|
341f698ace | ||
|
|
e3c580e905 | ||
|
|
6d241e972b | ||
|
|
83632f15a9 | ||
|
|
bbb2393031 | ||
|
|
c31d7ef70a | ||
|
|
3666935c06 | ||
|
|
8e125b2953 | ||
|
|
026e7bff40 | ||
|
|
bf55d856d2 | ||
|
|
806acbdf12 | ||
|
|
fba2ab0996 | ||
|
|
529ced80f2 | ||
|
|
01fdfc4574 | ||
|
|
f6665edc73 | ||
|
|
c29f08c53e | ||
|
|
bf620363b9 | ||
|
|
f32e59d4b2 | ||
|
|
deb8cd458d | ||
|
|
7c95100180 | ||
|
|
079e5df740 | ||
|
|
2f11870970 | ||
|
|
11b96c214d | ||
|
|
cb604026d6 | ||
|
|
8020cd9994 | ||
|
|
70cc5d87af | ||
|
|
408b62bcc2 | ||
|
|
5a2de2108e | ||
|
|
c7691d8a40 | ||
|
|
f5b68b8950 | ||
|
|
260908cb06 | ||
|
|
79010b9e06 | ||
|
|
06410202d0 | ||
|
|
0c0d31e13a | ||
|
|
17b5870ca1 | ||
|
|
72c7fe5e56 | ||
|
|
a9db673cdf | ||
|
|
ab24a1e36d | ||
|
|
adea26bd8f | ||
|
|
b4cce8e240 | ||
|
|
c65844a7d0 | ||
|
|
994f613450 | ||
|
|
90911a423a | ||
|
|
314071d79f | ||
|
|
fe94bf7c1d | ||
|
|
78e199b5d7 | ||
|
|
a564744cd0 | ||
|
|
18dde0a0bd | ||
|
|
a11182ca84 | ||
|
|
70e17b5f8f | ||
|
|
c8e8cb86ce | ||
|
|
ba3700141f | ||
|
|
2eb5b751f3 | ||
|
|
28fd571d0c | ||
|
|
2c2e8317de | ||
|
|
4dec5ec5f9 | ||
|
|
79c2d22c25 | ||
|
|
8d5fc61c12 | ||
|
|
e023035393 | ||
|
|
c5c571f8ec | ||
|
|
0ef0e69f03 | ||
|
|
a0d252870c | ||
|
|
ef1e2d6fe0 | ||
|
|
83dc8cc13b | ||
|
|
a67c992c36 | ||
|
|
1647c12c73 | ||
|
|
c4942d931c | ||
|
|
2d15b8fe78 | ||
|
|
fa79b40946 | ||
|
|
91559191c9 | ||
|
|
832b5a36fa | ||
|
|
38ebf5ac9f | ||
|
|
6a59b37bea | ||
|
|
dee9aef975 | ||
|
|
6ff111a141 | ||
|
|
1b3cd01851 | ||
|
|
fa1a5f2a42 | ||
|
|
fc1469175b | ||
|
|
6ad0a22602 | ||
|
|
370d790776 | ||
|
|
1b8790aeb2 | ||
|
|
828545c128 | ||
|
|
fd6eeed5c4 | ||
|
|
6301582e77 | ||
|
|
0d5e98a201 | ||
|
|
4321db401c | ||
|
|
c7d1f95240 | ||
|
|
1eddb5cf98 | ||
|
|
b89fe86fa1 | ||
|
|
cb9ab213bb | ||
|
|
326e379154 | ||
|
|
8a15231475 | ||
|
|
886230f64f | ||
|
|
d907f43e6e | ||
|
|
d40cce92bf | ||
|
|
442ec7113e | ||
|
|
2660859434 | ||
|
|
6935addd38 | ||
|
|
2275625e1a | ||
|
|
61fac1bbc1 | ||
|
|
0a614217ce | ||
|
|
57cda797f3 | ||
|
|
b0f1b5f65b | ||
|
|
b621321ea0 | ||
|
|
066b92c7cd | ||
|
|
57ad506cde | ||
|
|
7f64dbc1ba | ||
|
|
e943cce125 | ||
|
|
ac03b81624 | ||
|
|
bb4979a82e | ||
|
|
0f1fcc3f4b | ||
|
|
562831ec1a | ||
|
|
45e78728bd | ||
|
|
ec44fb79d8 | ||
|
|
86fcdd0bae | ||
|
|
104fa96d4d | ||
|
|
8bb7525fe0 | ||
|
|
b7e245aba1 | ||
|
|
265aa3da29 | ||
|
|
5beadd90ee | ||
|
|
fd25f594cd | ||
|
|
01a9b32637 | ||
|
|
46ed623dad | ||
|
|
de30defb62 | ||
|
|
b0b31e67da | ||
|
|
8ea864d6eb | ||
|
|
8bf7ec0c21 | ||
|
|
4cfe5ecaa4 | ||
|
|
a798a40026 | ||
|
|
0f7c25fc63 | ||
|
|
2c8dc9e0bd | ||
|
|
322bde526c | ||
|
|
55c8aa7f1c | ||
|
|
322a303683 | ||
|
|
5f5322c64e | ||
|
|
bc10be3de6 | ||
|
|
fb4a8e9cb9 | ||
|
|
22fed0c798 | ||
|
|
94e825378c | ||
|
|
4a90056462 | ||
|
|
3deffa859d | ||
|
|
003a5a0160 | ||
|
|
72c63a10ee | ||
|
|
cc30f4c4fd | ||
|
|
438ac61ff7 | ||
|
|
b3edfd7d89 | ||
|
|
6dff60b899 | ||
|
|
93bee69266 | ||
|
|
c320da5ec8 | ||
|
|
560c0e72e6 | ||
|
|
2337237d58 | ||
|
|
ee57c95aa6 | ||
|
|
42ec7b317f | ||
|
|
6f076f7433 | ||
|
|
ef7947d176 | ||
|
|
595b0663b2 | ||
|
|
300c7a4b04 | ||
|
|
3b81312cf7 | ||
|
|
51db1efb8a | ||
|
|
aeeb2a259f | ||
|
|
fd4a0626c5 | ||
|
|
7c2303c758 | ||
|
|
b842a4b133 | ||
|
|
7c19ae302e | ||
|
|
8b2bffcf9e | ||
|
|
156a97b80d | ||
|
|
a0a5e4abb2 | ||
|
|
91173320e6 | ||
|
|
f087f8e205 | ||
|
|
7177e941eb | ||
|
|
3fbc3869dc | ||
|
|
cda13e5e79 | ||
|
|
022ffe69e0 | ||
|
|
5a5eb43359 | ||
|
|
5f461cd5cd | ||
|
|
850051463b | ||
|
|
ddec87224c | ||
|
|
d7b8cce162 | ||
|
|
83993fede8 | ||
|
|
d2653e8192 | ||
|
|
f068ed9ee7 | ||
|
|
e8735cc005 | ||
|
|
b160093b91 | ||
|
|
da0fd10423 | ||
|
|
2a161e1725 | ||
|
|
04855bc499 | ||
|
|
2b26206ea2 | ||
|
|
9488ef4867 | ||
|
|
e1c374de6e | ||
|
|
6feec2e2a5 | ||
|
|
211d7825d3 | ||
|
|
9d9d6ca20b | ||
|
|
73eb5af2cc | ||
|
|
8fa48d1c04 | ||
|
|
c4134c3516 | ||
|
|
136105e353 | ||
|
|
0fb6dc79d8 | ||
|
|
7a36322432 | ||
|
|
6a4d9309b2 | ||
|
|
9fc6b9dda2 | ||
|
|
2f3fcb9dbe | ||
|
|
ea97f43145 | ||
|
|
bb2715e7a5 | ||
|
|
2b24b26e59 | ||
|
|
640877ebf8 | ||
|
|
5a320222e2 | ||
|
|
e058d11657 | ||
|
|
874af5c982 | ||
|
|
56cdf94f95 | ||
|
|
fc34076c2b | ||
|
|
cc2cd95ec5 | ||
|
|
54a506c8eb | ||
|
|
d5dfb19508 | ||
|
|
fe7947da90 | ||
|
|
14f4108e55 | ||
|
|
6248aaf8dd | ||
|
|
0fd8513c80 | ||
|
|
aec3c3fb66 | ||
|
|
5d3692c16f | ||
|
|
5df0fd9dc8 | ||
|
|
ce8af7d499 | ||
|
|
c6bf39b283 | ||
|
|
f1fd457411 | ||
|
|
eae0674f61 | ||
|
|
0bb29e092d | ||
|
|
bbba9ff906 | ||
|
|
c2282ce4bd | ||
|
|
5354e804d0 | ||
|
|
bdae243552 | ||
|
|
8a69a09868 | ||
|
|
13877ce2c8 | ||
|
|
8acbfca06b | ||
|
|
cf6d36cb72 | ||
|
|
e79751c8d4 | ||
|
|
2c87dfef8a | ||
|
|
8f7a0ca90c | ||
|
|
3c76cc21ec | ||
|
|
9aa18d29a5 | ||
|
|
cc386f2345 | ||
|
|
72057bf7ef | ||
|
|
87d0175c76 | ||
|
|
3090550e53 | ||
|
|
f2b1b3f6b8 | ||
|
|
26f5390ac0 | ||
|
|
73ac019882 | ||
|
|
1cc5492784 | ||
|
|
fd8e330760 | ||
|
|
daf75dd375 | ||
|
|
4d078fdb03 | ||
|
|
86d023b02f | ||
|
|
c13d1e8ae6 | ||
|
|
82dd5fee12 | ||
|
|
428f10f9ee | ||
|
|
52e3d5e4f0 | ||
|
|
5b5c161601 | ||
|
|
811ae1a936 | ||
|
|
9c8952aef0 | ||
|
|
118da36b52 | ||
|
|
022b6973b2 | ||
|
|
7aa101ba8b | ||
|
|
dac584f7d6 | ||
|
|
48fe013549 | ||
|
|
f67c625e6a | ||
|
|
b280ea5579 | ||
|
|
7be30bb249 | ||
|
|
9b56ca3961 | ||
|
|
a2c3db666e | ||
|
|
5547df6073 | ||
|
|
28fc58067b | ||
|
|
a9709a635c | ||
|
|
ada884a129 | ||
|
|
3aba515bbc | ||
|
|
94ffd4bfc0 | ||
|
|
208374afa4 | ||
|
|
664e14b91f | ||
|
|
e1dcd79e48 | ||
|
|
1f29124d11 | ||
|
|
a08b4f780c | ||
|
|
6646ef71da | ||
|
|
3fd0ec99ae | ||
|
|
0a2dc1efb0 | ||
|
|
cdc5022305 | ||
|
|
5ba9f6a966 | ||
|
|
091ddb3c34 | ||
|
|
1b8b73ce71 | ||
|
|
82329124ff | ||
|
|
36c4519d7e | ||
|
|
c81dac774a | ||
|
|
1957eb9429 | ||
|
|
63d670c286 | ||
|
|
94e6be6cae | ||
|
|
f1c7df8c28 | ||
|
|
78ab97ab04 | ||
|
|
d355bf0267 | ||
|
|
2cecc6ec2c | ||
|
|
49cab41fdf | ||
|
|
b0a8d825b3 | ||
|
|
af60a2fdf6 | ||
|
|
b602714e06 | ||
|
|
013a28a527 | ||
|
|
d46aa92f0b | ||
|
|
55a7f6f0ce | ||
|
|
c67d1b62e3 | ||
|
|
e00b128a50 | ||
|
|
400fb79dc2 | ||
|
|
7c5b70d304 | ||
|
|
221b103721 | ||
|
|
c0dc2d0238 | ||
|
|
37a68aebcf | ||
|
|
a332930cdf | ||
|
|
e44b62d5a3 | ||
|
|
d76b0223d9 | ||
|
|
338a816ffd | ||
|
|
c1381ac598 | ||
|
|
51b7322a0f | ||
|
|
b90ff86f8c | ||
|
|
089428857c | ||
|
|
e07ea24610 | ||
|
|
2225cc9608 | ||
|
|
727cd68cee | ||
|
|
6d18bd0633 | ||
|
|
ee2c3607ad | ||
|
|
21ffcbddad | ||
|
|
21e5a2e071 | ||
|
|
4cd7d11391 | ||
|
|
cc98bd6b6d | ||
|
|
dd7e0f80fe | ||
|
|
1a64b9f0c2 | ||
|
|
4fcd178c36 | ||
|
|
152422af81 | ||
|
|
cf70267871 | ||
|
|
7733b87431 | ||
|
|
5e48dd9d45 | ||
|
|
39242c978f | ||
|
|
75a624434c | ||
|
|
7c4964fae6 | ||
|
|
9c65abd746 | ||
|
|
2579071b98 | ||
|
|
975964f9f0 | ||
|
|
bf2b4814e0 | ||
|
|
12a57ff1c2 | ||
|
|
94236bf4eb | ||
|
|
f9ee24f8f0 | ||
|
|
28b85762fd | ||
|
|
ff571f3b5d | ||
|
|
aa5c80f8a6 | ||
|
|
c44279bb10 | ||
|
|
569967ac21 | ||
|
|
f6a7e5ea23 | ||
|
|
8e9667d86c | ||
|
|
ce54fd334d | ||
|
|
1c6c75da4f | ||
|
|
9bc79f840e | ||
|
|
37a7df49d6 | ||
|
|
fcc82ebd35 | ||
|
|
c7a0b419a9 | ||
|
|
032b7c68d8 | ||
|
|
55e2dbdbc8 | ||
|
|
6d0ac6593c | ||
|
|
30f1d0991b | ||
|
|
7c5fcecbec | ||
|
|
eb7ccf8afa | ||
|
|
f3c00e96aa | ||
|
|
27cee90e5e | ||
|
|
f1587da480 | ||
|
|
6c26bb1cf8 | ||
|
|
e6695cf2ec | ||
|
|
a635f078c6 | ||
|
|
667c43398c | ||
|
|
cd407d1c3f | ||
|
|
6c9f3066fd | ||
|
|
7473b612c5 | ||
|
|
1340b17424 | ||
|
|
e38f511737 | ||
|
|
71ebd99dfa | ||
|
|
cfed9fa4b9 | ||
|
|
e7bb7dd78b | ||
|
|
f7d4437b3f | ||
|
|
8cc81509d7 | ||
|
|
c090dd2f81 | ||
|
|
47826a1262 | ||
|
|
89d909ab43 | ||
|
|
35a4a07320 | ||
|
|
ec35966715 | ||
|
|
9f7a8832a1 | ||
|
|
c6f4bbd143 | ||
|
|
53bdf22c85 | ||
|
|
717f55b012 | ||
|
|
f8e523b277 | ||
|
|
49c8c31220 | ||
|
|
284aca68c0 | ||
|
|
ca406637af | ||
|
|
a254f3d02c | ||
|
|
7a8a0f6b4b | ||
|
|
40ff17c9f9 | ||
|
|
354f872919 | ||
|
|
a19ddfc578 | ||
|
|
875706f660 | ||
|
|
59527165ec | ||
|
|
d06c79f5d3 | ||
|
|
d0c80b5b55 | ||
|
|
90a7b5ebce | ||
|
|
91f97ca02f | ||
|
|
1e2828b80e | ||
|
|
4cb41ac425 | ||
|
|
8a94d4fcf9 | ||
|
|
b180f18b7e | ||
|
|
82cbd4327f | ||
|
|
bb2fb93355 | ||
|
|
a10564c3b1 | ||
|
|
7cc3b877dc | ||
|
|
cd8278dceb | ||
|
|
06892775d4 | ||
|
|
43a9092c16 | ||
|
|
1727a9eca9 | ||
|
|
8b4a89c445 | ||
|
|
e606a74de3 | ||
|
|
858828d343 | ||
|
|
de1eae288c | ||
|
|
03d119d539 | ||
|
|
7acbbf2ef3 | ||
|
|
23bb3bd963 | ||
|
|
a0cac05555 | ||
|
|
3edb1eed8d | ||
|
|
ad2baccefa | ||
|
|
9e5c264012 | ||
|
|
d722008367 | ||
|
|
3dce1dd240 | ||
|
|
b05932310b | ||
|
|
97fb15ac49 | ||
|
|
dd45473356 | ||
|
|
558d36c1f3 | ||
|
|
311d730bce | ||
|
|
d706a30849 | ||
|
|
2b5bde4071 | ||
|
|
5a95aaaa54 | ||
|
|
cfd8ea8eb0 | ||
|
|
56735d4ff5 | ||
|
|
13473ee138 | ||
|
|
97e8800677 | ||
|
|
e20cf8687e | ||
|
|
6fc819dae1 | ||
|
|
d7a003b0bc | ||
|
|
eca0436f58 | ||
|
|
6b5e09478c | ||
|
|
0e5aaab0b5 | ||
|
|
41134f52d9 | ||
|
|
2131dc839a | ||
|
|
4c51c03779 | ||
|
|
dabd61bf80 | ||
|
|
6bfb122cd1 | ||
|
|
89f2eb1023 | ||
|
|
970f79e32f | ||
|
|
82f8914f9e | ||
|
|
65e8199a93 | ||
|
|
f8b8dc1494 | ||
|
|
cad8eed6e4 | ||
|
|
f0d08f4da1 | ||
|
|
4316949a1d | ||
|
|
7a01ff11cd | ||
|
|
c1439bb02b | ||
|
|
a14ebc80d2 | ||
|
|
5486a65702 | ||
|
|
52b1065b3b | ||
|
|
c1404ff2c1 | ||
|
|
c75dd93b92 | ||
|
|
3a45d541f3 | ||
|
|
200388ff96 | ||
|
|
9d570dc645 | ||
|
|
8fc5c6c862 | ||
|
|
1a649a6ac3 | ||
|
|
a7352e57d5 | ||
|
|
fbff355742 | ||
|
|
02693839ca | ||
|
|
894c96f39f | ||
|
|
171230e45d | ||
|
|
fc00a2ba32 | ||
|
|
a677c22e1f | ||
|
|
5f7c6ccfe4 | ||
|
|
22da843efa | ||
|
|
2e5cb930de | ||
|
|
cfd91a3b56 | ||
|
|
6a3d238b7e | ||
|
|
31206cfa0a | ||
|
|
95cbd69e48 | ||
|
|
f41cce96a3 | ||
|
|
c50a460ce6 | ||
|
|
642f5a84d4 | ||
|
|
9d1527b1df | ||
|
|
67f052a6e1 | ||
|
|
05fcec829e | ||
|
|
0abbedcdae | ||
|
|
6df2326a30 | ||
|
|
001275339b | ||
|
|
3d47a8a2fd | ||
|
|
887bc12350 | ||
|
|
9772777919 | ||
|
|
d323ce2c42 | ||
|
|
7c0c798c90 | ||
|
|
05dc04dacc | ||
|
|
0d7becff87 | ||
|
|
6fa4ec22c5 | ||
|
|
37eccbcd33 | ||
|
|
e3dfffb77b | ||
|
|
060b592fc8 | ||
|
|
cd30a4e2d4 | ||
|
|
c70150847d | ||
|
|
2e94a730cc | ||
|
|
a9cdd6614a | ||
|
|
0ad8815bbc | ||
|
|
d4969783d7 | ||
|
|
f5e1ee010b | ||
|
|
e24c0dda5d | ||
|
|
4b39d17e5f | ||
|
|
c1908147a9 | ||
|
|
6aebae5a98 | ||
|
|
714a793a0e | ||
|
|
94fce43ed9 | ||
|
|
c3f8f6bc42 | ||
|
|
97fcf7079b | ||
|
|
cb4c54eec1 | ||
|
|
9702898dcd | ||
|
|
97eb7f2c98 | ||
|
|
f9de29ed8c | ||
|
|
246f6318e4 | ||
|
|
d5ecbfc539 | ||
|
|
750c3d05aa | ||
|
|
dfc4dbdbd3 | ||
|
|
d58b366123 | ||
|
|
d90b600bc1 | ||
|
|
d3afb595dc | ||
|
|
639be7f7bc | ||
|
|
b6b7707dc3 | ||
|
|
624e09533c | ||
|
|
42938de973 | ||
|
|
e6d38cb64e | ||
|
|
524f56354c | ||
|
|
5e9da04ab7 | ||
|
|
f4ee48eaf4 | ||
|
|
d141d2445d | ||
|
|
b08d086b0f | ||
|
|
7e7634d344 | ||
|
|
ecefe41728 | ||
|
|
34cb9cf1fe | ||
|
|
76ef6e3ecc | ||
|
|
0f9f04e4ec | ||
|
|
aa25381651 | ||
|
|
5f71fbc6b3 | ||
|
|
ecd0f9d0e7 | ||
|
|
f2116c50c0 | ||
|
|
c15e09b71e | ||
|
|
f68cba0c71 | ||
|
|
80772c2419 | ||
|
|
b9bb4dfc06 | ||
|
|
719980a948 | ||
|
|
5684f8886f | ||
|
|
b552ad7065 | ||
|
|
1f2d229862 | ||
|
|
fa3d9d32ae | ||
|
|
e35b128fa3 | ||
|
|
6de49f515e | ||
|
|
007ea500d0 | ||
|
|
490b1e2532 | ||
|
|
8269a6dc37 | ||
|
|
78266db427 | ||
|
|
b0fe23072d | ||
|
|
a21e0c652c | ||
|
|
0b6293e2f5 | ||
|
|
9181db1304 | ||
|
|
dcece31519 | ||
|
|
aab6f27503 | ||
|
|
74cedd3255 | ||
|
|
d1061692d5 | ||
|
|
481c70311a | ||
|
|
4d234e3abc | ||
|
|
37a321a601 | ||
|
|
7c8be94a6e | ||
|
|
1c648f9714 | ||
|
|
fdc7c183e8 | ||
|
|
f80b328937 | ||
|
|
5a2f85600d | ||
|
|
7356be0164 | ||
|
|
a8e013dcb6 | ||
|
|
c3dec709ab | ||
|
|
6402b23041 | ||
|
|
1158d35021 | ||
|
|
e65815e34c | ||
|
|
021e383418 | ||
|
|
0291dc8214 | ||
|
|
ce755483ba | ||
|
|
de2981a767 | ||
|
|
41b9825f00 | ||
|
|
6f695b93d5 | ||
|
|
f2edd5d068 | ||
|
|
f0ef11b856 | ||
|
|
12066a60f3 | ||
|
|
4666879f94 | ||
|
|
fb55db665c | ||
|
|
7f50c3d08e | ||
|
|
461e33104e | ||
|
|
ed992ae6a1 | ||
|
|
b608152c41 | ||
|
|
5cf1ef7be0 | ||
|
|
6649a82776 | ||
|
|
0ac883c6d4 | ||
|
|
20a0508a16 | ||
|
|
42934a1006 | ||
|
|
3b8ddd0997 | ||
|
|
377e6c3210 | ||
|
|
61160ff9e5 | ||
|
|
9599615b23 | ||
|
|
6b80865bfe | ||
|
|
ed1c84445c | ||
|
|
f993888424 | ||
|
|
6f6f388f38 | ||
|
|
558ef7352d | ||
|
|
31d688ad3d | ||
|
|
84ce3a9ea1 | ||
|
|
792837bd71 | ||
|
|
e93c587b8e | ||
|
|
bb73a0e2cb | ||
|
|
243ab45111 | ||
|
|
71c3483f55 | ||
|
|
4b476f13bb | ||
|
|
2681e769a6 | ||
|
|
c2673aa970 | ||
|
|
f54c94d6c9 | ||
|
|
9aeb61181a | ||
|
|
1f8de33e75 | ||
|
|
9ed9885c8d | ||
|
|
e7181eb89c | ||
|
|
90dc897f71 | ||
|
|
8993a2c6ed | ||
|
|
704af29543 | ||
|
|
134872e9c1 | ||
|
|
e741bc0577 | ||
|
|
e62349cffb | ||
|
|
8664dd2139 | ||
|
|
ee67211035 | ||
|
|
582ef30b4a | ||
|
|
1b3568e66e | ||
|
|
3575dae75c | ||
|
|
673335de4b | ||
|
|
48dd8f96b7 | ||
|
|
72579f9bab | ||
|
|
5a81cfbbc6 | ||
|
|
c3bcb606a9 | ||
|
|
8e07e7483f | ||
|
|
e400585a0e | ||
|
|
e648662cfd | ||
|
|
2d90e763ad | ||
|
|
379bd79de4 | ||
|
|
e4d5ae53fc | ||
|
|
71795ecc62 | ||
|
|
685948bcaa | ||
|
|
dd2c2660b9 | ||
|
|
86af20ded0 | ||
|
|
9d090e00f2 | ||
|
|
e085c01a2e | ||
|
|
9c0e579bd3 | ||
|
|
06bf72da67 | ||
|
|
4673c67835 | ||
|
|
f685e389d3 | ||
|
|
94299f6cd8 | ||
|
|
2bf1131dab | ||
|
|
3cfe66e4c3 | ||
|
|
0d12fc3033 | ||
|
|
30405a3441 | ||
|
|
e79b18762e | ||
|
|
83f01096c0 | ||
|
|
5d2452608d | ||
|
|
50a5a69c46 | ||
|
|
1882b88c78 | ||
|
|
3fea581ec8 | ||
|
|
c8ef15cf40 | ||
|
|
e3bb3c3906 | ||
|
|
d88fa8b787 | ||
|
|
068f0cce96 | ||
|
|
cf36fdecbf | ||
|
|
a9dcce82ed | ||
|
|
5f48f91d94 | ||
|
|
15503a3b9e | ||
|
|
5c15d263e0 | ||
|
|
cde0c1d418 | ||
|
|
44c66fc284 | ||
|
|
3885674877 | ||
|
|
0937b84b01 | ||
|
|
51f89048d6 | ||
|
|
134d3f98c9 | ||
|
|
ba24920fec | ||
|
|
569b87ff83 | ||
|
|
8c138e74be | ||
|
|
2f4fd3324b | ||
|
|
69e7afee26 | ||
|
|
fdab98aa59 | ||
|
|
35a512310a | ||
|
|
3b2a494033 | ||
|
|
b0820e4886 | ||
|
|
4ab7b2d2b1 | ||
|
|
c31bf8474c | ||
|
|
cc6bcb6c81 | ||
|
|
65ee977a86 | ||
|
|
f170914def | ||
|
|
ea9d33374f | ||
|
|
7f664aa18c | ||
|
|
1413f22095 | ||
|
|
a3e33a313a | ||
|
|
411da169ac | ||
|
|
78468098c5 | ||
|
|
9000bd6679 | ||
|
|
413fdc6f0d | ||
|
|
9c7854aef6 | ||
|
|
bf862d1d07 | ||
|
|
8bbe28e998 | ||
|
|
702f1631a3 | ||
|
|
eea4e60b73 | ||
|
|
5a4c2fb61d | ||
|
|
498f5d65fd | ||
|
|
3b3e69f8b2 | ||
|
|
503b0ba1b1 | ||
|
|
bc34ca9e25 | ||
|
|
7d4ff3b061 | ||
|
|
8a1884c407 | ||
|
|
e7f175d578 | ||
|
|
4c7b48e596 | ||
|
|
1681ee35db | ||
|
|
7b8890a4c9 | ||
|
|
2eaa6d0874 | ||
|
|
cad3d694ab | ||
|
|
e73326a324 | ||
|
|
90bd1fd7e9 | ||
|
|
ca42325ade | ||
|
|
7516b059fe | ||
|
|
d8f16f4116 | ||
|
|
26a071ea00 | ||
|
|
7dec3c9320 | ||
|
|
731240e0e9 | ||
|
|
a5a068b2ee | ||
|
|
2435ffaf09 | ||
|
|
795447f61a | ||
|
|
a3d4d461a3 | ||
|
|
3635872f37 | ||
|
|
199cf31b9e | ||
|
|
dc29b3add1 | ||
|
|
642dc96956 | ||
|
|
e9808d138f | ||
|
|
b530d70a7b | ||
|
|
1005a63130 | ||
|
|
52c0864cb8 | ||
|
|
3a55e5b384 | ||
|
|
847cf17b77 | ||
|
|
e9de194b89 | ||
|
|
e76d5bc7cf | ||
|
|
6d82966ebe | ||
|
|
efeabfe3ef | ||
|
|
738b10adea | ||
|
|
dfa1dc43df | ||
|
|
bf491de9fe | ||
|
|
2abc69780e | ||
|
|
1db05a2655 | ||
|
|
b05d818f45 | ||
|
|
837a2d4bbd | ||
|
|
35cbe9d140 | ||
|
|
b722150d87 | ||
|
|
5336b4a89c | ||
|
|
e84d7c0cda | ||
|
|
53229e3d6c | ||
|
|
fdd66bd76d | ||
|
|
ccf30e0934 | ||
|
|
25f04d5b03 | ||
|
|
f7786a9e48 | ||
|
|
cc608a3fb0 | ||
|
|
da9f12d1e2 | ||
|
|
35cc197d0b | ||
|
|
18362eb948 | ||
|
|
3948323a8c | ||
|
|
7e3b690257 | ||
|
|
b9ab2fe0fb | ||
|
|
81c23b84e7 | ||
|
|
b25175a19a | ||
|
|
39e0433570 | ||
|
|
9d05c59600 | ||
|
|
2fcf2c81bf | ||
|
|
9fec1a3cb4 | ||
|
|
b7b40d9c3a | ||
|
|
653ceb9860 | ||
|
|
0e5b6f9300 | ||
|
|
31eb5e26e3 | ||
|
|
12b37c7386 | ||
|
|
7cad5d0cd2 | ||
|
|
e6bad6e183 | ||
|
|
f5d207f8f0 | ||
|
|
da7fc54e37 | ||
|
|
0ec2eba2a3 | ||
|
|
dcb369ee46 | ||
|
|
041b32b01f | ||
|
|
cdab073614 | ||
|
|
fbd5e4c2b3 | ||
|
|
5eb0a89579 | ||
|
|
9fa08fdbc0 | ||
|
|
6f00e4a014 | ||
|
|
f52f752acd | ||
|
|
d846c9006e | ||
|
|
69ca6ccdc1 | ||
|
|
25d966110e | ||
|
|
e03f7baa60 | ||
|
|
62635f43f4 | ||
|
|
248d572077 | ||
|
|
60f69ad77b | ||
|
|
b02edd014a | ||
|
|
024f84f1be | ||
|
|
5d870837cf | ||
|
|
de576fa82e | ||
|
|
412b9e9ad8 | ||
|
|
8f78bd3307 | ||
|
|
91a339b625 | ||
|
|
1a9b056e93 | ||
|
|
abc6003640 | ||
|
|
76683c0af5 | ||
|
|
128cb7f5b2 | ||
|
|
8c0c1e4ded | ||
|
|
e59f788c43 | ||
|
|
8d6c7955ad | ||
|
|
233679865b | ||
|
|
6a61ec7763 | ||
|
|
1b866e20c6 | ||
|
|
75c17cf846 | ||
|
|
8250dbd172 | ||
|
|
0d83b69fe2 | ||
|
|
a6412d0690 | ||
|
|
dda64bd652 | ||
|
|
9d6db65c7c | ||
|
|
5783ce0b3c | ||
|
|
8ef705ad10 | ||
|
|
381cf55434 | ||
|
|
15ce235eed | ||
|
|
3be92f550c | ||
|
|
366638b1b9 | ||
|
|
fa6510a90c | ||
|
|
816a96c2cc | ||
|
|
c87fc2426d | ||
|
|
c611eb061d | ||
|
|
aa3eafcea1 | ||
|
|
66fab65a1a | ||
|
|
a25b49a127 | ||
|
|
a3124e8873 | ||
|
|
bffb31c337 | ||
|
|
44e7282b4b | ||
|
|
c2aa312e0c | ||
|
|
384b03d49b | ||
|
|
6650a06339 | ||
|
|
c256a43139 | ||
|
|
0d9a157914 | ||
|
|
47950f7b97 | ||
|
|
f9c48e1fb0 | ||
|
|
973647eaa2 | ||
|
|
3bda63c350 | ||
|
|
88b887fe47 | ||
|
|
58e15c7755 | ||
|
|
7365a45948 | ||
|
|
e8a57376f0 | ||
|
|
8e51659237 | ||
|
|
c403968230 | ||
|
|
9d4c68d272 | ||
|
|
8268afdf33 | ||
|
|
975e6e6194 | ||
|
|
99d9e262eb | ||
|
|
037ee0cff3 | ||
|
|
91ee99ab8a | ||
|
|
64fc523977 | ||
|
|
b869471068 | ||
|
|
322f7dadc7 | ||
|
|
191463397b | ||
|
|
683e02fbcd | ||
|
|
ebbecce56d | ||
|
|
e98637596d | ||
|
|
3c66e810c0 | ||
|
|
20ca6b4a55 | ||
|
|
69b0a358f3 | ||
|
|
8dd44f66ca | ||
|
|
eeb5845aac | ||
|
|
fe4762588c | ||
|
|
c3362c7617 | ||
|
|
ffd607bb52 | ||
|
|
d7360e3203 | ||
|
|
879d21c80e | ||
|
|
3623cf9729 | ||
|
|
8d219e94dc | ||
|
|
d552af97c3 | ||
|
|
fc7e50dce2 | ||
|
|
bdc0cd4418 | ||
|
|
cdcd031192 | ||
|
|
a38fb5df41 | ||
|
|
66c0d6620b | ||
|
|
29b03fc242 | ||
|
|
e0b77db46f | ||
|
|
f0d9b93ede | ||
|
|
f398b5d843 | ||
|
|
b8259a82c1 | ||
|
|
7bcea57241 | ||
|
|
3cd6c2e9eb | ||
|
|
455a61d210 | ||
|
|
83e94f3de1 | ||
|
|
ffdd6ab821 | ||
|
|
60fe728c0f | ||
|
|
b209620514 | ||
|
|
e5f4916e31 | ||
|
|
5212b98c87 | ||
|
|
88fa343387 | ||
|
|
40bd3336a5 | ||
|
|
bf92fa88b7 | ||
|
|
6ea2755095 | ||
|
|
f047bb61bb | ||
|
|
747495e77c | ||
|
|
159a25d8e7 | ||
|
|
c8cc021ea1 | ||
|
|
7d9c1a80f0 | ||
|
|
ff8f439afd | ||
|
|
fd0e7dc4ab | ||
|
|
ed909cd54c | ||
|
|
ad0fd82566 | ||
|
|
d2b9766886 | ||
|
|
f56ec818fb | ||
|
|
11a1b824c0 | ||
|
|
db542f2a26 | ||
|
|
eb109cf905 | ||
|
|
7197368c6d | ||
|
|
400d6c3de5 | ||
|
|
c78a6fa7d4 | ||
|
|
6b7e73db92 | ||
|
|
70092b493e | ||
|
|
912307386c | ||
|
|
03b4f57d23 | ||
|
|
b5e5de626c | ||
|
|
8155da152f | ||
|
|
1dbaec0edd | ||
|
|
fa483e1fe0 | ||
|
|
4dbe051494 | ||
|
|
3a7a6efffb | ||
|
|
2d26eebca8 | ||
|
|
a259d10bcb | ||
|
|
0a48af9ff7 | ||
|
|
d55c3c5030 | ||
|
|
ab62755a88 | ||
|
|
bd20bde1a2 | ||
|
|
d9bfe6a49d | ||
|
|
8a31e2d9c0 | ||
|
|
a1efa28520 | ||
|
|
e75f2aa087 | ||
|
|
4ad6ecd196 | ||
|
|
ea07d4c6c8 | ||
|
|
0df2d882ea | ||
|
|
553326b006 | ||
|
|
309887c444 | ||
|
|
38834cb997 | ||
|
|
16270fa080 | ||
|
|
e719eab878 | ||
|
|
26520c5cf4 | ||
|
|
a3dcf8ced6 | ||
|
|
5e70868fd0 | ||
|
|
e859228db1 | ||
|
|
9398494100 | ||
|
|
21cda4e7fc | ||
|
|
b7387da085 | ||
|
|
8ca005eb41 | ||
|
|
f5e34deb1a | ||
|
|
b41635e809 | ||
|
|
24d31e2046 | ||
|
|
7160054927 | ||
|
|
b6c353ee80 | ||
|
|
67d9eaa215 | ||
|
|
ebcf4c0224 | ||
|
|
656e403f01 | ||
|
|
41cd6d13c9 | ||
|
|
7b9926807d | ||
|
|
cc4e2fcd94 | ||
|
|
cad1fa50a9 | ||
|
|
0586822808 | ||
|
|
f310222ce1 | ||
|
|
ad207eeabb | ||
|
|
1696237a3f | ||
|
|
269be86998 | ||
|
|
047a8de934 | ||
|
|
39fae3a480 | ||
|
|
40da835cbb | ||
|
|
38aba07290 | ||
|
|
a636fad51e | ||
|
|
d0db7bfb58 | ||
|
|
8d537ee2b6 | ||
|
|
3387f33a8e | ||
|
|
1116a36c15 | ||
|
|
bcf87fd3c9 | ||
|
|
753d5675dd | ||
|
|
be2934d9b5 | ||
|
|
4a1d11b2be | ||
|
|
b1f7cfa9da | ||
|
|
cc9d222923 | ||
|
|
c5b39126ee | ||
|
|
12f4e9b7ea | ||
|
|
742923c73d | ||
|
|
980036b78a | ||
|
|
1387d3969e | ||
|
|
5d6921ff2a | ||
|
|
cbb5004ff9 | ||
|
|
9145a08395 | ||
|
|
3d713baa4c | ||
|
|
14c851e9f8 | ||
|
|
e6db1875d0 | ||
|
|
8e056672bc | ||
|
|
6f574c3802 | ||
|
|
a5c4a2c7c6 | ||
|
|
bfd5f5d221 | ||
|
|
94044b2950 | ||
|
|
51a55810b9 | ||
|
|
1884b9a235 | ||
|
|
730acd59c7 | ||
|
|
c79aecf64d | ||
|
|
f033e23ea3 | ||
|
|
3d219b4be6 | ||
|
|
d950fe3736 | ||
|
|
9cc90ac7d5 | ||
|
|
94dec0ff85 | ||
|
|
c9fa29ef64 | ||
|
|
213ac43721 | ||
|
|
d0bf1a842f | ||
|
|
2d3af6fc38 | ||
|
|
ace550d6b2 | ||
|
|
ac5be7dad7 | ||
|
|
bdfbef41c6 | ||
|
|
e2e1faa225 | ||
|
|
78ab726ec7 | ||
|
|
caa5ea0316 | ||
|
|
a20e02ee23 | ||
|
|
6ac926aa32 | ||
|
|
4cada31f80 | ||
|
|
ff65b7dae1 |
@@ -1,80 +1,147 @@
|
|||||||
|
build-steps: &build-steps
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: Install Node.js 10 on MacOS
|
||||||
|
command: |
|
||||||
|
if [ "$INSTALL_MACOS_NODE" == "true" ]; then
|
||||||
|
echo 'Installing Node.js 10 for MacOS'
|
||||||
|
brew update
|
||||||
|
brew install node@10
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Check for release
|
||||||
|
command: |
|
||||||
|
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
||||||
|
echo 'release build triggered from api'
|
||||||
|
echo 'export ELECTRON_RELEASE=1 UPLOAD_TO_S3=1' >> $BASH_ENV
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Bootstrap
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||||
|
echo "Bootstrapping Electron for release build for $TARGET_ARCH"
|
||||||
|
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||||
|
else
|
||||||
|
echo "Bootstrapping Electron for debug build for $TARGET_ARCH"
|
||||||
|
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Lint
|
||||||
|
command: npm run lint
|
||||||
|
- run:
|
||||||
|
name: Build
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||||
|
echo 'Building Electron for release'
|
||||||
|
script/build.py -c R
|
||||||
|
else
|
||||||
|
echo 'Building Electron for debug'
|
||||||
|
script/build.py -c D
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Create distribution
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||||
|
echo 'Creating Electron release distribution'
|
||||||
|
script/create-dist.py
|
||||||
|
else
|
||||||
|
echo 'Skipping create distribution because build is not for release'
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Upload distribution
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$UPLOAD_TO_S3" != "1" ]; then
|
||||||
|
echo 'Uploading Electron release distribution to github releases'
|
||||||
|
script/upload.py
|
||||||
|
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$UPLOAD_TO_S3" == "1" ]; then
|
||||||
|
echo 'Uploading Electron release distribution to s3'
|
||||||
|
script/upload.py --upload_to_s3
|
||||||
|
else
|
||||||
|
echo 'Skipping upload distribution because build is not for release'
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Setup for headless testing
|
||||||
|
command: |
|
||||||
|
if [ "$RUN_HEADLESS_TESTS" == "true" ]; then
|
||||||
|
echo 'Setup for headless testing'
|
||||||
|
sh -e /etc/init.d/xvfb start
|
||||||
|
else
|
||||||
|
echo 'Headless testing not needed'
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Test
|
||||||
|
environment:
|
||||||
|
MOCHA_FILE: junit/test-results.xml
|
||||||
|
MOCHA_REPORTER: mocha-junit-reporter
|
||||||
|
command: |
|
||||||
|
if [ "$RUN_TESTS" == "true" ]; then
|
||||||
|
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||||
|
echo 'Testing Electron debug build'
|
||||||
|
mkdir junit
|
||||||
|
script/test.py --ci --rebuild_native_modules
|
||||||
|
else
|
||||||
|
if [ "$UPLOAD_TO_S3" == "1" ]; then
|
||||||
|
echo 'Testing Electron release build'
|
||||||
|
mkdir junit
|
||||||
|
script/test.py --ci --rebuild_native_modules -c R
|
||||||
|
else
|
||||||
|
echo 'Skipping tests on GitHub release'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo 'Skipping tests due to configuration'
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Verify FFmpeg
|
||||||
|
command: |
|
||||||
|
if [ "$RUN_TESTS" == "true" ]; then
|
||||||
|
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||||
|
echo 'Verifying ffmpeg on debug build'
|
||||||
|
script/verify-ffmpeg.py
|
||||||
|
else
|
||||||
|
echo 'Verifying ffmpeg on release build'
|
||||||
|
script/verify-ffmpeg.py -R
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo 'Skipping tests due to configuration'
|
||||||
|
fi
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Generate Typescript Definitions
|
||||||
|
command: |
|
||||||
|
if [ "$CREATE_TYPESCRIPT_DEFS" == "true" ]; then
|
||||||
|
npm run create-typescript-definitions
|
||||||
|
fi
|
||||||
|
- persist_to_workspace:
|
||||||
|
root: out
|
||||||
|
paths:
|
||||||
|
- "*"
|
||||||
|
- store_test_results:
|
||||||
|
path: junit
|
||||||
|
- store_artifacts:
|
||||||
|
path: junit
|
||||||
|
- store_artifacts:
|
||||||
|
path: out
|
||||||
|
|
||||||
|
build-defaults: &build-defaults
|
||||||
|
docker:
|
||||||
|
- image: electronbuilds/electron:0.0.8
|
||||||
|
<<: *build-steps
|
||||||
|
|
||||||
version: 2
|
version: 2
|
||||||
jobs:
|
jobs:
|
||||||
electron-linux-arm:
|
electron-linux-arm:
|
||||||
docker:
|
environment:
|
||||||
- image: electronbuilds/electron:0.0.4
|
TARGET_ARCH: arm
|
||||||
environment:
|
<<: *build-defaults
|
||||||
TARGET_ARCH: arm
|
|
||||||
resource_class: 2xlarge
|
resource_class: 2xlarge
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- run:
|
|
||||||
name: Check for release
|
|
||||||
command: |
|
|
||||||
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
|
||||||
echo 'release build triggered from api'
|
|
||||||
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Bootstrap
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
|
||||||
echo 'Bootstrapping Electron for release build'
|
|
||||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
|
||||||
else
|
|
||||||
echo 'Bootstrapping Electron for debug build'
|
|
||||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
|
||||||
fi
|
|
||||||
- run: npm run lint
|
|
||||||
- run:
|
|
||||||
name: Build
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
|
||||||
echo 'Building Electron for release'
|
|
||||||
script/build.py -c R
|
|
||||||
else
|
|
||||||
echo 'Building Electron for debug'
|
|
||||||
script/build.py -c D
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Create distribution
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
|
||||||
echo 'Creating Electron release distribution'
|
|
||||||
script/create-dist.py
|
|
||||||
else
|
|
||||||
echo 'Skipping create distribution because build is not for release'
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Upload distribution
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
|
|
||||||
echo 'Uploading Electron release distribution to github releases'
|
|
||||||
script/upload.py
|
|
||||||
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
|
|
||||||
echo 'Uploading Electron release distribution to s3'
|
|
||||||
script/upload.py --upload_to_s3
|
|
||||||
else
|
|
||||||
echo 'Skipping upload distribution because build is not for release'
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Zip out directory
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
|
||||||
zip -r electron.zip out/D
|
|
||||||
fi
|
|
||||||
- persist_to_workspace:
|
|
||||||
root: /home/builduser
|
|
||||||
paths:
|
|
||||||
- project/out
|
|
||||||
- store_artifacts:
|
|
||||||
path: electron.zip
|
|
||||||
electron-linux-arm-test:
|
electron-linux-arm-test:
|
||||||
machine: true
|
machine: true
|
||||||
steps:
|
steps:
|
||||||
- attach_workspace:
|
- attach_workspace:
|
||||||
at: /tmp/workspace
|
at: /tmp/workspace/project/out
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
name: Test in ARM docker container
|
name: Test in ARM docker container
|
||||||
@@ -83,7 +150,7 @@ jobs:
|
|||||||
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||||
docker run -it \
|
docker run -it \
|
||||||
--mount type=bind,source=/tmp/workspace,target=/tmp/workspace \
|
--mount type=bind,source=/tmp/workspace,target=/tmp/workspace \
|
||||||
--rm electronbuilds/electronarm7:0.0.4 > version.txt
|
--rm electronbuilds/electronarm7:0.0.5 > version.txt
|
||||||
cat version.txt
|
cat version.txt
|
||||||
if grep -q `script/get-version.py` version.txt; then
|
if grep -q `script/get-version.py` version.txt; then
|
||||||
echo "Versions match"
|
echo "Versions match"
|
||||||
@@ -94,80 +161,25 @@ jobs:
|
|||||||
else
|
else
|
||||||
echo "Skipping test for release build"
|
echo "Skipping test for release build"
|
||||||
fi
|
fi
|
||||||
electron-linux-arm64:
|
|
||||||
docker:
|
electron-linux-arm-release-nightly:
|
||||||
- image: electronbuilds/electron:0.0.4
|
environment:
|
||||||
environment:
|
TARGET_ARCH: arm
|
||||||
TARGET_ARCH: arm64
|
RUN_RELEASE_BUILD: true
|
||||||
|
<<: *build-defaults
|
||||||
resource_class: 2xlarge
|
resource_class: 2xlarge
|
||||||
steps:
|
|
||||||
- checkout
|
electron-linux-arm64:
|
||||||
- run:
|
environment:
|
||||||
name: Check for release
|
TARGET_ARCH: arm64
|
||||||
command: |
|
<<: *build-defaults
|
||||||
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
resource_class: 2xlarge
|
||||||
echo 'release build triggered from api'
|
|
||||||
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Bootstrap
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
|
||||||
echo 'Bootstrapping Electron for release build'
|
|
||||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
|
||||||
else
|
|
||||||
echo 'Bootstrapping Electron for debug build'
|
|
||||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
|
||||||
fi
|
|
||||||
- run: npm run lint
|
|
||||||
- run:
|
|
||||||
name: Build
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
|
||||||
echo 'Building Electron for release'
|
|
||||||
script/build.py -c R
|
|
||||||
else
|
|
||||||
echo 'Building Electron for debug'
|
|
||||||
script/build.py -c D
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Create distribution
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
|
||||||
echo 'Creating Electron release distribution'
|
|
||||||
script/create-dist.py
|
|
||||||
else
|
|
||||||
echo 'Skipping create distribution because build is not for release'
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Upload distribution
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
|
|
||||||
echo 'Uploading Electron release distribution to github releases'
|
|
||||||
script/upload.py
|
|
||||||
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
|
|
||||||
echo 'Uploading Electron release distribution to s3'
|
|
||||||
script/upload.py --upload_to_s3
|
|
||||||
else
|
|
||||||
echo 'Skipping upload distribution because build is not for release'
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Zip out directory
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
|
||||||
zip -r electron.zip out/D
|
|
||||||
fi
|
|
||||||
- persist_to_workspace:
|
|
||||||
root: /home/builduser
|
|
||||||
paths:
|
|
||||||
- project/out
|
|
||||||
- store_artifacts:
|
|
||||||
path: electron.zip
|
|
||||||
electron-linux-arm64-test:
|
electron-linux-arm64-test:
|
||||||
machine: true
|
machine: true
|
||||||
steps:
|
steps:
|
||||||
- attach_workspace:
|
- attach_workspace:
|
||||||
at: /tmp/workspace
|
at: /tmp/workspace/project/out
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
name: Test in ARM64 docker container
|
name: Test in ARM64 docker container
|
||||||
@@ -176,7 +188,7 @@ jobs:
|
|||||||
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||||
docker run -it \
|
docker run -it \
|
||||||
--mount type=bind,source=/tmp/workspace,target=/tmp/workspace \
|
--mount type=bind,source=/tmp/workspace,target=/tmp/workspace \
|
||||||
--rm electronbuilds/electronarm64:0.0.5 > version.txt
|
--rm electronbuilds/electronarm64:0.0.6 > version.txt
|
||||||
cat version.txt
|
cat version.txt
|
||||||
if grep -q `script/get-version.py` version.txt; then
|
if grep -q `script/get-version.py` version.txt; then
|
||||||
echo "Versions match"
|
echo "Versions match"
|
||||||
@@ -187,242 +199,91 @@ jobs:
|
|||||||
else
|
else
|
||||||
echo "Skipping test for release build"
|
echo "Skipping test for release build"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
electron-linux-arm64-release-nightly:
|
||||||
|
environment:
|
||||||
|
TARGET_ARCH: arm64
|
||||||
|
RUN_RELEASE_BUILD: true
|
||||||
|
<<: *build-defaults
|
||||||
|
resource_class: 2xlarge
|
||||||
|
|
||||||
electron-linux-ia32:
|
electron-linux-ia32:
|
||||||
docker:
|
environment:
|
||||||
- image: electronbuilds/electron:0.0.4
|
TARGET_ARCH: ia32
|
||||||
environment:
|
DISPLAY: ':99.0'
|
||||||
TARGET_ARCH: ia32
|
RUN_TESTS: true
|
||||||
DISPLAY: ':99.0'
|
RUN_HEADLESS_TESTS: true
|
||||||
|
<<: *build-defaults
|
||||||
resource_class: xlarge
|
resource_class: xlarge
|
||||||
steps:
|
|
||||||
- checkout
|
electron-linux-ia32-release-nightly:
|
||||||
- run:
|
environment:
|
||||||
name: Setup for headless testing
|
TARGET_ARCH: ia32
|
||||||
command: sh -e /etc/init.d/xvfb start
|
RUN_RELEASE_BUILD: true
|
||||||
- run:
|
<<: *build-defaults
|
||||||
name: Check for release
|
resource_class: xlarge
|
||||||
command: |
|
|
||||||
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
|
||||||
echo 'release build triggered from api'
|
|
||||||
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Bootstrap
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
|
||||||
echo 'Bootstrapping Electron for release build'
|
|
||||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
|
||||||
else
|
|
||||||
echo 'Bootstrapping Electron for debug build'
|
|
||||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
|
||||||
fi
|
|
||||||
- run: npm run lint
|
|
||||||
- run:
|
|
||||||
name: Build
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
|
||||||
echo 'Building Electron for release'
|
|
||||||
script/build.py -c R
|
|
||||||
else
|
|
||||||
echo 'Building Electron for debug'
|
|
||||||
script/build.py -c D
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Create distribution
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
|
||||||
echo 'Creating Electron release distribution'
|
|
||||||
script/create-dist.py
|
|
||||||
else
|
|
||||||
echo 'Skipping create distribution because build is not for release'
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Upload distribution
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
|
|
||||||
echo 'Uploading Electron release distribution to github releases'
|
|
||||||
script/upload.py
|
|
||||||
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
|
|
||||||
echo 'Uploading Electron release distribution to s3'
|
|
||||||
script/upload.py --upload_to_s3
|
|
||||||
else
|
|
||||||
echo 'Skipping upload distribution because build is not for release'
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Test
|
|
||||||
environment:
|
|
||||||
MOCHA_FILE: junit/test-results.xml
|
|
||||||
MOCHA_REPORTER: mocha-junit-reporter
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
|
||||||
echo 'Testing Electron debug build'
|
|
||||||
out/D/electron --version
|
|
||||||
mkdir junit
|
|
||||||
script/test.py --ci --rebuild_native_modules
|
|
||||||
else
|
|
||||||
echo 'Skipping testing on release build'
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Verify FFmpeg
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
|
||||||
echo 'Verifying ffmpeg on debug build'
|
|
||||||
script/verify-ffmpeg.py
|
|
||||||
else
|
|
||||||
echo 'Skipping verify ffmpeg on release build'
|
|
||||||
fi
|
|
||||||
electron-linux-mips64el:
|
electron-linux-mips64el:
|
||||||
docker:
|
environment:
|
||||||
- image: electronbuilds/electron:0.0.4
|
TARGET_ARCH: mips64el
|
||||||
environment:
|
<<: *build-defaults
|
||||||
TARGET_ARCH: mips64el
|
|
||||||
resource_class: xlarge
|
resource_class: xlarge
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- run:
|
|
||||||
name: Check for release
|
|
||||||
command: |
|
|
||||||
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
|
||||||
echo 'release build triggered from api'
|
|
||||||
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Bootstrap
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
|
||||||
echo 'Bootstrapping Electron for release build'
|
|
||||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
|
||||||
else
|
|
||||||
echo 'Bootstrapping Electron for debug build'
|
|
||||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
|
||||||
fi
|
|
||||||
- run: npm run lint
|
|
||||||
- run:
|
|
||||||
name: Build
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
|
||||||
echo 'Building Electron for release'
|
|
||||||
script/build.py -c R
|
|
||||||
else
|
|
||||||
echo 'Building Electron for debug'
|
|
||||||
script/build.py -c D
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Create distribution
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
|
||||||
echo 'Creating Electron release distribution'
|
|
||||||
script/create-dist.py
|
|
||||||
else
|
|
||||||
echo 'Skipping create distribution because build is not for release'
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Upload distribution
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
|
|
||||||
echo 'Uploading Electron release distribution to github releases'
|
|
||||||
script/upload.py
|
|
||||||
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
|
|
||||||
echo 'Uploading Electron release distribution to s3'
|
|
||||||
script/upload.py --upload_to_s3
|
|
||||||
else
|
|
||||||
echo 'Skipping upload distribution because build is not for release'
|
|
||||||
fi
|
|
||||||
|
|
||||||
electron-linux-x64:
|
electron-linux-x64:
|
||||||
docker:
|
environment:
|
||||||
- image: electronbuilds/electron:0.0.4
|
TARGET_ARCH: x64
|
||||||
environment:
|
DISPLAY: ':99.0'
|
||||||
TARGET_ARCH: x64
|
RUN_TESTS: true
|
||||||
DISPLAY: ':99.0'
|
RUN_HEADLESS_TESTS: true
|
||||||
|
CREATE_TYPESCRIPT_DEFS: true
|
||||||
|
<<: *build-defaults
|
||||||
resource_class: xlarge
|
resource_class: xlarge
|
||||||
steps:
|
|
||||||
- checkout
|
electron-linux-x64-release-nightly:
|
||||||
- run:
|
environment:
|
||||||
name: Setup for headless testing
|
TARGET_ARCH: x64
|
||||||
command: sh -e /etc/init.d/xvfb start
|
RUN_RELEASE_BUILD: true
|
||||||
- run:
|
<<: *build-defaults
|
||||||
name: Check for release
|
resource_class: xlarge
|
||||||
command: |
|
|
||||||
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
electron-osx-x64:
|
||||||
echo 'release build triggered from api'
|
environment:
|
||||||
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
TARGET_ARCH: x64
|
||||||
fi
|
RUN_TESTS: true
|
||||||
- run:
|
INSTALL_MACOS_NODE: true
|
||||||
name: Bootstrap
|
macos:
|
||||||
command: |
|
xcode: "8.3.3"
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
<<: *build-steps
|
||||||
echo 'Bootstrapping Electron for release build'
|
|
||||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
electron-osx-x64-release-nightly:
|
||||||
else
|
environment:
|
||||||
echo 'Bootstrapping Electron for debug build'
|
TARGET_ARCH: x64
|
||||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
RUN_RELEASE_BUILD: true
|
||||||
fi
|
INSTALL_MACOS_NODE: true
|
||||||
- run: npm run lint
|
macos:
|
||||||
- run:
|
xcode: "8.3.3"
|
||||||
name: Build
|
<<: *build-steps
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
electron-mas-x64:
|
||||||
echo 'Building Electron for release'
|
environment:
|
||||||
script/build.py -c R
|
TARGET_ARCH: x64
|
||||||
else
|
MAS_BUILD: 1
|
||||||
echo 'Building Electron for debug'
|
RUN_TESTS: true
|
||||||
script/build.py -c D
|
INSTALL_MACOS_NODE: true
|
||||||
fi
|
macos:
|
||||||
- run:
|
xcode: "8.3.3"
|
||||||
name: Create distribution
|
<<: *build-steps
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
electron-mas-x64-release-nightly:
|
||||||
echo 'Creating Electron release distribution'
|
environment:
|
||||||
script/create-dist.py
|
TARGET_ARCH: x64
|
||||||
else
|
MAS_BUILD: 1
|
||||||
echo 'Skipping create distribution because build is not for release'
|
RUN_RELEASE_BUILD: true
|
||||||
fi
|
INSTALL_MACOS_NODE: true
|
||||||
- run:
|
macos:
|
||||||
name: Upload distribution
|
xcode: "8.3.3"
|
||||||
command: |
|
<<: *build-steps
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
|
|
||||||
echo 'Uploading Electron release distribution to github releases'
|
|
||||||
script/upload.py
|
|
||||||
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
|
|
||||||
echo 'Uploading Electron release distribution to s3'
|
|
||||||
script/upload.py --upload_to_s3
|
|
||||||
else
|
|
||||||
echo 'Skipping upload distribution because build is not for release'
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Test
|
|
||||||
environment:
|
|
||||||
MOCHA_FILE: junit/test-results.xml
|
|
||||||
MOCHA_REPORTER: mocha-junit-reporter
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
|
||||||
echo 'Testing Electron debug build'
|
|
||||||
mkdir junit
|
|
||||||
script/test.py --ci --rebuild_native_modules
|
|
||||||
else
|
|
||||||
echo 'Skipping testing on release build'
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Verify FFmpeg
|
|
||||||
command: |
|
|
||||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
|
||||||
echo 'Verifying ffmpeg on debug build'
|
|
||||||
script/verify-ffmpeg.py
|
|
||||||
else
|
|
||||||
echo 'Skipping verify ffmpeg on release build'
|
|
||||||
fi
|
|
||||||
- run:
|
|
||||||
name: Generate Typescript Definitions
|
|
||||||
command: npm run create-typescript-definitions
|
|
||||||
- store_test_results:
|
|
||||||
path: junit
|
|
||||||
- store_artifacts:
|
|
||||||
path: junit
|
|
||||||
- store_artifacts:
|
|
||||||
path: out/electron.d.ts
|
|
||||||
- store_artifacts:
|
|
||||||
path: out/electron-api.json
|
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
version: 2
|
version: 2
|
||||||
@@ -442,5 +303,37 @@ workflows:
|
|||||||
jobs:
|
jobs:
|
||||||
- electron-linux-ia32
|
- electron-linux-ia32
|
||||||
build-x64:
|
build-x64:
|
||||||
jobs:
|
jobs:
|
||||||
- electron-linux-x64
|
- electron-linux-x64
|
||||||
|
build-osx-x64:
|
||||||
|
jobs:
|
||||||
|
- electron-osx-x64
|
||||||
|
build-mas-x64:
|
||||||
|
jobs:
|
||||||
|
- electron-mas-x64
|
||||||
|
|
||||||
|
nightly-release-test:
|
||||||
|
triggers:
|
||||||
|
- schedule:
|
||||||
|
cron: "0 0 * * *"
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
- 2-0-x
|
||||||
|
- 1-8-x
|
||||||
|
- 1-7-x
|
||||||
|
jobs:
|
||||||
|
- electron-linux-arm-release-nightly
|
||||||
|
- electron-linux-arm64-release-nightly
|
||||||
|
- electron-linux-ia32-release-nightly
|
||||||
|
- electron-linux-x64-release-nightly
|
||||||
|
|
||||||
|
experimental:
|
||||||
|
notify:
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
- 2-0-x
|
||||||
|
- 1-8-x
|
||||||
|
- 1-7-x
|
||||||
|
|||||||
7
.env.example
Normal file
7
.env.example
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# These env vars are only necessary for creating Electron releases.
|
||||||
|
# See docs/development/releasing.md
|
||||||
|
|
||||||
|
APPVEYOR_TOKEN=
|
||||||
|
CIRCLE_TOKEN=
|
||||||
|
ELECTRON_GITHUB_TOKEN=
|
||||||
|
VSTS_TOKEN=
|
||||||
4
.github/CODEOWNERS
vendored
4
.github/CODEOWNERS
vendored
@@ -14,8 +14,8 @@
|
|||||||
*updater* @electron/updater
|
*updater* @electron/updater
|
||||||
|
|
||||||
# directories
|
# directories
|
||||||
/.github/ @electron/hubbers
|
/.github/ @electron/electrocats
|
||||||
/default_app/ @electron/docs
|
/default_app/ @electron/docs
|
||||||
/docs/ @electron/docs
|
/docs/ @electron/docs
|
||||||
/docs-translations/ @electron/i18n
|
/docs-translations/ @electron/i18n
|
||||||
/npm/ @electron/hubbers
|
/npm/ @electron/electrocats
|
||||||
3
.github/ISSUE_TEMPLATE.md
vendored
3
.github/ISSUE_TEMPLATE.md
vendored
@@ -10,6 +10,9 @@ Thanks for opening an issue! A few things to keep in mind:
|
|||||||
* Electron version:
|
* Electron version:
|
||||||
* Operating system:
|
* Operating system:
|
||||||
|
|
||||||
|
<!-- If this used to work -->
|
||||||
|
* Last known working Electron version:
|
||||||
|
|
||||||
### Expected behavior
|
### Expected behavior
|
||||||
|
|
||||||
<!-- What do you think should happen? -->
|
<!-- What do you think should happen? -->
|
||||||
|
|||||||
32
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
Normal file
32
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve Electron
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
* Electron Version:
|
||||||
|
* Operating System (Platform and Version):
|
||||||
|
* Last known working Electron version:
|
||||||
|
|
||||||
|
**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.
|
||||||
|
|
||||||
|
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.
|
||||||
17
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
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.
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
13
.github/PULL_REQUEST_TEMPLATE.md
vendored
13
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -2,7 +2,14 @@
|
|||||||
Thank you for your Pull Request. Please provide a description above and review
|
Thank you for your Pull Request. Please provide a description above and review
|
||||||
the requirements below.
|
the requirements below.
|
||||||
|
|
||||||
Bug fixes and new features should include tests and possibly benchmarks.
|
|
||||||
|
|
||||||
Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTING.md
|
Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTING.md
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
##### Checklist
|
||||||
|
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->
|
||||||
|
|
||||||
|
- [ ] PR description included and stakeholders cc'd
|
||||||
|
- [ ] `npm test` passes
|
||||||
|
- [ ] tests are [changed or added](https://github.com/electron/electron/blob/master/docs/development/testing.md)
|
||||||
|
- [ ] relevant documentation is changed or added
|
||||||
|
- [ ] commit messages or PR title follow semantic [commit guidelines](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines)
|
||||||
30
.github/config.yml
vendored
30
.github/config.yml
vendored
@@ -4,7 +4,7 @@
|
|||||||
newIssueWelcomeComment: |
|
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.
|
👋 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#submitting-issues).
|
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
|
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
|
||||||
|
|
||||||
@@ -12,14 +12,22 @@ newIssueWelcomeComment: |
|
|||||||
newPRWelcomeComment: |
|
newPRWelcomeComment: |
|
||||||
💖 Thanks for opening this pull request! 💖
|
💖 Thanks for opening this pull request! 💖
|
||||||
|
|
||||||

|
We use [semantic commit messages](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines) to streamline the release process. Before your pull request can be merged, you should **update your pull request title** to start with a semantic prefix, OR prefix at least one of your commit messages.
|
||||||
|
|
||||||
|
Examples of commit messages with semantic prefixes:
|
||||||
|
|
||||||
|
- `fix: don't overwrite prevent_default if default wasn't prevented`
|
||||||
|
- `feat: add app.isPackaged() method`
|
||||||
|
- `docs: app.isDefaultProtocolClient is now available on Linux`
|
||||||
|
|
||||||
|
Things that will help get your PR across the finish line:
|
||||||
|
|
||||||
Here is a list of things that will help get it across the finish line:
|
|
||||||
- Follow the JavaScript, C++, and Python [coding style](https://github.com/electron/electron/blob/master/docs/development/coding-style.md).
|
- Follow the JavaScript, C++, and Python [coding style](https://github.com/electron/electron/blob/master/docs/development/coding-style.md).
|
||||||
- Run `npm run lint` locally to catch formatting errors earlier.
|
- Run `npm run lint` locally to catch formatting errors earlier.
|
||||||
- Document any user-facing changes you've made following the [documentation styleguide](https://github.com/electron/electron/blob/master/docs/styleguide.md).
|
- Document any user-facing changes you've made following the [documentation styleguide](https://github.com/electron/electron/blob/master/docs/styleguide.md).
|
||||||
- Include tests when adding/changing behavior.
|
- Include tests when adding/changing behavior.
|
||||||
- Include screenshots and animated GIFs whenever possible.
|
- Include screenshots and animated GIFs whenever possible.
|
||||||
|
|
||||||
We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can.
|
We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can.
|
||||||
|
|
||||||
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
|
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
|
||||||
@@ -28,4 +36,18 @@ newPRWelcomeComment: |
|
|||||||
firstPRMergeComment: >
|
firstPRMergeComment: >
|
||||||
Congrats on merging your first pull request! 🎉🎉🎉
|
Congrats on merging your first pull request! 🎉🎉🎉
|
||||||
|
|
||||||
# It is recommend to include as many gifs and emojis as possible
|
# Configuration for trop - https://github.com/codebytere/trop
|
||||||
|
|
||||||
|
watchedProject:
|
||||||
|
name: Backports
|
||||||
|
|
||||||
|
authorizedUsers:
|
||||||
|
- alexeykuzmin
|
||||||
|
- ckerr
|
||||||
|
- codebytere
|
||||||
|
- deepak1556
|
||||||
|
- jkleinsc
|
||||||
|
- MarshallOfSound
|
||||||
|
- nitsakh
|
||||||
|
- nornagon
|
||||||
|
- zcbenz
|
||||||
|
|||||||
22
.gitignore
vendored
22
.gitignore
vendored
@@ -23,19 +23,15 @@
|
|||||||
/brightray/brightray.v12.suo
|
/brightray/brightray.v12.suo
|
||||||
/brightray/brightray.vcxproj*
|
/brightray/brightray.vcxproj*
|
||||||
/brightray/brightray.xcodeproj/
|
/brightray/brightray.xcodeproj/
|
||||||
/build/
|
|
||||||
/dist/
|
/dist/
|
||||||
/external_binaries/
|
/external_binaries/
|
||||||
/out/
|
/out/
|
||||||
/vendor/.gclient
|
/vendor/.gclient
|
||||||
/vendor/debian_jessie_amd64-sysroot/
|
|
||||||
/vendor/debian_jessie_arm-sysroot/
|
|
||||||
/vendor/debian_jessie_arm64-sysroot/
|
|
||||||
/vendor/debian_jessie_i386-sysroot/
|
|
||||||
/vendor/debian_jessie_mips64-sysroot/
|
/vendor/debian_jessie_mips64-sysroot/
|
||||||
/vendor/debian_wheezy_amd64-sysroot/
|
/vendor/debian_stretch_amd64-sysroot/
|
||||||
/vendor/debian_wheezy_arm-sysroot/
|
/vendor/debian_stretch_arm-sysroot/
|
||||||
/vendor/debian_wheezy_i386-sysroot/
|
/vendor/debian_stretch_arm64-sysroot/
|
||||||
|
/vendor/debian_stretch_i386-sysroot/
|
||||||
/vendor/gcc-4.8.3-d197-n64-loongson/
|
/vendor/gcc-4.8.3-d197-n64-loongson/
|
||||||
/vendor/readme-gcc483-loongson.txt
|
/vendor/readme-gcc483-loongson.txt
|
||||||
/vendor/download/
|
/vendor/download/
|
||||||
@@ -43,6 +39,14 @@
|
|||||||
/vendor/llvm/
|
/vendor/llvm/
|
||||||
/vendor/npm/
|
/vendor/npm/
|
||||||
/vendor/python_26/
|
/vendor/python_26/
|
||||||
|
/vendor/native_mksnapshot
|
||||||
|
/vendor/LICENSES.chromium.html
|
||||||
node_modules/
|
node_modules/
|
||||||
SHASUMS256.txt
|
SHASUMS256.txt
|
||||||
**/package-lock.json
|
**/yarn.lock
|
||||||
|
compile_commands.json
|
||||||
|
.envrc
|
||||||
|
|
||||||
|
# npm package
|
||||||
|
/npm/dist
|
||||||
|
/npm/path.txt
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -7,9 +7,6 @@
|
|||||||
[submodule "vendor/breakpad"]
|
[submodule "vendor/breakpad"]
|
||||||
path = vendor/breakpad
|
path = vendor/breakpad
|
||||||
url = https://github.com/electron/chromium-breakpad.git
|
url = https://github.com/electron/chromium-breakpad.git
|
||||||
[submodule "vendor/native_mate"]
|
|
||||||
path = vendor/native_mate
|
|
||||||
url = https://github.com/electron/native-mate.git
|
|
||||||
[submodule "vendor/crashpad"]
|
[submodule "vendor/crashpad"]
|
||||||
path = vendor/crashpad
|
path = vendor/crashpad
|
||||||
url = https://github.com/electron/crashpad.git
|
url = https://github.com/electron/crashpad.git
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
v8.2.1
|
|
||||||
592
BUILD.gn
Normal file
592
BUILD.gn
Normal file
@@ -0,0 +1,592 @@
|
|||||||
|
import("//build/config/locales.gni")
|
||||||
|
import("//tools/grit/repack.gni")
|
||||||
|
import("build/asar.gni")
|
||||||
|
import("build/npm.gni")
|
||||||
|
|
||||||
|
if (is_mac) {
|
||||||
|
import("//build/config/mac/rules.gni")
|
||||||
|
import("//third_party/icu/config.gni")
|
||||||
|
import("//v8/gni/v8.gni")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_linux) {
|
||||||
|
import("//build/config/linux/pkg_config.gni")
|
||||||
|
|
||||||
|
pkg_config("gio_unix") {
|
||||||
|
packages = [ "gio-unix-2.0" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare_args() {
|
||||||
|
electron_project_name = "electron"
|
||||||
|
electron_product_name = "Electron"
|
||||||
|
electron_company_name = "GitHub, Inc"
|
||||||
|
electron_company_abbr = "github"
|
||||||
|
electron_version = "0.0.0-dev"
|
||||||
|
|
||||||
|
enable_desktop_capturer = true
|
||||||
|
enable_run_as_node = true
|
||||||
|
enable_osr = true
|
||||||
|
|
||||||
|
# Provide a fake location provider for mocking
|
||||||
|
# the geolocation responses. Disable it if you
|
||||||
|
# need to test with chromium's location provider.
|
||||||
|
# Should not be enabled for release build.
|
||||||
|
enable_fake_location_provider = !is_official_build
|
||||||
|
}
|
||||||
|
|
||||||
|
filenames_gypi = exec_script(
|
||||||
|
"//build/gypi_to_gn.py",
|
||||||
|
[
|
||||||
|
rebase_path("filenames.gypi"),
|
||||||
|
"--replace=<(SHARED_INTERMEDIATE_DIR)=$target_gen_dir",
|
||||||
|
],
|
||||||
|
"scope",
|
||||||
|
[ "filenames.gypi" ]
|
||||||
|
)
|
||||||
|
|
||||||
|
config("branding") {
|
||||||
|
defines = [
|
||||||
|
"ATOM_PRODUCT_NAME=\"$electron_product_name\"",
|
||||||
|
"ATOM_PROJECT_NAME=\"$electron_project_name\"",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
config("features") {
|
||||||
|
defines = []
|
||||||
|
if (enable_desktop_capturer) {
|
||||||
|
defines += [ "ENABLE_DESKTOP_CAPTURER=1" ]
|
||||||
|
}
|
||||||
|
if (enable_run_as_node) {
|
||||||
|
defines += [ "ENABLE_RUN_AS_NODE=1" ]
|
||||||
|
}
|
||||||
|
if (enable_osr) {
|
||||||
|
defines += [ "ENABLE_OSR=1" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config("native_mate_config") {
|
||||||
|
include_dirs = [
|
||||||
|
"//third_party/native_mate",
|
||||||
|
]
|
||||||
|
cflags_cc = [
|
||||||
|
"-Wno-deprecated-declarations",
|
||||||
|
]
|
||||||
|
cflags_objcc = cflags_cc
|
||||||
|
}
|
||||||
|
|
||||||
|
source_set("native_mate") {
|
||||||
|
deps = [
|
||||||
|
"//base",
|
||||||
|
"//net",
|
||||||
|
"//v8:v8_headers",
|
||||||
|
"build/node",
|
||||||
|
]
|
||||||
|
public_configs = [ ":native_mate_config" ]
|
||||||
|
sources = [
|
||||||
|
"//third_party/native_mate/native_mate/arguments.cc",
|
||||||
|
"//third_party/native_mate/native_mate/arguments.h",
|
||||||
|
"//third_party/native_mate/native_mate/compat.h",
|
||||||
|
"//third_party/native_mate/native_mate/constructor.h",
|
||||||
|
"//third_party/native_mate/native_mate/converter.cc",
|
||||||
|
"//third_party/native_mate/native_mate/converter.h",
|
||||||
|
"//third_party/native_mate/native_mate/dictionary.cc",
|
||||||
|
"//third_party/native_mate/native_mate/dictionary.h",
|
||||||
|
"//third_party/native_mate/native_mate/function_template.cc",
|
||||||
|
"//third_party/native_mate/native_mate/function_template.h",
|
||||||
|
"//third_party/native_mate/native_mate/handle.h",
|
||||||
|
"//third_party/native_mate/native_mate/object_template_builder.cc",
|
||||||
|
"//third_party/native_mate/native_mate/object_template_builder.h",
|
||||||
|
"//third_party/native_mate/native_mate/persistent_dictionary.cc",
|
||||||
|
"//third_party/native_mate/native_mate/persistent_dictionary.h",
|
||||||
|
"//third_party/native_mate/native_mate/scoped_persistent.h",
|
||||||
|
"//third_party/native_mate/native_mate/wrappable.cc",
|
||||||
|
"//third_party/native_mate/native_mate/wrappable.h",
|
||||||
|
"//third_party/native_mate/native_mate/wrappable_base.h",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
npm_action("atom_browserify_sandbox") {
|
||||||
|
deps = [ ":atom_js2c_copy" ]
|
||||||
|
|
||||||
|
sandbox_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",
|
||||||
|
]
|
||||||
|
|
||||||
|
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") {
|
||||||
|
deps = [ ":atom_js2c_copy" ]
|
||||||
|
|
||||||
|
inputs = [ "lib/isolated_renderer/init.js" ]
|
||||||
|
outputs = [ "$target_gen_dir/js2c/isolated_bundle.js" ]
|
||||||
|
|
||||||
|
script = "browserify"
|
||||||
|
args = inputs + [
|
||||||
|
"-o", rebase_path(outputs[0])
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
copy("atom_js2c_copy") {
|
||||||
|
sources = [
|
||||||
|
"lib/common/asar.js",
|
||||||
|
"lib/common/asar_init.js",
|
||||||
|
]
|
||||||
|
outputs = [ "$target_gen_dir/js2c/{{source_file_part}}" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
action("atom_js2c") {
|
||||||
|
deps = [
|
||||||
|
":atom_js2c_copy",
|
||||||
|
":atom_browserify_sandbox",
|
||||||
|
":atom_browserify_isolated",
|
||||||
|
]
|
||||||
|
|
||||||
|
js2c_sources = filenames_gypi.js2c_sources
|
||||||
|
|
||||||
|
browserify_sources = [
|
||||||
|
"$target_gen_dir/js2c/isolated_bundle.js",
|
||||||
|
"$target_gen_dir/js2c/preload_bundle.js",
|
||||||
|
]
|
||||||
|
|
||||||
|
inputs = js2c_sources + browserify_sources
|
||||||
|
|
||||||
|
outputs = [ "$target_gen_dir/atom_natives.h" ]
|
||||||
|
|
||||||
|
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)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
asar("js2asar") {
|
||||||
|
sources = filenames_gypi.js_sources
|
||||||
|
outputs = [ "$root_out_dir/resources/electron.asar" ]
|
||||||
|
root = "lib"
|
||||||
|
}
|
||||||
|
|
||||||
|
asar("app2asar") {
|
||||||
|
sources = filenames_gypi.default_app_sources
|
||||||
|
outputs = [ "$root_out_dir/resources/default_app.asar" ]
|
||||||
|
root = "default_app"
|
||||||
|
}
|
||||||
|
|
||||||
|
group("electron") {
|
||||||
|
deps = [ ":electron_lib" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
static_library("electron_lib") {
|
||||||
|
configs += [
|
||||||
|
"//v8:external_startup_data",
|
||||||
|
]
|
||||||
|
public_configs = [
|
||||||
|
":branding",
|
||||||
|
":features",
|
||||||
|
]
|
||||||
|
deps = [
|
||||||
|
"//chrome/common:constants",
|
||||||
|
"//components/cdm/renderer",
|
||||||
|
"//components/network_session_configurator/common",
|
||||||
|
"//components/prefs",
|
||||||
|
"//components/printing/common",
|
||||||
|
"//components/security_state/content",
|
||||||
|
"//content/public/browser",
|
||||||
|
"//device/geolocation",
|
||||||
|
"//gin",
|
||||||
|
"//net:net_resources",
|
||||||
|
"//ppapi/host",
|
||||||
|
"//ppapi/proxy",
|
||||||
|
"//ppapi/shared_impl",
|
||||||
|
"//printing",
|
||||||
|
"//services/device/wake_lock/power_save_blocker", # TODO: this requires a visibility patch to chromium src
|
||||||
|
"//skia",
|
||||||
|
"//third_party/WebKit/public:blink",
|
||||||
|
"//third_party/boringssl",
|
||||||
|
"//third_party/crashpad/crashpad/client",
|
||||||
|
"//third_party/leveldatabase",
|
||||||
|
"//third_party/libyuv",
|
||||||
|
"//third_party/webrtc/modules/desktop_capture",
|
||||||
|
"//third_party/webrtc/modules/desktop_capture:primitives",
|
||||||
|
"//ui/events:dom_keycode_converter",
|
||||||
|
"//ui/views",
|
||||||
|
"//v8",
|
||||||
|
":atom_js2c",
|
||||||
|
":native_mate",
|
||||||
|
"brightray",
|
||||||
|
"build/node",
|
||||||
|
]
|
||||||
|
if (is_mac) {
|
||||||
|
deps += [
|
||||||
|
"//ui/accelerated_widget_mac",
|
||||||
|
"//base/allocator:features",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if (is_linux) {
|
||||||
|
deps += [
|
||||||
|
"//build/config/linux/gtk3",
|
||||||
|
"//chrome/browser/ui/libgtkui",
|
||||||
|
"//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" ]
|
||||||
|
}
|
||||||
|
defines = [
|
||||||
|
# This is defined in skia/skia_common.gypi.
|
||||||
|
"SK_SUPPORT_LEGACY_GETTOPDEVICE",
|
||||||
|
# Disable warnings for g_settings_list_schemas.
|
||||||
|
"GLIB_DISABLE_DEPRECATION_WARNINGS",
|
||||||
|
|
||||||
|
# Import V8 symbols from shared library (node.dll / libnode.so)
|
||||||
|
"USING_V8_SHARED",
|
||||||
|
"USING_V8_PLATFORM_SHARED",
|
||||||
|
"USING_V8_BASE_SHARED",
|
||||||
|
|
||||||
|
# Enables SkBitmap size 64 operations
|
||||||
|
#"SK_SUPPORT_LEGACY_SAFESIZE64", # doesn't seem to be needed to build?
|
||||||
|
]
|
||||||
|
include_dirs = [
|
||||||
|
"chromium_src",
|
||||||
|
".",
|
||||||
|
"$target_gen_dir",
|
||||||
|
# TODO(nornagon): replace usage of SchemeRegistry by an actually exported
|
||||||
|
# API of blink, then delete this include dir.
|
||||||
|
"//third_party/WebKit/Source",
|
||||||
|
# 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",
|
||||||
|
]
|
||||||
|
if (is_linux) {
|
||||||
|
include_dirs += [
|
||||||
|
"//third_party/breakpad",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
extra_source_filters = []
|
||||||
|
if (!is_linux) {
|
||||||
|
extra_source_filters += [
|
||||||
|
"*\bx/*",
|
||||||
|
"*_x11.h",
|
||||||
|
"*_x11.cc",
|
||||||
|
"*_gtk.h",
|
||||||
|
"*_gtk.cc",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if (!is_win) {
|
||||||
|
extra_source_filters += [
|
||||||
|
"*\bwin_*.h",
|
||||||
|
"*\bwin_*.cc",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if (is_mac) {
|
||||||
|
extra_source_filters += [
|
||||||
|
"*_views.cc",
|
||||||
|
"*_views.h",
|
||||||
|
"*\bviews/*",
|
||||||
|
"*/autofill_popup.cc",
|
||||||
|
"*/autofill_popup.h",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
set_sources_assignment_filter(sources_assignment_filter + extra_source_filters)
|
||||||
|
sources = filenames_gypi.lib_sources
|
||||||
|
set_sources_assignment_filter(sources_assignment_filter)
|
||||||
|
|
||||||
|
if (enable_fake_location_provider) {
|
||||||
|
defines += [
|
||||||
|
"OVERRIDE_LOCATION_PROVIDER"
|
||||||
|
]
|
||||||
|
sources += filenames_gypi.lib_sources_location_provider
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enable_run_as_node) {
|
||||||
|
sources += [
|
||||||
|
"atom/app/node_main.cc",
|
||||||
|
"atom/app/node_main.h",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
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_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_view_proxy.cc",
|
||||||
|
"atom/browser/osr/osr_view_proxy.h",
|
||||||
|
"atom/browser/osr/osr_web_contents_view.cc",
|
||||||
|
"atom/browser/osr/osr_web_contents_view.h",
|
||||||
|
"atom/browser/osr/osr_web_contents_view_mac.mm",
|
||||||
|
]
|
||||||
|
deps += [
|
||||||
|
"//ui/compositor",
|
||||||
|
"//components/viz/service",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enable_desktop_capturer) {
|
||||||
|
sources += [
|
||||||
|
"atom/browser/api/atom_api_desktop_capturer.cc",
|
||||||
|
"atom/browser/api/atom_api_desktop_capturer.h",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_mac) {
|
||||||
|
libs = [
|
||||||
|
"Squirrel.framework",
|
||||||
|
"ReactiveCocoa.framework",
|
||||||
|
"Mantle.framework",
|
||||||
|
]
|
||||||
|
cflags_objcc = [
|
||||||
|
"-F", rebase_path("external_binaries", root_build_dir)
|
||||||
|
]
|
||||||
|
if (true) { # !is_mas_build
|
||||||
|
# ReactiveCocoa which is used by Squirrel requires using __weak.
|
||||||
|
cflags_objcc += [ "-fobjc-weak" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_linux) {
|
||||||
|
sources += filenames_gypi.lib_sources_linux
|
||||||
|
sources += filenames_gypi.lib_sources_nss
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_mac) {
|
||||||
|
electron_framework_name = electron_product_name + " Framework"
|
||||||
|
electron_helper_name = electron_product_name + " Helper"
|
||||||
|
electron_framework_version = "A"
|
||||||
|
electron_mac_bundle_id = "com.$electron_company_abbr.$electron_project_name"
|
||||||
|
|
||||||
|
mac_xib_bundle_data("electron_xibs") {
|
||||||
|
sources = [ "atom/common/resources/mac/MainMenu.xib" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
bundle_data("electron_framework_resources") {
|
||||||
|
public_deps = [
|
||||||
|
"//content/shell:pak",
|
||||||
|
":electron_locales",
|
||||||
|
]
|
||||||
|
sources = [
|
||||||
|
"$root_out_dir/content_shell.pak",
|
||||||
|
]
|
||||||
|
if (icu_use_data_file) {
|
||||||
|
sources += [ "$root_out_dir/icudtl.dat" ]
|
||||||
|
public_deps += [ "//third_party/icu:icudata" ]
|
||||||
|
}
|
||||||
|
if (v8_use_external_startup_data) {
|
||||||
|
sources += [
|
||||||
|
"$root_out_dir/natives_blob.bin",
|
||||||
|
"$root_out_dir/snapshot_blob.bin",
|
||||||
|
]
|
||||||
|
public_deps += [ "//v8" ]
|
||||||
|
}
|
||||||
|
outputs = [
|
||||||
|
"{{bundle_resources_dir}}/{{source_file_part}}",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
bundle_data("electron_framework_libraries") {
|
||||||
|
public_deps = [ "build/node" ]
|
||||||
|
sources = [
|
||||||
|
"$root_out_dir/libnode.dylib"
|
||||||
|
]
|
||||||
|
outputs = [
|
||||||
|
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
bundle_data("electron_framework_helpers") {
|
||||||
|
sources = [
|
||||||
|
"$root_out_dir/crashpad_handler",
|
||||||
|
]
|
||||||
|
|
||||||
|
outputs = [
|
||||||
|
"{{bundle_resources_dir}}/{{source_file_part}}",
|
||||||
|
]
|
||||||
|
|
||||||
|
public_deps = [
|
||||||
|
"//third_party/crashpad/crashpad/handler:crashpad_handler",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
mac_framework_bundle("electron_framework") {
|
||||||
|
output_name = electron_framework_name
|
||||||
|
framework_version = electron_framework_version
|
||||||
|
framework_contents = [ "Resources" ]
|
||||||
|
public_deps = [ ":electron_lib" ]
|
||||||
|
deps = [
|
||||||
|
"//base",
|
||||||
|
"//base:i18n",
|
||||||
|
":electron_framework_helpers",
|
||||||
|
":electron_framework_libraries",
|
||||||
|
":electron_framework_resources",
|
||||||
|
":electron_xibs",
|
||||||
|
]
|
||||||
|
info_plist = "atom/common/resources/mac/Info.plist"
|
||||||
|
extra_substitutions = [
|
||||||
|
"ATOM_BUNDLE_ID=$electron_mac_bundle_id.framework",
|
||||||
|
]
|
||||||
|
|
||||||
|
include_dirs = [
|
||||||
|
".",
|
||||||
|
]
|
||||||
|
sources = filenames_gypi.framework_sources
|
||||||
|
|
||||||
|
libs = [
|
||||||
|
"Carbon.framework",
|
||||||
|
"QuartzCore.framework",
|
||||||
|
"Quartz.framework",
|
||||||
|
"Security.framework",
|
||||||
|
"SecurityInterface.framework",
|
||||||
|
"ServiceManagement.framework",
|
||||||
|
"StoreKit.framework",
|
||||||
|
]
|
||||||
|
ldflags = [
|
||||||
|
"-F", rebase_path("external_binaries", root_build_dir),
|
||||||
|
"-Wl,-install_name,@rpath/$output_name.framework/$output_name",
|
||||||
|
"-rpath",
|
||||||
|
"@loader_path/Libraries",
|
||||||
|
]
|
||||||
|
if (is_component_build) {
|
||||||
|
ldflags += [
|
||||||
|
"-rpath",
|
||||||
|
"@executable_path/../../../../../.."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mac_app_bundle("electron_helper_app") {
|
||||||
|
output_name = electron_helper_name
|
||||||
|
deps = [ ":electron_framework+link" ]
|
||||||
|
sources = filenames_gypi.app_sources
|
||||||
|
include_dirs = [ "." ]
|
||||||
|
info_plist = "atom/renderer/resources/mac/Info.plist"
|
||||||
|
extra_substitutions = [
|
||||||
|
"ATOM_BUNDLE_ID=$electron_mac_bundle_id.helper",
|
||||||
|
]
|
||||||
|
ldflags = [
|
||||||
|
"-rpath",
|
||||||
|
"@executable_path/../../..",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
bundle_data("electron_app_framework_bundle_data") {
|
||||||
|
sources = [
|
||||||
|
"$root_out_dir/$electron_framework_name.framework",
|
||||||
|
"$root_out_dir/$electron_helper_name.app",
|
||||||
|
"external_binaries/Squirrel.framework",
|
||||||
|
"external_binaries/ReactiveCocoa.framework",
|
||||||
|
"external_binaries/Mantle.framework",
|
||||||
|
]
|
||||||
|
outputs = [
|
||||||
|
"{{bundle_contents_dir}}/Frameworks/{{source_file_part}}",
|
||||||
|
]
|
||||||
|
public_deps = [
|
||||||
|
":electron_framework+link",
|
||||||
|
":electron_helper_app",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
bundle_data("electron_app_resources") {
|
||||||
|
public_deps = [
|
||||||
|
":js2asar",
|
||||||
|
":app2asar",
|
||||||
|
]
|
||||||
|
sources = [
|
||||||
|
"$root_out_dir/resources/electron.asar",
|
||||||
|
"$root_out_dir/resources/default_app.asar",
|
||||||
|
]
|
||||||
|
outputs = [
|
||||||
|
"{{bundle_resources_dir}}/{{source_file_part}}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
repack_locales("electron_locales") {
|
||||||
|
source_patterns = [
|
||||||
|
"${root_gen_dir}/content/app/strings/content_strings_",
|
||||||
|
]
|
||||||
|
deps = [
|
||||||
|
"//content/app/strings",
|
||||||
|
]
|
||||||
|
|
||||||
|
input_locales = locales
|
||||||
|
|
||||||
|
if (is_mac) {
|
||||||
|
output_locales = locales_as_mac_outputs
|
||||||
|
} else {
|
||||||
|
output_locales = locales
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_mac) {
|
||||||
|
output_dir = "$root_gen_dir/repack"
|
||||||
|
copy_data_to_bundle = true
|
||||||
|
} else {
|
||||||
|
output_dir = root_out_dir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mac_app_bundle("electron_app") {
|
||||||
|
output_name = electron_product_name
|
||||||
|
sources = filenames_gypi.app_sources
|
||||||
|
include_dirs = [ "." ]
|
||||||
|
deps = [
|
||||||
|
":electron_app_framework_bundle_data",
|
||||||
|
":electron_app_resources",
|
||||||
|
]
|
||||||
|
info_plist = "atom/browser/resources/mac/Info.plist"
|
||||||
|
extra_substitutions = [
|
||||||
|
"ATOM_BUNDLE_ID=$electron_mac_bundle_id",
|
||||||
|
]
|
||||||
|
ldflags = [
|
||||||
|
"-rpath",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_linux) {
|
||||||
|
executable("electron_app") {
|
||||||
|
output_name = electron_project_name
|
||||||
|
sources = filenames_gypi.app_sources
|
||||||
|
include_dirs = [ "." ]
|
||||||
|
deps = [
|
||||||
|
":app2asar",
|
||||||
|
":electron_lib",
|
||||||
|
":js2asar",
|
||||||
|
"//build/config:exe_and_shlib_deps",
|
||||||
|
"//chrome:packed_resources",
|
||||||
|
"//content/shell:copy_shell_resources",
|
||||||
|
"//content/shell:pak",
|
||||||
|
"//third_party/WebKit/public:image_resources",
|
||||||
|
"//ui/strings",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
|
|||||||
|
|
||||||
## Enforcement
|
## Enforcement
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [electron@github.com](mailto:electron@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [coc@electronjs.org](mailto:coc@electronjs.org). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
|
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
|
||||||
By participating, you are expected to uphold this code. Please report unacceptable
|
By participating, you are expected to uphold this code. Please report unacceptable
|
||||||
behavior to electron@github.com.
|
behavior to coc@electronjs.org.
|
||||||
|
|
||||||
The following is a set of guidelines for contributing to Electron.
|
The following is a set of guidelines for contributing to Electron.
|
||||||
These are just guidelines, not rules, use your best judgment and feel free to
|
These are just guidelines, not rules, use your best judgment and feel free to
|
||||||
@@ -54,3 +54,7 @@ dependencies, and tools contained in the `electron/electron` repository.
|
|||||||
|
|
||||||
See [Coding Style](https://electronjs.org/docs/development/coding-style) for information about which standards Electron adheres to in different parts of its codebase.
|
See [Coding Style](https://electronjs.org/docs/development/coding-style) for information about which standards Electron adheres to in different parts of its codebase.
|
||||||
|
|
||||||
|
## Further Reading
|
||||||
|
|
||||||
|
For more in-depth guides on developing Electron, see
|
||||||
|
[/docs/development](/docs/development/README.md)
|
||||||
73
DEPS
Normal file
73
DEPS
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
vars = {
|
||||||
|
'chromium_version':
|
||||||
|
'63.0.3239.150',
|
||||||
|
'libchromiumcontent_revision':
|
||||||
|
'61d71f3f150c3ff5025560dee254a53313bfbaf6',
|
||||||
|
'node_version':
|
||||||
|
'v9.7.0-33-g538a5023af',
|
||||||
|
'native_mate_revision':
|
||||||
|
'4cd7d113915de0cc08e9a218be35bff9c7361906',
|
||||||
|
|
||||||
|
'chromium_git':
|
||||||
|
'https://chromium.googlesource.com',
|
||||||
|
|
||||||
|
'electron_git':
|
||||||
|
'https://github.com/electron',
|
||||||
|
}
|
||||||
|
|
||||||
|
deps = {
|
||||||
|
'src':
|
||||||
|
(Var("chromium_git")) + '/chromium/src.git@' + (Var("chromium_version")),
|
||||||
|
'src/libchromiumcontent':
|
||||||
|
(Var("electron_git")) + '/libchromiumcontent.git@' + (Var("libchromiumcontent_revision")),
|
||||||
|
'src/third_party/electron_node':
|
||||||
|
(Var("electron_git")) + '/node.git@' + (Var("node_version")),
|
||||||
|
'src/third_party/native_mate':
|
||||||
|
(Var("electron_git")) + '/native-mate.git@' + (Var("native_mate_revision")),
|
||||||
|
}
|
||||||
|
|
||||||
|
hooks = [
|
||||||
|
{
|
||||||
|
'action': [
|
||||||
|
'src/libchromiumcontent/script/apply-patches'
|
||||||
|
],
|
||||||
|
'pattern':
|
||||||
|
'src/libchromiumcontent',
|
||||||
|
'name':
|
||||||
|
'patch_chromium'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'action': [
|
||||||
|
'src/electron/script/update-external-binaries.py'
|
||||||
|
],
|
||||||
|
'pattern':
|
||||||
|
'src/electron/script/update-external-binaries.py',
|
||||||
|
'name':
|
||||||
|
'electron_external_binaries'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'action': [
|
||||||
|
'bash',
|
||||||
|
'-c',
|
||||||
|
# NOTE(nornagon): this ridiculous {{}} stuff is because these strings get
|
||||||
|
# variable-substituted twice by gclient.
|
||||||
|
'echo -e "#\\n{{{{\'variables\':{{{{}}}}}}}}" > src/third_party/electron_node/config.gypi',
|
||||||
|
],
|
||||||
|
'pattern': 'src/third_party/electron_node',
|
||||||
|
'name': 'touch_node_config_gypi'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'action': [
|
||||||
|
'bash',
|
||||||
|
'-c',
|
||||||
|
'cd src/electron; npm install',
|
||||||
|
],
|
||||||
|
'pattern': 'src/electron/package.json',
|
||||||
|
'name': 'electron_npm_deps'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
recursedeps = [
|
||||||
|
'src',
|
||||||
|
'src/libchromiumcontent',
|
||||||
|
]
|
||||||
@@ -7,8 +7,8 @@ ENV HOME=/home
|
|||||||
RUN chmod a+rwx /home
|
RUN chmod a+rwx /home
|
||||||
|
|
||||||
# Install node.js
|
# Install node.js
|
||||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
|
||||||
RUN apt-get update && apt-get install -y nodejs
|
RUN apt-get install -y nodejs
|
||||||
|
|
||||||
# Install wget used by crash reporter
|
# Install wget used by crash reporter
|
||||||
RUN apt-get install -y wget
|
RUN apt-get install -y wget
|
||||||
@@ -16,6 +16,9 @@ RUN apt-get install -y wget
|
|||||||
# Install python-dbusmock
|
# Install python-dbusmock
|
||||||
RUN apt-get install -y python-dbusmock
|
RUN apt-get install -y python-dbusmock
|
||||||
|
|
||||||
|
# Install libnotify
|
||||||
|
RUN apt-get install -y libnotify-bin
|
||||||
|
|
||||||
# Add xvfb init script
|
# Add xvfb init script
|
||||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||||
RUN chmod a+x /etc/init.d/xvfb
|
RUN chmod a+x /etc/init.d/xvfb
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ RUN apt-get update && apt-get install -y\
|
|||||||
libgnome-keyring-dev \
|
libgnome-keyring-dev \
|
||||||
libgtk-3-0 \
|
libgtk-3-0 \
|
||||||
libgtk-3-dev \
|
libgtk-3-dev \
|
||||||
|
libnotify-bin \
|
||||||
libnotify-dev \
|
libnotify-dev \
|
||||||
libnss3 \
|
libnss3 \
|
||||||
libnss3-dev \
|
libnss3-dev \
|
||||||
|
|||||||
63
Dockerfile.arm64v8
Normal file
63
Dockerfile.arm64v8
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
FROM arm64v8/ubuntu:16.04
|
||||||
|
|
||||||
|
RUN groupadd --gid 1000 builduser \
|
||||||
|
&& useradd --uid 1000 --gid builduser --shell /bin/bash --create-home builduser
|
||||||
|
|
||||||
|
RUN groupadd --gid 114 jenkins \
|
||||||
|
&& useradd --uid 110 --gid jenkins --shell /bin/bash --create-home jenkins
|
||||||
|
|
||||||
|
# Set up TEMP directory
|
||||||
|
ENV TEMP=/tmp
|
||||||
|
RUN chmod a+rwx /tmp
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y\
|
||||||
|
bison \
|
||||||
|
build-essential \
|
||||||
|
clang \
|
||||||
|
curl \
|
||||||
|
gperf \
|
||||||
|
git \
|
||||||
|
libasound2 \
|
||||||
|
libasound2-dev \
|
||||||
|
libcap-dev \
|
||||||
|
libcups2-dev \
|
||||||
|
libdbus-1-dev \
|
||||||
|
libgconf-2-4 \
|
||||||
|
libgconf2-dev \
|
||||||
|
libgnome-keyring-dev \
|
||||||
|
libgtk2.0-0 \
|
||||||
|
libgtk2.0-dev \
|
||||||
|
libgtk-3-0 \
|
||||||
|
libgtk-3-dev \
|
||||||
|
libnotify-dev \
|
||||||
|
libnss3 \
|
||||||
|
libnss3-dev \
|
||||||
|
libx11-xcb-dev \
|
||||||
|
libxss1 \
|
||||||
|
libxtst-dev \
|
||||||
|
libxtst6 \
|
||||||
|
lsb-release \
|
||||||
|
locales \
|
||||||
|
ninja \
|
||||||
|
python-setuptools \
|
||||||
|
python-pip \
|
||||||
|
python-dbusmock \
|
||||||
|
wget \
|
||||||
|
xvfb
|
||||||
|
|
||||||
|
# Install node.js
|
||||||
|
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
|
||||||
|
RUN apt-get update && apt-get install -y nodejs
|
||||||
|
|
||||||
|
# Install crcmod
|
||||||
|
RUN pip install -U crcmod
|
||||||
|
|
||||||
|
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||||
|
RUN chmod a+x /etc/init.d/xvfb
|
||||||
|
|
||||||
|
# Install ninja in /usr/local
|
||||||
|
RUN cd /usr/local && git clone https://github.com/martine/ninja.git -b v1.5.3
|
||||||
|
RUN cd /usr/local/ninja && ./configure.py --bootstrap
|
||||||
|
|
||||||
|
USER builduser
|
||||||
|
WORKDIR /home/builduser
|
||||||
@@ -16,6 +16,7 @@ RUN apt-get update && apt-get install -y\
|
|||||||
libgnome-keyring-dev \
|
libgnome-keyring-dev \
|
||||||
libgtk-3-0 \
|
libgtk-3-0 \
|
||||||
libgtk-3-dev \
|
libgtk-3-dev \
|
||||||
|
libnotify-bin \
|
||||||
libnotify-dev \
|
libnotify-dev \
|
||||||
libnss3 \
|
libnss3 \
|
||||||
libnss3-dev \
|
libnss3-dev \
|
||||||
@@ -28,13 +29,8 @@ RUN apt-get update && apt-get install -y\
|
|||||||
wget \
|
wget \
|
||||||
xvfb
|
xvfb
|
||||||
|
|
||||||
# Install node.js
|
|
||||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
|
||||||
RUN apt-get update && apt-get install -y nodejs
|
|
||||||
|
|
||||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||||
RUN chmod a+x /etc/init.d/xvfb
|
RUN chmod a+x /etc/init.d/xvfb
|
||||||
ADD tools/run-electron.sh /run-electron.sh
|
ADD tools/run-electron.sh /run-electron.sh
|
||||||
RUN chmod a+x /run-electron.sh
|
RUN chmod a+x /run-electron.sh
|
||||||
|
|
||||||
CMD sh /run-electron.sh
|
CMD sh /run-electron.sh
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ FROM electronbuilds/libchromiumcontent:0.0.4
|
|||||||
USER root
|
USER root
|
||||||
|
|
||||||
# Install node.js
|
# Install node.js
|
||||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
|
||||||
RUN apt-get update && apt-get install -y nodejs
|
RUN apt-get install -y nodejs
|
||||||
|
|
||||||
# Install wget used by crash reporter
|
# Install wget used by crash reporter
|
||||||
RUN apt-get install -y wget
|
RUN apt-get install -y wget
|
||||||
@@ -12,6 +12,9 @@ RUN apt-get install -y wget
|
|||||||
# Install python-dbusmock
|
# Install python-dbusmock
|
||||||
RUN apt-get install -y python-dbusmock
|
RUN apt-get install -y python-dbusmock
|
||||||
|
|
||||||
|
# Install libnotify
|
||||||
|
RUN apt-get install -y libnotify-bin
|
||||||
|
|
||||||
# Add xvfb init script
|
# Add xvfb init script
|
||||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||||
RUN chmod a+x /etc/init.d/xvfb
|
RUN chmod a+x /etc/init.d/xvfb
|
||||||
|
|||||||
48
Jenkinsfile
vendored
48
Jenkinsfile
vendored
@@ -1,48 +0,0 @@
|
|||||||
pipeline {
|
|
||||||
agent none
|
|
||||||
stages {
|
|
||||||
stage('Build') {
|
|
||||||
parallel {
|
|
||||||
stage('electron-osx-x64') {
|
|
||||||
agent {
|
|
||||||
label 'osx'
|
|
||||||
}
|
|
||||||
steps {
|
|
||||||
timeout(60) {
|
|
||||||
sh 'script/bootstrap.py --target_arch=x64 --dev'
|
|
||||||
sh 'npm run lint'
|
|
||||||
sh 'script/build.py -c D'
|
|
||||||
sh 'script/test.py --ci --rebuild_native_modules'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
post {
|
|
||||||
always {
|
|
||||||
cleanWs()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('electron-mas-x64') {
|
|
||||||
agent {
|
|
||||||
label 'osx'
|
|
||||||
}
|
|
||||||
environment {
|
|
||||||
MAS_BUILD = '1'
|
|
||||||
}
|
|
||||||
steps {
|
|
||||||
timeout(60) {
|
|
||||||
sh 'script/bootstrap.py --target_arch=x64 --dev'
|
|
||||||
sh 'npm run lint'
|
|
||||||
sh 'script/build.py -c D'
|
|
||||||
sh 'script/test.py --ci --rebuild_native_modules'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
post {
|
|
||||||
always {
|
|
||||||
cleanWs()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
31
README.md
31
README.md
@@ -3,12 +3,11 @@
|
|||||||
|
|
||||||
[](https://circleci.com/gh/electron/electron/tree/master)
|
[](https://circleci.com/gh/electron/electron/tree/master)
|
||||||
[](https://windows-ci.electronjs.org/project/AppVeyor/electron/branch/master)
|
[](https://windows-ci.electronjs.org/project/AppVeyor/electron/branch/master)
|
||||||
[](https://mac-ci.electronjs.org/blue/organizations/jenkins/Electron%20org%2Felectron/activity?branch=master)
|
|
||||||
[](https://david-dm.org/electron/electron?type=dev)
|
[](https://david-dm.org/electron/electron?type=dev)
|
||||||
[](https://atom-slack.herokuapp.com/)
|
[](https://atom-slack.herokuapp.com/)
|
||||||
|
|
||||||
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹.
|
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹.
|
||||||
View these docs in other languages at [electron/electron-i18n](https://github.com/electron/electron-i18n/tree/master/content/).
|
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
|
The Electron framework lets you write cross-platform desktop applications
|
||||||
using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and
|
using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and
|
||||||
@@ -21,7 +20,7 @@ announcements.
|
|||||||
This project adheres to the Contributor Covenant
|
This project adheres to the Contributor Covenant
|
||||||
[code of conduct](https://github.com/electron/electron/tree/master/CODE_OF_CONDUCT.md).
|
[code of conduct](https://github.com/electron/electron/tree/master/CODE_OF_CONDUCT.md).
|
||||||
By participating, you are expected to uphold this code. Please report unacceptable
|
By participating, you are expected to uphold this code. Please report unacceptable
|
||||||
behavior to [electron@github.com](mailto:electron@github.com).
|
behavior to [coc@electronjs.org](mailto:coc@electronjs.org).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -30,11 +29,11 @@ The preferred method is to install Electron as a development dependency in your
|
|||||||
app:
|
app:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm install electron --save-dev --save-exact
|
npm install electron --save-dev [--save-exact]
|
||||||
```
|
```
|
||||||
|
|
||||||
The `--save-exact` flag is recommended as Electron does not follow semantic
|
The `--save-exact` flag is recommended for Electron prior to version 2, as it does not follow semantic
|
||||||
versioning. For info on how to manage Electron versions in your apps, see
|
versioning. As of version 2.0.0, Electron follows semver, so you don't need `--save-exact` flag. For info on how to manage Electron versions in your apps, see
|
||||||
[Electron versioning](docs/tutorial/electron-versioning.md).
|
[Electron versioning](docs/tutorial/electron-versioning.md).
|
||||||
|
|
||||||
For more installation options and troubleshooting tips, see
|
For more installation options and troubleshooting tips, see
|
||||||
@@ -85,26 +84,12 @@ const child = proc.spawn(electron)
|
|||||||
|
|
||||||
## Documentation Translations
|
## Documentation Translations
|
||||||
|
|
||||||
Find documentation translations in [electron/electron-i18n](https://github.com/electron/electron-i18n).
|
Find documentation translations in [electron/i18n](https://github.com/electron/i18n).
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
You can ask questions and interact with the community in the following
|
Info on reporting bugs, getting help, finding third-party tools and sample apps,
|
||||||
locations:
|
and more can be found in the [support document](docs/tutorial/support.md#finding-support).
|
||||||
- [`electron`](https://discuss.atom.io/c/electron) category on the Atom
|
|
||||||
forums
|
|
||||||
- `#atom-shell` channel on Freenode
|
|
||||||
- [`Atom`](https://atom-slack.herokuapp.com) channel on Slack
|
|
||||||
- [`electron-ru`](https://telegram.me/electron_ru) *(Russian)*
|
|
||||||
- [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
|
|
||||||
- [`electron-kr`](https://electron-kr.github.io/electron-kr) *(Korean)*
|
|
||||||
- [`electron-jp`](https://electron-jp.slack.com) *(Japanese)*
|
|
||||||
- [`electron-tr`](https://electron-tr.herokuapp.com) *(Turkish)*
|
|
||||||
- [`electron-id`](https://electron-id.slack.com) *(Indonesia)*
|
|
||||||
- [`electron-pl`](https://electronpl.github.io) *(Poland)*
|
|
||||||
|
|
||||||
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron)
|
|
||||||
for a community maintained list of useful example apps, tools and resources.
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
The Electron team and community take security bugs in Electron seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
|
The Electron team and community take security bugs in Electron seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
|
||||||
|
|
||||||
To report a security issue, email [electron@github.com](mailto:electron@github.com) and include the word "SECURITY" in the subject line.
|
To report a security issue, email [security@electronjs.org](mailto:security@electronjs.org) and include the word "SECURITY" in the subject line.
|
||||||
|
|
||||||
The Electron team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
|
The Electron team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
|
||||||
|
|
||||||
|
|||||||
71
appveyor.yml
Normal file
71
appveyor.yml
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
build_cloud: electron-16
|
||||||
|
image: electron-16-vs2017-15.4.5
|
||||||
|
build_script:
|
||||||
|
- ps: >-
|
||||||
|
echo "Build worker image $env:APPVEYOR_BUILD_WORKER_IMAGE"
|
||||||
|
|
||||||
|
&"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"
|
||||||
|
|
||||||
|
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
|
||||||
|
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
|
||||||
|
} else {
|
||||||
|
Add-Path "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64"
|
||||||
|
$env:path = "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64;$env:path"
|
||||||
|
if($env:APPVEYOR_SCHEDULED_BUILD -eq 'True') {
|
||||||
|
$env:RUN_RELEASE_BUILD = "1"
|
||||||
|
}
|
||||||
|
$Message = (git log --format=%B -n 1 HEAD) | Out-String
|
||||||
|
if ((Test-Path Env:\RUN_RELEASE_BUILD)) {
|
||||||
|
$env:ELECTRON_RELEASE = '1'
|
||||||
|
Write-Output "release build triggered from api"
|
||||||
|
}
|
||||||
|
if ((Test-Path Env:\ELECTRON_RELEASE)) {
|
||||||
|
Write-Output "Running release build"
|
||||||
|
python script\bootstrap.py --target_arch=$env:TARGET_ARCH
|
||||||
|
python script\build.py -c R
|
||||||
|
python script\create-dist.py
|
||||||
|
} else {
|
||||||
|
Write-Output "Running debug build"
|
||||||
|
python script\bootstrap.py --target_arch=$env:TARGET_ARCH --dev
|
||||||
|
python script\build.py -c D
|
||||||
|
}
|
||||||
|
if ($? -ne 'True') {
|
||||||
|
throw "Build failed with exit code $?"
|
||||||
|
} else {
|
||||||
|
"Build succeeded."
|
||||||
|
}
|
||||||
|
Push-AppveyorArtifact out
|
||||||
|
}
|
||||||
|
test_script:
|
||||||
|
- ps: >-
|
||||||
|
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||||
|
Write-Output "Skipping tests for release build"
|
||||||
|
} else {
|
||||||
|
Write-Output "Running tests for debug build"
|
||||||
|
python script\test.py --ci --rebuild_native_modules
|
||||||
|
if ($LASTEXITCODE -ne '0') {
|
||||||
|
throw "Tests failed with exit code $LASTEXITCODE"
|
||||||
|
} else {
|
||||||
|
Write-Output "Tests succeeded."
|
||||||
|
}
|
||||||
|
python script\verify-ffmpeg.py
|
||||||
|
if ($LASTEXITCODE -ne '0') {
|
||||||
|
throw "Verify ffmpeg failed with exit code $LASTEXITCODE"
|
||||||
|
} else {
|
||||||
|
"Verify ffmpeg succeeded."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
artifacts:
|
||||||
|
- path: test-results.xml
|
||||||
|
name: test-results.xml
|
||||||
|
deploy_script:
|
||||||
|
- ps: >-
|
||||||
|
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||||
|
if (Test-Path Env:\RUN_RELEASE_BUILD) {
|
||||||
|
Write-Output "Uploading Electron release distribution to s3"
|
||||||
|
& python script\upload.py --upload_to_s3
|
||||||
|
} else {
|
||||||
|
Write-Output "Uploading Electron release distribution to github releases"
|
||||||
|
& python script\upload.py
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
filter=+build/include_alpha
|
|
||||||
@@ -7,7 +7,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "atom/common/atom_constants.h"
|
|
||||||
#include "atom/common/atom_version.h"
|
#include "atom/common/atom_version.h"
|
||||||
#include "atom/common/chrome_version.h"
|
#include "atom/common/chrome_version.h"
|
||||||
#include "atom/common/options_switches.h"
|
#include "atom/common/options_switches.h"
|
||||||
@@ -19,20 +18,90 @@
|
|||||||
#include "content/public/common/content_constants.h"
|
#include "content/public/common/content_constants.h"
|
||||||
#include "content/public/common/pepper_plugin_info.h"
|
#include "content/public/common/pepper_plugin_info.h"
|
||||||
#include "content/public/common/user_agent.h"
|
#include "content/public/common/user_agent.h"
|
||||||
#include "pdf/pdf.h"
|
#include "media/media_features.h"
|
||||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||||
#include "third_party/widevine/cdm/stub/widevine_cdm_version.h"
|
#include "third_party/widevine/cdm/widevine_cdm_common.h"
|
||||||
#include "ui/base/l10n/l10n_util.h"
|
#include "ui/base/l10n/l10n_util.h"
|
||||||
#include "url/url_constants.h"
|
#include "url/url_constants.h"
|
||||||
|
|
||||||
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
|
#if defined(WIDEVINE_CDM_AVAILABLE)
|
||||||
|
#include "base/native_library.h"
|
||||||
|
#include "base/strings/stringprintf.h"
|
||||||
#include "chrome/common/widevine_cdm_constants.h"
|
#include "chrome/common/widevine_cdm_constants.h"
|
||||||
#endif
|
#include "content/public/common/cdm_info.h"
|
||||||
|
#include "media/base/video_codecs.h"
|
||||||
|
#endif // defined(WIDEVINE_CDM_AVAILABLE)
|
||||||
|
|
||||||
|
#if defined(ENABLE_PDF_VIEWER)
|
||||||
|
#include "atom/common/atom_constants.h"
|
||||||
|
#include "pdf/pdf.h"
|
||||||
|
#endif // defined(ENABLE_PDF_VIEWER)
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
#if defined(WIDEVINE_CDM_AVAILABLE)
|
||||||
|
bool IsWidevineAvailable(base::FilePath* adapter_path,
|
||||||
|
base::FilePath* cdm_path,
|
||||||
|
std::vector<media::VideoCodec>* codecs_supported) {
|
||||||
|
static enum {
|
||||||
|
NOT_CHECKED,
|
||||||
|
FOUND,
|
||||||
|
NOT_FOUND,
|
||||||
|
} widevine_cdm_file_check = NOT_CHECKED;
|
||||||
|
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||||
|
*adapter_path = command_line->GetSwitchValuePath(switches::kWidevineCdmPath);
|
||||||
|
if (!adapter_path->empty()) {
|
||||||
|
*cdm_path = adapter_path->DirName().AppendASCII(
|
||||||
|
base::GetNativeLibraryName(kWidevineCdmLibraryName));
|
||||||
|
if (widevine_cdm_file_check == NOT_CHECKED) {
|
||||||
|
widevine_cdm_file_check =
|
||||||
|
(base::PathExists(*adapter_path) && base::PathExists(*cdm_path))
|
||||||
|
? FOUND
|
||||||
|
: NOT_FOUND;
|
||||||
|
}
|
||||||
|
if (widevine_cdm_file_check == FOUND) {
|
||||||
|
// Add the supported codecs as if they came from the component manifest.
|
||||||
|
// This list must match the CDM that is being bundled with Chrome.
|
||||||
|
codecs_supported->push_back(media::VideoCodec::kCodecVP8);
|
||||||
|
codecs_supported->push_back(media::VideoCodec::kCodecVP9);
|
||||||
|
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
|
||||||
|
codecs_supported->push_back(media::VideoCodec::kCodecH264);
|
||||||
|
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void AddWidevineAdapterFromCommandLine(
|
||||||
|
base::CommandLine* command_line,
|
||||||
|
std::vector<content::PepperPluginInfo>* plugins) {
|
||||||
|
base::FilePath adapter_path;
|
||||||
|
base::FilePath cdm_path;
|
||||||
|
std::vector<media::VideoCodec> video_codecs_supported;
|
||||||
|
if (IsWidevineAvailable(&adapter_path, &cdm_path, &video_codecs_supported)) {
|
||||||
|
auto cdm_version_string =
|
||||||
|
command_line->GetSwitchValueASCII(switches::kWidevineCdmVersion);
|
||||||
|
content::PepperPluginInfo info;
|
||||||
|
info.is_out_of_process = true;
|
||||||
|
info.path = adapter_path;
|
||||||
|
info.name = kWidevineCdmDisplayName;
|
||||||
|
info.description =
|
||||||
|
base::StringPrintf("%s (version: %s)", kWidevineCdmDescription,
|
||||||
|
cdm_version_string.c_str());
|
||||||
|
info.version = cdm_version_string;
|
||||||
|
info.permissions = kWidevineCdmPluginPermissions;
|
||||||
|
content::WebPluginMimeType mime_type(kWidevineCdmPluginMimeType,
|
||||||
|
kWidevineCdmPluginExtension,
|
||||||
|
kWidevineCdmPluginMimeTypeDescription);
|
||||||
|
info.mime_types.push_back(mime_type);
|
||||||
|
plugins->push_back(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // defined(WIDEVINE_CDM_AVAILABLE)
|
||||||
|
|
||||||
|
#if defined(ENABLE_PEPPER_FLASH)
|
||||||
content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
||||||
const std::string& version) {
|
const std::string& version) {
|
||||||
content::PepperPluginInfo plugin;
|
content::PepperPluginInfo plugin;
|
||||||
@@ -57,60 +126,38 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
|||||||
flash_version_numbers.push_back("999");
|
flash_version_numbers.push_back("999");
|
||||||
// E.g., "Shockwave Flash 10.2 r154":
|
// E.g., "Shockwave Flash 10.2 r154":
|
||||||
plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
|
plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
|
||||||
flash_version_numbers[1] + " r" + flash_version_numbers[2];
|
flash_version_numbers[1] + " r" +
|
||||||
|
flash_version_numbers[2];
|
||||||
plugin.version = base::JoinString(flash_version_numbers, ".");
|
plugin.version = base::JoinString(flash_version_numbers, ".");
|
||||||
content::WebPluginMimeType swf_mime_type(
|
content::WebPluginMimeType swf_mime_type(content::kFlashPluginSwfMimeType,
|
||||||
content::kFlashPluginSwfMimeType,
|
content::kFlashPluginSwfExtension,
|
||||||
content::kFlashPluginSwfExtension,
|
content::kFlashPluginSwfDescription);
|
||||||
content::kFlashPluginSwfDescription);
|
|
||||||
plugin.mime_types.push_back(swf_mime_type);
|
plugin.mime_types.push_back(swf_mime_type);
|
||||||
content::WebPluginMimeType spl_mime_type(
|
content::WebPluginMimeType spl_mime_type(content::kFlashPluginSplMimeType,
|
||||||
content::kFlashPluginSplMimeType,
|
content::kFlashPluginSplExtension,
|
||||||
content::kFlashPluginSplExtension,
|
content::kFlashPluginSplDescription);
|
||||||
content::kFlashPluginSplDescription);
|
|
||||||
plugin.mime_types.push_back(spl_mime_type);
|
plugin.mime_types.push_back(spl_mime_type);
|
||||||
|
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
|
void AddPepperFlashFromCommandLine(
|
||||||
content::PepperPluginInfo CreateWidevineCdmInfo(const base::FilePath& path,
|
base::CommandLine* command_line,
|
||||||
const std::string& version) {
|
std::vector<content::PepperPluginInfo>* plugins) {
|
||||||
content::PepperPluginInfo widevine_cdm;
|
base::FilePath flash_path =
|
||||||
widevine_cdm.is_out_of_process = true;
|
command_line->GetSwitchValuePath(switches::kPpapiFlashPath);
|
||||||
widevine_cdm.path = path;
|
if (flash_path.empty())
|
||||||
widevine_cdm.name = kWidevineCdmDisplayName;
|
return;
|
||||||
widevine_cdm.description = kWidevineCdmDescription +
|
|
||||||
std::string(" (version: ") +
|
|
||||||
version + ")";
|
|
||||||
widevine_cdm.version = version;
|
|
||||||
content::WebPluginMimeType widevine_cdm_mime_type(
|
|
||||||
kWidevineCdmPluginMimeType,
|
|
||||||
kWidevineCdmPluginExtension,
|
|
||||||
kWidevineCdmPluginMimeTypeDescription);
|
|
||||||
|
|
||||||
// Add the supported codecs as if they came from the component manifest.
|
auto flash_version =
|
||||||
std::vector<std::string> codecs;
|
command_line->GetSwitchValueASCII(switches::kPpapiFlashVersion);
|
||||||
codecs.push_back(kCdmSupportedCodecVp8);
|
|
||||||
codecs.push_back(kCdmSupportedCodecVp9);
|
|
||||||
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
|
|
||||||
codecs.push_back(kCdmSupportedCodecAvc1);
|
|
||||||
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
|
|
||||||
std::string codec_string = base::JoinString(
|
|
||||||
codecs, std::string(1, kCdmSupportedCodecsValueDelimiter));
|
|
||||||
widevine_cdm_mime_type.additional_param_names.push_back(
|
|
||||||
base::ASCIIToUTF16(kCdmSupportedCodecsParamName));
|
|
||||||
widevine_cdm_mime_type.additional_param_values.push_back(
|
|
||||||
base::ASCIIToUTF16(codec_string));
|
|
||||||
|
|
||||||
widevine_cdm.mime_types.push_back(widevine_cdm_mime_type);
|
plugins->push_back(CreatePepperFlashInfo(flash_path, flash_version));
|
||||||
widevine_cdm.permissions = kWidevineCdmPluginPermissions;
|
|
||||||
|
|
||||||
return widevine_cdm;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif // defined(ENABLE_PEPPER_FLASH)
|
||||||
|
|
||||||
void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||||
|
#if defined(ENABLE_PDF_VIEWER)
|
||||||
content::PepperPluginInfo pdf_info;
|
content::PepperPluginInfo pdf_info;
|
||||||
pdf_info.is_internal = true;
|
pdf_info.is_internal = true;
|
||||||
pdf_info.is_out_of_process = true;
|
pdf_info.is_out_of_process = true;
|
||||||
@@ -127,71 +174,33 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
|||||||
chrome_pdf::PPP_ShutdownModule;
|
chrome_pdf::PPP_ShutdownModule;
|
||||||
pdf_info.permissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV;
|
pdf_info.permissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV;
|
||||||
plugins->push_back(pdf_info);
|
plugins->push_back(pdf_info);
|
||||||
|
#endif // defined(ENABLE_PDF_VIEWER)
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
|
void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
|
||||||
const char* separator,
|
const char* separator,
|
||||||
const char* cmd_switch) {
|
const char* cmd_switch) {
|
||||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||||
auto string_with_separator = command_line->GetSwitchValueASCII(cmd_switch);
|
auto string_with_separator = command_line->GetSwitchValueASCII(cmd_switch);
|
||||||
if (!string_with_separator.empty())
|
if (!string_with_separator.empty())
|
||||||
*vec = base::SplitString(string_with_separator, separator,
|
*vec = base::SplitString(string_with_separator, separator,
|
||||||
base::TRIM_WHITESPACE,
|
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||||
base::SPLIT_WANT_NONEMPTY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void AddPepperFlashFromCommandLine(
|
AtomContentClient::AtomContentClient() {}
|
||||||
std::vector<content::PepperPluginInfo>* plugins) {
|
|
||||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
|
||||||
base::FilePath flash_path = command_line->GetSwitchValuePath(
|
|
||||||
switches::kPpapiFlashPath);
|
|
||||||
if (flash_path.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto flash_version = command_line->GetSwitchValueASCII(
|
AtomContentClient::~AtomContentClient() {}
|
||||||
switches::kPpapiFlashVersion);
|
|
||||||
|
|
||||||
plugins->push_back(CreatePepperFlashInfo(flash_path, flash_version));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
|
|
||||||
void AddWidevineCdmFromCommandLine(
|
|
||||||
std::vector<content::PepperPluginInfo>* plugins) {
|
|
||||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
|
||||||
base::FilePath widevine_cdm_path = command_line->GetSwitchValuePath(
|
|
||||||
switches::kWidevineCdmPath);
|
|
||||||
if (widevine_cdm_path.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!base::PathExists(widevine_cdm_path))
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto widevine_cdm_version = command_line->GetSwitchValueASCII(
|
|
||||||
switches::kWidevineCdmVersion);
|
|
||||||
if (widevine_cdm_version.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
plugins->push_back(CreateWidevineCdmInfo(widevine_cdm_path,
|
|
||||||
widevine_cdm_version));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AtomContentClient::AtomContentClient() {
|
|
||||||
}
|
|
||||||
|
|
||||||
AtomContentClient::~AtomContentClient() {
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string AtomContentClient::GetProduct() const {
|
std::string AtomContentClient::GetProduct() const {
|
||||||
return "Chrome/" CHROME_VERSION_STRING;
|
return "Chrome/" CHROME_VERSION_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AtomContentClient::GetUserAgent() const {
|
std::string AtomContentClient::GetUserAgent() const {
|
||||||
return content::BuildUserAgentFromProduct(
|
return content::BuildUserAgentFromProduct("Chrome/" CHROME_VERSION_STRING
|
||||||
"Chrome/" CHROME_VERSION_STRING " "
|
" " ATOM_PRODUCT_NAME
|
||||||
ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING);
|
"/" ATOM_VERSION_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
|
base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
|
||||||
@@ -215,11 +224,43 @@ void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) {
|
|||||||
|
|
||||||
void AtomContentClient::AddPepperPlugins(
|
void AtomContentClient::AddPepperPlugins(
|
||||||
std::vector<content::PepperPluginInfo>* plugins) {
|
std::vector<content::PepperPluginInfo>* plugins) {
|
||||||
AddPepperFlashFromCommandLine(plugins);
|
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||||
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
|
#if defined(ENABLE_PEPPER_FLASH)
|
||||||
AddWidevineCdmFromCommandLine(plugins);
|
AddPepperFlashFromCommandLine(command_line, plugins);
|
||||||
#endif
|
#endif // defined(ENABLE_PEPPER_FLASH)
|
||||||
|
#if defined(WIDEVINE_CDM_AVAILABLE)
|
||||||
|
AddWidevineAdapterFromCommandLine(command_line, plugins);
|
||||||
|
#endif // defined(WIDEVINE_CDM_AVAILABLE)
|
||||||
ComputeBuiltInPlugins(plugins);
|
ComputeBuiltInPlugins(plugins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AtomContentClient::AddContentDecryptionModules(
|
||||||
|
std::vector<content::CdmInfo>* cdms,
|
||||||
|
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) {
|
||||||
|
if (cdms) {
|
||||||
|
#if defined(WIDEVINE_CDM_AVAILABLE)
|
||||||
|
base::FilePath adapter_path;
|
||||||
|
base::FilePath cdm_path;
|
||||||
|
std::vector<media::VideoCodec> video_codecs_supported;
|
||||||
|
bool supports_persistent_license = false;
|
||||||
|
if (IsWidevineAvailable(&adapter_path, &cdm_path,
|
||||||
|
&video_codecs_supported)) {
|
||||||
|
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||||
|
auto cdm_version_string =
|
||||||
|
command_line->GetSwitchValueASCII(switches::kWidevineCdmVersion);
|
||||||
|
// CdmInfo needs |path| to be the actual Widevine library,
|
||||||
|
// not the adapter, so adjust as necessary. It will be in the
|
||||||
|
// same directory as the installed adapter.
|
||||||
|
const base::Version version(cdm_version_string);
|
||||||
|
DCHECK(version.IsValid());
|
||||||
|
|
||||||
|
cdms->push_back(content::CdmInfo(
|
||||||
|
kWidevineCdmDisplayName, kWidevineCdmGuid, version, cdm_path,
|
||||||
|
kWidevineCdmFileSystemId, video_codecs_supported,
|
||||||
|
supports_persistent_license, kWidevineKeySystem, false));
|
||||||
|
}
|
||||||
|
#endif // defined(WIDEVINE_CDM_AVAILABLE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace atom {
|
|||||||
class AtomContentClient : public brightray::ContentClient {
|
class AtomContentClient : public brightray::ContentClient {
|
||||||
public:
|
public:
|
||||||
AtomContentClient();
|
AtomContentClient();
|
||||||
virtual ~AtomContentClient();
|
~AtomContentClient() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// content::ContentClient:
|
// content::ContentClient:
|
||||||
@@ -26,6 +26,9 @@ class AtomContentClient : public brightray::ContentClient {
|
|||||||
void AddAdditionalSchemes(Schemes* schemes) override;
|
void AddAdditionalSchemes(Schemes* schemes) override;
|
||||||
void AddPepperPlugins(
|
void AddPepperPlugins(
|
||||||
std::vector<content::PepperPluginInfo>* plugins) override;
|
std::vector<content::PepperPluginInfo>* plugins) override;
|
||||||
|
void AddContentDecryptionModules(
|
||||||
|
std::vector<content::CdmInfo>* cdms,
|
||||||
|
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
||||||
|
|||||||
@@ -9,11 +9,13 @@
|
|||||||
|
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
__attribute__((visibility("default")))
|
__attribute__((visibility("default"))) int AtomMain(int argc, char* argv[]);
|
||||||
int AtomMain(int argc, char* argv[]);
|
|
||||||
|
|
||||||
__attribute__((visibility("default")))
|
#ifdef ENABLE_RUN_AS_NODE
|
||||||
int AtomInitializeICUandStartNode(int argc, char *argv[]);
|
__attribute__((visibility("default"))) int AtomInitializeICUandStartNode(
|
||||||
|
int argc,
|
||||||
|
char* argv[]);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif // OS_MACOSX
|
#endif // OS_MACOSX
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
#include "brightray/common/mac/main_application_bundle.h"
|
#include "brightray/common/mac/main_application_bundle.h"
|
||||||
#include "content/public/app/content_main.h"
|
#include "content/public/app/content_main.h"
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
int AtomMain(int argc, char* argv[]) {
|
int AtomMain(int argc, char* argv[]) {
|
||||||
atom::AtomMainDelegate delegate;
|
atom::AtomMainDelegate delegate;
|
||||||
content::ContentMainParams params(&delegate);
|
content::ContentMainParams params(&delegate);
|
||||||
@@ -24,7 +23,8 @@ int AtomMain(int argc, char* argv[]) {
|
|||||||
return content::ContentMain(params);
|
return content::ContentMain(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AtomInitializeICUandStartNode(int argc, char *argv[]) {
|
#ifdef ENABLE_RUN_AS_NODE
|
||||||
|
int AtomInitializeICUandStartNode(int argc, char* argv[]) {
|
||||||
base::AtExitManager atexit_manager;
|
base::AtExitManager atexit_manager;
|
||||||
base::mac::ScopedNSAutoreleasePool pool;
|
base::mac::ScopedNSAutoreleasePool pool;
|
||||||
base::mac::SetOverrideFrameworkBundlePath(
|
base::mac::SetOverrideFrameworkBundlePath(
|
||||||
@@ -35,4 +35,4 @@ int AtomInitializeICUandStartNode(int argc, char *argv[]) {
|
|||||||
base::i18n::InitializeICU();
|
base::i18n::InitializeICU();
|
||||||
return atom::NodeMain(argc, argv);
|
return atom::NodeMain(argc, argv);
|
||||||
}
|
}
|
||||||
#endif // OS_MACOSX
|
#endif
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||||
NSArray* pathComponents = [[[NSBundle mainBundle] bundlePath] pathComponents];
|
NSArray* pathComponents = [[[NSBundle mainBundle] bundlePath] pathComponents];
|
||||||
pathComponents = [pathComponents subarrayWithRange:NSMakeRange(0, [pathComponents count] - 4)];
|
pathComponents = [pathComponents
|
||||||
|
subarrayWithRange:NSMakeRange(0, [pathComponents count] - 4)];
|
||||||
NSString* path = [NSString pathWithComponents:pathComponents];
|
NSString* path = [NSString pathWithComponents:pathComponents];
|
||||||
[[NSWorkspace sharedWorkspace] launchApplication:path];
|
[[NSWorkspace sharedWorkspace] launchApplication:path];
|
||||||
[pool drain];
|
[pool drain];
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#include "base/win/windows_version.h"
|
#include "base/win/windows_version.h"
|
||||||
#include "content/public/app/sandbox_helper_win.h"
|
#include "content/public/app/sandbox_helper_win.h"
|
||||||
#include "sandbox/win/src/sandbox_types.h"
|
#include "sandbox/win/src/sandbox_types.h"
|
||||||
#elif defined(OS_LINUX) // defined(OS_WIN)
|
#elif defined(OS_LINUX) // defined(OS_WIN)
|
||||||
#include "atom/app/atom_main_delegate.h" // NOLINT
|
#include "atom/app/atom_main_delegate.h" // NOLINT
|
||||||
#include "content/public/app/content_main.h"
|
#include "content/public/app/content_main.h"
|
||||||
#else // defined(OS_LINUX)
|
#else // defined(OS_LINUX)
|
||||||
@@ -39,9 +39,10 @@
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#ifdef ENABLE_RUN_AS_NODE
|
#ifdef ENABLE_RUN_AS_NODE
|
||||||
const auto kRunAsNode = "ELECTRON_RUN_AS_NODE";
|
const char kRunAsNode[] = "ELECTRON_RUN_AS_NODE";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(ENABLE_RUN_AS_NODE) || defined(OS_WIN)
|
||||||
bool IsEnvSet(const char* name) {
|
bool IsEnvSet(const char* name) {
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
size_t required_size;
|
size_t required_size;
|
||||||
@@ -52,6 +53,7 @@ bool IsEnvSet(const char* name) {
|
|||||||
return indicator && indicator[0] != '\0';
|
return indicator && indicator[0] != '\0';
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -115,9 +117,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
|||||||
// from within the CRT's atexit facility, ensuring the heap functions are
|
// from within the CRT's atexit facility, ensuring the heap functions are
|
||||||
// still active. The second invocation from the OS loader will be a no-op.
|
// still active. The second invocation from the OS loader will be a no-op.
|
||||||
extern void NTAPI OnThreadExit(PVOID module, DWORD reason, PVOID reserved);
|
extern void NTAPI OnThreadExit(PVOID module, DWORD reason, PVOID reserved);
|
||||||
atexit([]() {
|
atexit([]() { OnThreadExit(nullptr, DLL_THREAD_DETACH, nullptr); });
|
||||||
OnThreadExit(nullptr, DLL_THREAD_DETACH, nullptr);
|
|
||||||
});
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_RUN_AS_NODE
|
#ifdef ENABLE_RUN_AS_NODE
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "chrome/common/chrome_paths.h"
|
#include "chrome/common/chrome_paths.h"
|
||||||
#include "content/public/common/content_switches.h"
|
#include "content/public/common/content_switches.h"
|
||||||
#include "ipc/ipc_features.h"
|
#include "ipc/ipc_features.h"
|
||||||
|
#include "services/service_manager/sandbox/switches.h"
|
||||||
#include "ui/base/l10n/l10n_util.h"
|
#include "ui/base/l10n/l10n_util.h"
|
||||||
#include "ui/base/resource/resource_bundle.h"
|
#include "ui/base/resource/resource_bundle.h"
|
||||||
|
|
||||||
@@ -45,22 +46,23 @@ bool IsBrowserProcess(base::CommandLine* cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
void InvalidParameterHandler(const wchar_t*, const wchar_t*, const wchar_t*,
|
void InvalidParameterHandler(const wchar_t*,
|
||||||
unsigned int, uintptr_t) {
|
const wchar_t*,
|
||||||
|
const wchar_t*,
|
||||||
|
unsigned int,
|
||||||
|
uintptr_t) {
|
||||||
// noop.
|
// noop.
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
AtomMainDelegate::AtomMainDelegate() {
|
AtomMainDelegate::AtomMainDelegate() {}
|
||||||
}
|
|
||||||
|
|
||||||
AtomMainDelegate::~AtomMainDelegate() {
|
AtomMainDelegate::~AtomMainDelegate() {}
|
||||||
}
|
|
||||||
|
|
||||||
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||||
|
|
||||||
logging::LoggingSettings settings;
|
logging::LoggingSettings settings;
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
@@ -77,12 +79,12 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
|||||||
#else
|
#else
|
||||||
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
||||||
#endif // defined(DEBUG)
|
#endif // defined(DEBUG)
|
||||||
#else // defined(OS_WIN)
|
#else // defined(OS_WIN)
|
||||||
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
||||||
#endif // !defined(OS_WIN)
|
#endif // !defined(OS_WIN)
|
||||||
|
|
||||||
// Only enable logging when --enable-logging is specified.
|
// Only enable logging when --enable-logging is specified.
|
||||||
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
auto env = base::Environment::Create();
|
||||||
if (!command_line->HasSwitch(::switches::kEnableLogging) &&
|
if (!command_line->HasSwitch(::switches::kEnableLogging) &&
|
||||||
!env->HasVar("ELECTRON_ENABLE_LOGGING")) {
|
!env->HasVar("ELECTRON_ENABLE_LOGGING")) {
|
||||||
settings.logging_dest = logging::LOG_NONE;
|
settings.logging_dest = logging::LOG_NONE;
|
||||||
@@ -99,6 +101,11 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
|||||||
bool enable_stack_dumping = true;
|
bool enable_stack_dumping = true;
|
||||||
#else
|
#else
|
||||||
bool enable_stack_dumping = env->HasVar("ELECTRON_ENABLE_STACK_DUMPING");
|
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
|
#endif
|
||||||
if (enable_stack_dumping)
|
if (enable_stack_dumping)
|
||||||
base::debug::EnableInProcessStackDumping();
|
base::debug::EnableInProcessStackDumping();
|
||||||
@@ -123,14 +130,9 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
|||||||
void AtomMainDelegate::PreSandboxStartup() {
|
void AtomMainDelegate::PreSandboxStartup() {
|
||||||
brightray::MainDelegate::PreSandboxStartup();
|
brightray::MainDelegate::PreSandboxStartup();
|
||||||
|
|
||||||
// Set google API key.
|
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||||
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
std::string process_type =
|
||||||
if (!env->HasVar("GOOGLE_API_KEY"))
|
command_line->GetSwitchValueASCII(::switches::kProcessType);
|
||||||
env->SetVar("GOOGLE_API_KEY", GOOGLEAPIS_API_KEY);
|
|
||||||
|
|
||||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
|
||||||
std::string process_type = command_line->GetSwitchValueASCII(
|
|
||||||
::switches::kProcessType);
|
|
||||||
|
|
||||||
// Only append arguments for browser process.
|
// Only append arguments for browser process.
|
||||||
if (!IsBrowserProcess(command_line))
|
if (!IsBrowserProcess(command_line))
|
||||||
@@ -140,7 +142,8 @@ void AtomMainDelegate::PreSandboxStartup() {
|
|||||||
if (command_line->HasSwitch(switches::kEnableSandbox)) {
|
if (command_line->HasSwitch(switches::kEnableSandbox)) {
|
||||||
// Disable setuid sandbox since it is not longer required on
|
// Disable setuid sandbox since it is not longer required on
|
||||||
// linux(namespace sandbox is available on most distros).
|
// linux(namespace sandbox is available on most distros).
|
||||||
command_line->AppendSwitch(::switches::kDisableSetuidSandbox);
|
command_line->AppendSwitch(
|
||||||
|
service_manager::switches::kDisableSetuidSandbox);
|
||||||
} else {
|
} else {
|
||||||
// Disable renderer sandbox for most of node's functions.
|
// Disable renderer sandbox for most of node's functions.
|
||||||
command_line->AppendSwitch(::switches::kNoSandbox);
|
command_line->AppendSwitch(::switches::kNoSandbox);
|
||||||
@@ -162,11 +165,11 @@ content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
content::ContentRendererClient*
|
content::ContentRendererClient*
|
||||||
AtomMainDelegate::CreateContentRendererClient() {
|
AtomMainDelegate::CreateContentRendererClient() {
|
||||||
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||||
switches::kEnableSandbox) ||
|
switches::kEnableSandbox) ||
|
||||||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||||
::switches::kNoSandbox)) {
|
::switches::kNoSandbox)) {
|
||||||
renderer_client_.reset(new AtomSandboxedRendererClient);
|
renderer_client_.reset(new AtomSandboxedRendererClient);
|
||||||
} else {
|
} else {
|
||||||
renderer_client_.reset(new AtomRendererClient);
|
renderer_client_.reset(new AtomRendererClient);
|
||||||
@@ -202,7 +205,7 @@ bool AtomMainDelegate::DelaySandboxInitialization(
|
|||||||
|
|
||||||
std::unique_ptr<brightray::ContentClient>
|
std::unique_ptr<brightray::ContentClient>
|
||||||
AtomMainDelegate::CreateContentClient() {
|
AtomMainDelegate::CreateContentClient() {
|
||||||
return std::unique_ptr<brightray::ContentClient>(new AtomContentClient);
|
return std::make_unique<AtomContentClient>();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace atom {
|
|||||||
class AtomMainDelegate : public brightray::MainDelegate {
|
class AtomMainDelegate : public brightray::MainDelegate {
|
||||||
public:
|
public:
|
||||||
AtomMainDelegate();
|
AtomMainDelegate();
|
||||||
~AtomMainDelegate();
|
~AtomMainDelegate() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// content::ContentMainDelegate:
|
// content::ContentMainDelegate:
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
#include "atom/app/atom_main_delegate.h"
|
#include "atom/app/atom_main_delegate.h"
|
||||||
|
|
||||||
#include "base/mac/bundle_locations.h"
|
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/files/file_util.h"
|
#include "base/files/file_util.h"
|
||||||
|
#include "base/mac/bundle_locations.h"
|
||||||
#include "base/mac/foundation_util.h"
|
#include "base/mac/foundation_util.h"
|
||||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
#include "base/mac/scoped_nsautorelease_pool.h"
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
@@ -20,16 +20,17 @@ namespace atom {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
base::FilePath GetFrameworksPath() {
|
base::FilePath GetFrameworksPath() {
|
||||||
return brightray::MainApplicationBundlePath().Append("Contents")
|
return brightray::MainApplicationBundlePath()
|
||||||
.Append("Frameworks");
|
.Append("Contents")
|
||||||
|
.Append("Frameworks");
|
||||||
}
|
}
|
||||||
|
|
||||||
base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
|
base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
|
||||||
const std::string& name) {
|
const std::string& name) {
|
||||||
return frameworks_path.Append(name + " Helper.app")
|
return frameworks_path.Append(name + " Helper.app")
|
||||||
.Append("Contents")
|
.Append("Contents")
|
||||||
.Append("MacOS")
|
.Append("MacOS")
|
||||||
.Append(name + " Helper");
|
.Append(name + " Helper");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -41,11 +42,11 @@ void AtomMainDelegate::OverrideFrameworkBundlePath() {
|
|||||||
|
|
||||||
void AtomMainDelegate::OverrideChildProcessPath() {
|
void AtomMainDelegate::OverrideChildProcessPath() {
|
||||||
base::FilePath frameworks_path = GetFrameworksPath();
|
base::FilePath frameworks_path = GetFrameworksPath();
|
||||||
base::FilePath helper_path = GetHelperAppPath(frameworks_path,
|
base::FilePath helper_path =
|
||||||
ATOM_PRODUCT_NAME);
|
GetHelperAppPath(frameworks_path, ATOM_PRODUCT_NAME);
|
||||||
if (!base::PathExists(helper_path))
|
if (!base::PathExists(helper_path))
|
||||||
helper_path = GetHelperAppPath(frameworks_path,
|
helper_path =
|
||||||
brightray::GetApplicationName());
|
GetHelperAppPath(frameworks_path, brightray::GetApplicationName());
|
||||||
if (!base::PathExists(helper_path))
|
if (!base::PathExists(helper_path))
|
||||||
LOG(FATAL) << "Unable to find helper app";
|
LOG(FATAL) << "Unable to find helper app";
|
||||||
PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
|
PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -14,4 +14,3 @@ bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv);
|
|||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
||||||
#endif // ATOM_APP_COMMAND_LINE_ARGS_H_
|
#endif // ATOM_APP_COMMAND_LINE_ARGS_H_
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "atom/common/api/atom_bindings.h"
|
#include "atom/common/api/atom_bindings.h"
|
||||||
#include "atom/common/crash_reporter/crash_reporter.h"
|
#include "atom/common/crash_reporter/crash_reporter.h"
|
||||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||||
|
#include "atom/common/node_bindings.h"
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
#include "base/feature_list.h"
|
#include "base/feature_list.h"
|
||||||
#include "base/task_scheduler/task_scheduler.h"
|
#include "base/task_scheduler/task_scheduler.h"
|
||||||
@@ -25,7 +26,7 @@
|
|||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
int NodeMain(int argc, char *argv[]) {
|
int NodeMain(int argc, char* argv[]) {
|
||||||
base::CommandLine::Init(argc, argv);
|
base::CommandLine::Init(argc, argv);
|
||||||
|
|
||||||
int exit_code = 1;
|
int exit_code = 1;
|
||||||
@@ -37,11 +38,12 @@ int NodeMain(int argc, char *argv[]) {
|
|||||||
base::ThreadTaskRunnerHandle handle(uv_task_runner);
|
base::ThreadTaskRunnerHandle handle(uv_task_runner);
|
||||||
|
|
||||||
// Initialize feature list.
|
// Initialize feature list.
|
||||||
std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
|
auto feature_list = std::make_unique<base::FeatureList>();
|
||||||
feature_list->InitializeFromCommandLine("", "");
|
feature_list->InitializeFromCommandLine("", "");
|
||||||
base::FeatureList::SetInstance(std::move(feature_list));
|
base::FeatureList::SetInstance(std::move(feature_list));
|
||||||
|
|
||||||
gin::V8Initializer::LoadV8Snapshot();
|
gin::V8Initializer::LoadV8Snapshot(
|
||||||
|
gin::V8Initializer::V8SnapshotFileType::kWithAdditionalContext);
|
||||||
gin::V8Initializer::LoadV8Natives();
|
gin::V8Initializer::LoadV8Natives();
|
||||||
|
|
||||||
// V8 requires a task scheduler apparently
|
// V8 requires a task scheduler apparently
|
||||||
@@ -50,14 +52,16 @@ int NodeMain(int argc, char *argv[]) {
|
|||||||
// Initialize gin::IsolateHolder.
|
// Initialize gin::IsolateHolder.
|
||||||
JavascriptEnvironment gin_env;
|
JavascriptEnvironment gin_env;
|
||||||
|
|
||||||
|
// Explicitly register electron's builtin modules.
|
||||||
|
NodeBindings::RegisterBuiltinModules();
|
||||||
|
|
||||||
int exec_argc;
|
int exec_argc;
|
||||||
const char** exec_argv;
|
const char** exec_argv;
|
||||||
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
|
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
|
||||||
|
|
||||||
node::IsolateData isolate_data(gin_env.isolate(), loop);
|
|
||||||
node::Environment* env = node::CreateEnvironment(
|
node::Environment* env = node::CreateEnvironment(
|
||||||
&isolate_data, gin_env.context(), argc, argv,
|
node::CreateIsolateData(gin_env.isolate(), loop, gin_env.platform()),
|
||||||
exec_argc, exec_argv);
|
gin_env.context(), argc, argv, exec_argc, exec_argv);
|
||||||
|
|
||||||
// Enable support for v8 inspector.
|
// Enable support for v8 inspector.
|
||||||
NodeDebugger node_debugger(env);
|
NodeDebugger node_debugger(env);
|
||||||
@@ -79,6 +83,7 @@ int NodeMain(int argc, char *argv[]) {
|
|||||||
bool more;
|
bool more;
|
||||||
do {
|
do {
|
||||||
more = uv_run(env->event_loop(), UV_RUN_ONCE);
|
more = uv_run(env->event_loop(), UV_RUN_ONCE);
|
||||||
|
gin_env.platform()->DrainBackgroundTasks(env->isolate());
|
||||||
if (more == false) {
|
if (more == false) {
|
||||||
node::EmitBeforeExit(env);
|
node::EmitBeforeExit(env);
|
||||||
|
|
||||||
@@ -92,6 +97,8 @@ int NodeMain(int argc, char *argv[]) {
|
|||||||
|
|
||||||
exit_code = node::EmitExit(env);
|
exit_code = node::EmitExit(env);
|
||||||
node::RunAtExit(env);
|
node::RunAtExit(env);
|
||||||
|
gin_env.platform()->DrainBackgroundTasks(env->isolate());
|
||||||
|
gin_env.platform()->CancelPendingDelayedTasks(env->isolate());
|
||||||
|
|
||||||
node::FreeEnvironment(env);
|
node::FreeEnvironment(env);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
int NodeMain(int argc, char *argv[]);
|
int NodeMain(int argc, char* argv[]);
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,7 @@
|
|||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
UvTaskRunner::UvTaskRunner(uv_loop_t* loop) : loop_(loop) {
|
UvTaskRunner::UvTaskRunner(uv_loop_t* loop) : loop_(loop) {}
|
||||||
}
|
|
||||||
|
|
||||||
UvTaskRunner::~UvTaskRunner() {
|
UvTaskRunner::~UvTaskRunner() {
|
||||||
for (auto& iter : tasks_) {
|
for (auto& iter : tasks_) {
|
||||||
@@ -20,7 +19,7 @@ UvTaskRunner::~UvTaskRunner() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UvTaskRunner::PostDelayedTask(const tracked_objects::Location& from_here,
|
bool UvTaskRunner::PostDelayedTask(const base::Location& from_here,
|
||||||
base::OnceClosure task,
|
base::OnceClosure task,
|
||||||
base::TimeDelta delay) {
|
base::TimeDelta delay) {
|
||||||
auto* timer = new uv_timer_t;
|
auto* timer = new uv_timer_t;
|
||||||
@@ -35,10 +34,9 @@ bool UvTaskRunner::RunsTasksInCurrentSequence() const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UvTaskRunner::PostNonNestableDelayedTask(
|
bool UvTaskRunner::PostNonNestableDelayedTask(const base::Location& from_here,
|
||||||
const tracked_objects::Location& from_here,
|
base::OnceClosure task,
|
||||||
base::OnceClosure task,
|
base::TimeDelta delay) {
|
||||||
base::TimeDelta delay) {
|
|
||||||
return PostDelayedTask(from_here, std::move(task), delay);
|
return PostDelayedTask(from_here, std::move(task), delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,9 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "base/callback.h"
|
#include "base/callback.h"
|
||||||
|
#include "base/location.h"
|
||||||
#include "base/single_thread_task_runner.h"
|
#include "base/single_thread_task_runner.h"
|
||||||
#include "vendor/node/deps/uv/include/uv.h"
|
#include "uv.h" // NOLINT(build/include)
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
@@ -17,19 +18,18 @@ namespace atom {
|
|||||||
class UvTaskRunner : public base::SingleThreadTaskRunner {
|
class UvTaskRunner : public base::SingleThreadTaskRunner {
|
||||||
public:
|
public:
|
||||||
explicit UvTaskRunner(uv_loop_t* loop);
|
explicit UvTaskRunner(uv_loop_t* loop);
|
||||||
~UvTaskRunner() override;
|
|
||||||
|
|
||||||
// base::SingleThreadTaskRunner:
|
// base::SingleThreadTaskRunner:
|
||||||
bool PostDelayedTask(const tracked_objects::Location& from_here,
|
bool PostDelayedTask(const base::Location& from_here,
|
||||||
base::OnceClosure task,
|
base::OnceClosure task,
|
||||||
base::TimeDelta delay) override;
|
base::TimeDelta delay) override;
|
||||||
bool RunsTasksInCurrentSequence() const override;
|
bool RunsTasksInCurrentSequence() const override;
|
||||||
bool PostNonNestableDelayedTask(
|
bool PostNonNestableDelayedTask(const base::Location& from_here,
|
||||||
const tracked_objects::Location& from_here,
|
base::OnceClosure task,
|
||||||
base::OnceClosure task,
|
base::TimeDelta delay) override;
|
||||||
base::TimeDelta delay) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
~UvTaskRunner() override;
|
||||||
static void OnTimeout(uv_timer_t* timer);
|
static void OnTimeout(uv_timer_t* timer);
|
||||||
static void OnClose(uv_handle_t* handle);
|
static void OnClose(uv_handle_t* handle);
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||||
#include "atom/common/native_mate_converters/image_converter.h"
|
#include "atom/common/native_mate_converters/image_converter.h"
|
||||||
#include "atom/common/native_mate_converters/net_converter.h"
|
#include "atom/common/native_mate_converters/net_converter.h"
|
||||||
|
#include "atom/common/native_mate_converters/network_converter.h"
|
||||||
#include "atom/common/native_mate_converters/value_converter.h"
|
#include "atom/common/native_mate_converters/value_converter.h"
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
#include "atom/common/options_switches.h"
|
#include "atom/common/options_switches.h"
|
||||||
@@ -47,6 +48,7 @@
|
|||||||
#include "native_mate/object_template_builder.h"
|
#include "native_mate/object_template_builder.h"
|
||||||
#include "net/ssl/client_cert_identity.h"
|
#include "net/ssl/client_cert_identity.h"
|
||||||
#include "net/ssl/ssl_cert_request_info.h"
|
#include "net/ssl/ssl_cert_request_info.h"
|
||||||
|
#include "services/network/public/cpp/network_switches.h"
|
||||||
#include "ui/base/l10n/l10n_util.h"
|
#include "ui/base/l10n/l10n_util.h"
|
||||||
#include "ui/gfx/image/image.h"
|
#include "ui/gfx/image/image.h"
|
||||||
|
|
||||||
@@ -64,9 +66,10 @@ using atom::Browser;
|
|||||||
namespace mate {
|
namespace mate {
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
template<>
|
template <>
|
||||||
struct Converter<Browser::UserTask> {
|
struct Converter<Browser::UserTask> {
|
||||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Value> val,
|
||||||
Browser::UserTask* out) {
|
Browser::UserTask* out) {
|
||||||
mate::Dictionary dict;
|
mate::Dictionary dict;
|
||||||
if (!ConvertFromV8(isolate, val, &dict))
|
if (!ConvertFromV8(isolate, val, &dict))
|
||||||
@@ -83,13 +86,14 @@ struct Converter<Browser::UserTask> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using atom::JumpListItem;
|
|
||||||
using atom::JumpListCategory;
|
using atom::JumpListCategory;
|
||||||
|
using atom::JumpListItem;
|
||||||
using atom::JumpListResult;
|
using atom::JumpListResult;
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<JumpListItem::Type> {
|
struct Converter<JumpListItem::Type> {
|
||||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Value> val,
|
||||||
JumpListItem::Type* out) {
|
JumpListItem::Type* out) {
|
||||||
std::string item_type;
|
std::string item_type;
|
||||||
if (!ConvertFromV8(isolate, val, &item_type))
|
if (!ConvertFromV8(isolate, val, &item_type))
|
||||||
@@ -127,9 +131,10 @@ struct Converter<JumpListItem::Type> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<JumpListItem> {
|
struct Converter<JumpListItem> {
|
||||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Value> val,
|
||||||
JumpListItem* out) {
|
JumpListItem* out) {
|
||||||
mate::Dictionary dict;
|
mate::Dictionary dict;
|
||||||
if (!ConvertFromV8(isolate, val, &dict))
|
if (!ConvertFromV8(isolate, val, &dict))
|
||||||
@@ -189,9 +194,10 @@ struct Converter<JumpListItem> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<JumpListCategory::Type> {
|
struct Converter<JumpListCategory::Type> {
|
||||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Value> val,
|
||||||
JumpListCategory::Type* out) {
|
JumpListCategory::Type* out) {
|
||||||
std::string category_type;
|
std::string category_type;
|
||||||
if (!ConvertFromV8(isolate, val, &category_type))
|
if (!ConvertFromV8(isolate, val, &category_type))
|
||||||
@@ -235,9 +241,10 @@ struct Converter<JumpListCategory::Type> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<JumpListCategory> {
|
struct Converter<JumpListCategory> {
|
||||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Value> val,
|
||||||
JumpListCategory* out) {
|
JumpListCategory* out) {
|
||||||
mate::Dictionary dict;
|
mate::Dictionary dict;
|
||||||
if (!ConvertFromV8(isolate, val, &dict))
|
if (!ConvertFromV8(isolate, val, &dict))
|
||||||
@@ -264,7 +271,7 @@ struct Converter<JumpListCategory> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// static
|
// static
|
||||||
template<>
|
template <>
|
||||||
struct Converter<JumpListResult> {
|
struct Converter<JumpListResult> {
|
||||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, JumpListResult val) {
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, JumpListResult val) {
|
||||||
std::string result_code;
|
std::string result_code;
|
||||||
@@ -298,9 +305,10 @@ struct Converter<JumpListResult> {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<Browser::LoginItemSettings> {
|
struct Converter<Browser::LoginItemSettings> {
|
||||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Value> val,
|
||||||
Browser::LoginItemSettings* out) {
|
Browser::LoginItemSettings* out) {
|
||||||
mate::Dictionary dict;
|
mate::Dictionary dict;
|
||||||
if (!ConvertFromV8(isolate, val, &dict))
|
if (!ConvertFromV8(isolate, val, &dict))
|
||||||
@@ -325,15 +333,16 @@ struct Converter<Browser::LoginItemSettings> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<content::CertificateRequestResultType> {
|
struct Converter<content::CertificateRequestResultType> {
|
||||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Value> val,
|
||||||
content::CertificateRequestResultType* out) {
|
content::CertificateRequestResultType* out) {
|
||||||
bool b;
|
bool b;
|
||||||
if (!ConvertFromV8(isolate, val, &b))
|
if (!ConvertFromV8(isolate, val, &b))
|
||||||
return false;
|
return false;
|
||||||
*out = b ? content::CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE :
|
*out = b ? content::CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE
|
||||||
content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL;
|
: content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -342,6 +351,16 @@ struct Converter<content::CertificateRequestResultType> {
|
|||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
ProcessMetric::ProcessMetric(int type,
|
||||||
|
base::ProcessId pid,
|
||||||
|
std::unique_ptr<base::ProcessMetrics> metrics) {
|
||||||
|
this->type = type;
|
||||||
|
this->pid = pid;
|
||||||
|
this->metrics = std::move(metrics);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessMetric::~ProcessMetric() = default;
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -405,7 +424,9 @@ int GetPathConstant(const std::string& name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool NotificationCallbackWrapper(
|
bool NotificationCallbackWrapper(
|
||||||
const ProcessSingleton::NotificationCallback& callback,
|
const base::Callback<
|
||||||
|
void(const base::CommandLine::StringVector& command_line,
|
||||||
|
const base::FilePath& current_directory)>& callback,
|
||||||
const base::CommandLine::StringVector& cmd,
|
const base::CommandLine::StringVector& cmd,
|
||||||
const base::FilePath& cwd) {
|
const base::FilePath& cwd) {
|
||||||
// Make sure the callback is called after app gets ready.
|
// Make sure the callback is called after app gets ready.
|
||||||
@@ -415,7 +436,7 @@ bool NotificationCallbackWrapper(
|
|||||||
scoped_refptr<base::SingleThreadTaskRunner> task_runner(
|
scoped_refptr<base::SingleThreadTaskRunner> task_runner(
|
||||||
base::ThreadTaskRunnerHandle::Get());
|
base::ThreadTaskRunnerHandle::Get());
|
||||||
task_runner->PostTask(
|
task_runner->PostTask(
|
||||||
FROM_HERE, base::Bind(base::IgnoreResult(callback), cmd, cwd));
|
FROM_HERE, base::BindOnce(base::IgnoreResult(callback), cmd, cwd));
|
||||||
}
|
}
|
||||||
// ProcessSingleton needs to know whether current process is quiting.
|
// ProcessSingleton needs to know whether current process is quiting.
|
||||||
return !Browser::Get()->is_shutting_down();
|
return !Browser::Get()->is_shutting_down();
|
||||||
@@ -479,12 +500,11 @@ void PassLoginInformation(scoped_refptr<LoginHandler> login_handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_NSS_CERTS)
|
#if defined(USE_NSS_CERTS)
|
||||||
int ImportIntoCertStore(
|
int ImportIntoCertStore(CertificateManagerModel* model,
|
||||||
CertificateManagerModel* model,
|
const base::DictionaryValue& options) {
|
||||||
const base::DictionaryValue& options) {
|
|
||||||
std::string file_data, cert_path;
|
std::string file_data, cert_path;
|
||||||
base::string16 password;
|
base::string16 password;
|
||||||
net::CertificateList imported_certs;
|
net::ScopedCERTCertificateList imported_certs;
|
||||||
int rv = -1;
|
int rv = -1;
|
||||||
options.GetString("certificate", &cert_path);
|
options.GetString("certificate", &cert_path);
|
||||||
options.GetString("password", &password);
|
options.GetString("password", &password);
|
||||||
@@ -492,17 +512,13 @@ int ImportIntoCertStore(
|
|||||||
if (!cert_path.empty()) {
|
if (!cert_path.empty()) {
|
||||||
if (base::ReadFileToString(base::FilePath(cert_path), &file_data)) {
|
if (base::ReadFileToString(base::FilePath(cert_path), &file_data)) {
|
||||||
auto module = model->cert_db()->GetPrivateSlot();
|
auto module = model->cert_db()->GetPrivateSlot();
|
||||||
rv = model->ImportFromPKCS12(module.get(),
|
rv = model->ImportFromPKCS12(module.get(), file_data, password, true,
|
||||||
file_data,
|
|
||||||
password,
|
|
||||||
true,
|
|
||||||
&imported_certs);
|
&imported_certs);
|
||||||
if (imported_certs.size() > 1) {
|
if (imported_certs.size() > 1) {
|
||||||
auto it = imported_certs.begin();
|
auto it = imported_certs.begin();
|
||||||
++it; // skip first which would be the client certificate.
|
++it; // skip first which would be the client certificate.
|
||||||
for (; it != imported_certs.end(); ++it)
|
for (; it != imported_certs.end(); ++it)
|
||||||
rv &= model->SetCertTrust(it->get(),
|
rv &= model->SetCertTrust(it->get(), net::CA_CERT,
|
||||||
net::CA_CERT,
|
|
||||||
net::NSSCertDatabase::TRUSTED_SSL);
|
net::NSSCertDatabase::TRUSTED_SSL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -521,7 +537,7 @@ void OnIconDataAvailable(v8::Isolate* isolate,
|
|||||||
callback.Run(v8::Null(isolate), *icon);
|
callback.Run(v8::Null(isolate), *icon);
|
||||||
} else {
|
} else {
|
||||||
v8::Local<v8::String> error_message =
|
v8::Local<v8::String> error_message =
|
||||||
v8::String::NewFromUtf8(isolate, "Failed to get file icon.");
|
v8::String::NewFromUtf8(isolate, "Failed to get file icon.");
|
||||||
callback.Run(v8::Exception::Error(error_message), gfx::Image());
|
callback.Run(v8::Exception::Error(error_message), gfx::Image());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -533,29 +549,31 @@ App::App(v8::Isolate* isolate) {
|
|||||||
Browser::Get()->AddObserver(this);
|
Browser::Get()->AddObserver(this);
|
||||||
content::GpuDataManager::GetInstance()->AddObserver(this);
|
content::GpuDataManager::GetInstance()->AddObserver(this);
|
||||||
base::ProcessId pid = base::GetCurrentProcId();
|
base::ProcessId pid = base::GetCurrentProcId();
|
||||||
std::unique_ptr<atom::ProcessMetric> process_metric(
|
auto process_metric = std::make_unique<atom::ProcessMetric>(
|
||||||
new atom::ProcessMetric(
|
content::PROCESS_TYPE_BROWSER, pid,
|
||||||
content::PROCESS_TYPE_BROWSER,
|
base::ProcessMetrics::CreateCurrentProcessMetrics());
|
||||||
pid,
|
|
||||||
base::ProcessMetrics::CreateCurrentProcessMetrics()));
|
|
||||||
app_metrics_[pid] = std::move(process_metric);
|
app_metrics_[pid] = std::move(process_metric);
|
||||||
Init(isolate);
|
Init(isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
App::~App() {
|
App::~App() {
|
||||||
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())->set_delegate(
|
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())
|
||||||
nullptr);
|
->set_delegate(nullptr);
|
||||||
Browser::Get()->RemoveObserver(this);
|
Browser::Get()->RemoveObserver(this);
|
||||||
content::GpuDataManager::GetInstance()->RemoveObserver(this);
|
content::GpuDataManager::GetInstance()->RemoveObserver(this);
|
||||||
content::BrowserChildProcessObserver::Remove(this);
|
content::BrowserChildProcessObserver::Remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::OnBeforeQuit(bool* prevent_default) {
|
void App::OnBeforeQuit(bool* prevent_default) {
|
||||||
*prevent_default = Emit("before-quit");
|
if (Emit("before-quit")) {
|
||||||
|
*prevent_default = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::OnWillQuit(bool* prevent_default) {
|
void App::OnWillQuit(bool* prevent_default) {
|
||||||
*prevent_default = Emit("will-quit");
|
if (Emit("will-quit")) {
|
||||||
|
*prevent_default = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::OnWindowAllClosed() {
|
void App::OnWindowAllClosed() {
|
||||||
@@ -573,7 +591,9 @@ void App::OnQuit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void App::OnOpenFile(bool* prevent_default, const std::string& file_path) {
|
void App::OnOpenFile(bool* prevent_default, const std::string& file_path) {
|
||||||
*prevent_default = Emit("open-file", file_path);
|
if (Emit("open-file", file_path)) {
|
||||||
|
*prevent_default = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::OnOpenURL(const std::string& url) {
|
void App::OnOpenURL(const std::string& url) {
|
||||||
@@ -609,36 +629,37 @@ void App::OnAccessibilitySupportChanged() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
void App::OnWillContinueUserActivity(
|
void App::OnWillContinueUserActivity(bool* prevent_default,
|
||||||
bool* prevent_default,
|
const std::string& type) {
|
||||||
const std::string& type) {
|
if (Emit("will-continue-activity", type)) {
|
||||||
*prevent_default = Emit("will-continue-activity", type);
|
*prevent_default = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::OnDidFailToContinueUserActivity(
|
void App::OnDidFailToContinueUserActivity(const std::string& type,
|
||||||
const std::string& type,
|
const std::string& error) {
|
||||||
const std::string& error) {
|
|
||||||
Emit("continue-activity-error", type, error);
|
Emit("continue-activity-error", type, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::OnContinueUserActivity(
|
void App::OnContinueUserActivity(bool* prevent_default,
|
||||||
bool* prevent_default,
|
const std::string& type,
|
||||||
const std::string& type,
|
const base::DictionaryValue& user_info) {
|
||||||
const base::DictionaryValue& user_info) {
|
if (Emit("continue-activity", type, user_info)) {
|
||||||
*prevent_default = Emit("continue-activity", type, user_info);
|
*prevent_default = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::OnUserActivityWasContinued(
|
void App::OnUserActivityWasContinued(const std::string& type,
|
||||||
const std::string& type,
|
const base::DictionaryValue& user_info) {
|
||||||
const base::DictionaryValue& user_info) {
|
|
||||||
Emit("activity-was-continued", type, user_info);
|
Emit("activity-was-continued", type, user_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::OnUpdateUserActivityState(
|
void App::OnUpdateUserActivityState(bool* prevent_default,
|
||||||
bool* prevent_default,
|
const std::string& type,
|
||||||
const std::string& type,
|
const base::DictionaryValue& user_info) {
|
||||||
const base::DictionaryValue& user_info) {
|
if (Emit("update-activity-state", type, user_info)) {
|
||||||
*prevent_default = Emit("update-activity-state", type, user_info);
|
*prevent_default = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::OnNewWindowForTab() {
|
void App::OnNewWindowForTab() {
|
||||||
@@ -646,20 +667,17 @@ void App::OnNewWindowForTab() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void App::OnLogin(LoginHandler* login_handler,
|
void App::OnLogin(scoped_refptr<LoginHandler> login_handler,
|
||||||
const base::DictionaryValue& request_details) {
|
const base::DictionaryValue& request_details) {
|
||||||
v8::Locker locker(isolate());
|
v8::Locker locker(isolate());
|
||||||
v8::HandleScope handle_scope(isolate());
|
v8::HandleScope handle_scope(isolate());
|
||||||
bool prevent_default = false;
|
bool prevent_default = false;
|
||||||
content::WebContents* web_contents = login_handler->GetWebContents();
|
content::WebContents* web_contents = login_handler->GetWebContents();
|
||||||
if (web_contents) {
|
if (web_contents) {
|
||||||
prevent_default =
|
prevent_default = Emit(
|
||||||
Emit("login",
|
"login", WebContents::CreateFrom(isolate(), web_contents),
|
||||||
WebContents::CreateFrom(isolate(), web_contents),
|
request_details, login_handler->auth_info(),
|
||||||
request_details,
|
base::Bind(&PassLoginInformation, base::RetainedRef(login_handler)));
|
||||||
login_handler->auth_info(),
|
|
||||||
base::Bind(&PassLoginInformation,
|
|
||||||
make_scoped_refptr(login_handler)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default behavior is to always cancel the auth.
|
// Default behavior is to always cancel the auth.
|
||||||
@@ -679,7 +697,7 @@ bool App::CanCreateWindow(
|
|||||||
WindowOpenDisposition disposition,
|
WindowOpenDisposition disposition,
|
||||||
const blink::mojom::WindowFeatures& features,
|
const blink::mojom::WindowFeatures& features,
|
||||||
const std::vector<std::string>& additional_features,
|
const std::vector<std::string>& additional_features,
|
||||||
const scoped_refptr<content::ResourceRequestBody>& body,
|
const scoped_refptr<network::ResourceRequestBody>& body,
|
||||||
bool user_gesture,
|
bool user_gesture,
|
||||||
bool opener_suppressed,
|
bool opener_suppressed,
|
||||||
bool* no_javascript_access) {
|
bool* no_javascript_access) {
|
||||||
@@ -689,8 +707,8 @@ bool App::CanCreateWindow(
|
|||||||
content::WebContents::FromRenderFrameHost(opener);
|
content::WebContents::FromRenderFrameHost(opener);
|
||||||
if (web_contents) {
|
if (web_contents) {
|
||||||
auto api_web_contents = WebContents::CreateFrom(isolate(), web_contents);
|
auto api_web_contents = WebContents::CreateFrom(isolate(), web_contents);
|
||||||
api_web_contents->OnCreateWindow(target_url, frame_name, disposition,
|
api_web_contents->OnCreateWindow(target_url, referrer, frame_name,
|
||||||
additional_features, body);
|
disposition, additional_features, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -702,19 +720,15 @@ void App::AllowCertificateError(
|
|||||||
const net::SSLInfo& ssl_info,
|
const net::SSLInfo& ssl_info,
|
||||||
const GURL& request_url,
|
const GURL& request_url,
|
||||||
content::ResourceType resource_type,
|
content::ResourceType resource_type,
|
||||||
bool overridable,
|
|
||||||
bool strict_enforcement,
|
bool strict_enforcement,
|
||||||
bool expired_previous_decision,
|
bool expired_previous_decision,
|
||||||
const base::Callback<void(content::CertificateRequestResultType)>&
|
const base::Callback<void(content::CertificateRequestResultType)>&
|
||||||
callback) {
|
callback) {
|
||||||
v8::Locker locker(isolate());
|
v8::Locker locker(isolate());
|
||||||
v8::HandleScope handle_scope(isolate());
|
v8::HandleScope handle_scope(isolate());
|
||||||
bool prevent_default = Emit("certificate-error",
|
bool prevent_default = Emit(
|
||||||
WebContents::CreateFrom(isolate(), web_contents),
|
"certificate-error", WebContents::CreateFrom(isolate(), web_contents),
|
||||||
request_url,
|
request_url, net::ErrorToString(cert_error), ssl_info.cert, callback);
|
||||||
net::ErrorToString(cert_error),
|
|
||||||
ssl_info.cert,
|
|
||||||
callback);
|
|
||||||
|
|
||||||
// Deny the certificate by default.
|
// Deny the certificate by default.
|
||||||
if (!prevent_default)
|
if (!prevent_default)
|
||||||
@@ -726,8 +740,8 @@ void App::SelectClientCertificate(
|
|||||||
net::SSLCertRequestInfo* cert_request_info,
|
net::SSLCertRequestInfo* cert_request_info,
|
||||||
net::ClientCertIdentityList identities,
|
net::ClientCertIdentityList identities,
|
||||||
std::unique_ptr<content::ClientCertificateDelegate> delegate) {
|
std::unique_ptr<content::ClientCertificateDelegate> delegate) {
|
||||||
std::shared_ptr<content::ClientCertificateDelegate>
|
std::shared_ptr<content::ClientCertificateDelegate> shared_delegate(
|
||||||
shared_delegate(delegate.release());
|
delegate.release());
|
||||||
|
|
||||||
// Convert the ClientCertIdentityList to a CertificateList
|
// Convert the ClientCertIdentityList to a CertificateList
|
||||||
// to avoid changes in the API.
|
// to avoid changes in the API.
|
||||||
@@ -757,7 +771,7 @@ void App::SelectClientCertificate(
|
|||||||
|
|
||||||
void App::OnGpuProcessCrashed(base::TerminationStatus status) {
|
void App::OnGpuProcessCrashed(base::TerminationStatus status) {
|
||||||
Emit("gpu-process-crashed",
|
Emit("gpu-process-crashed",
|
||||||
status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);
|
status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::BrowserChildProcessLaunchedAndConnected(
|
void App::BrowserChildProcessLaunchedAndConnected(
|
||||||
@@ -799,9 +813,8 @@ void App::ChildProcessLaunched(int process_type, base::ProcessHandle handle) {
|
|||||||
std::unique_ptr<base::ProcessMetrics> metrics(
|
std::unique_ptr<base::ProcessMetrics> metrics(
|
||||||
base::ProcessMetrics::CreateProcessMetrics(handle));
|
base::ProcessMetrics::CreateProcessMetrics(handle));
|
||||||
#endif
|
#endif
|
||||||
std::unique_ptr<atom::ProcessMetric> process_metric(
|
app_metrics_[pid] = std::make_unique<atom::ProcessMetric>(process_type, pid,
|
||||||
new atom::ProcessMetric(process_type, pid, std::move(metrics)));
|
std::move(metrics));
|
||||||
app_metrics_[pid] = std::move(process_metric);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::ChildProcessDisconnected(base::ProcessId pid) {
|
void App::ChildProcessDisconnected(base::ProcessId pid) {
|
||||||
@@ -854,30 +867,43 @@ std::string App::GetLocale() {
|
|||||||
return g_browser_process->GetApplicationLocale();
|
return g_browser_process->GetApplicationLocale();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool App::MakeSingleInstance(
|
void App::OnSecondInstance(const base::CommandLine::StringVector& cmd,
|
||||||
const ProcessSingleton::NotificationCallback& callback) {
|
const base::FilePath& cwd) {
|
||||||
|
Emit("second-instance", cmd, cwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool App::HasSingleInstanceLock() const {
|
||||||
if (process_singleton_)
|
if (process_singleton_)
|
||||||
return false;
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool App::RequestSingleInstanceLock() {
|
||||||
|
if (HasSingleInstanceLock())
|
||||||
|
return true;
|
||||||
|
|
||||||
base::FilePath user_dir;
|
base::FilePath user_dir;
|
||||||
PathService::Get(brightray::DIR_USER_DATA, &user_dir);
|
PathService::Get(brightray::DIR_USER_DATA, &user_dir);
|
||||||
|
|
||||||
|
auto cb = base::Bind(&App::OnSecondInstance, base::Unretained(this));
|
||||||
|
|
||||||
process_singleton_.reset(new ProcessSingleton(
|
process_singleton_.reset(new ProcessSingleton(
|
||||||
user_dir, base::Bind(NotificationCallbackWrapper, callback)));
|
user_dir, base::Bind(NotificationCallbackWrapper, cb)));
|
||||||
|
|
||||||
switch (process_singleton_->NotifyOtherProcessOrCreate()) {
|
switch (process_singleton_->NotifyOtherProcessOrCreate()) {
|
||||||
case ProcessSingleton::NotifyResult::LOCK_ERROR:
|
case ProcessSingleton::NotifyResult::LOCK_ERROR:
|
||||||
case ProcessSingleton::NotifyResult::PROFILE_IN_USE:
|
case ProcessSingleton::NotifyResult::PROFILE_IN_USE:
|
||||||
case ProcessSingleton::NotifyResult::PROCESS_NOTIFIED: {
|
case ProcessSingleton::NotifyResult::PROCESS_NOTIFIED: {
|
||||||
process_singleton_.reset();
|
process_singleton_.reset();
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
case ProcessSingleton::NotifyResult::PROCESS_NONE:
|
case ProcessSingleton::NotifyResult::PROCESS_NONE:
|
||||||
default: // Shouldn't be needed, but VS warns if it is not there.
|
default: // Shouldn't be needed, but VS warns if it is not there.
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::ReleaseSingleInstance() {
|
void App::ReleaseSingleInstanceLock() {
|
||||||
if (process_singleton_) {
|
if (process_singleton_) {
|
||||||
process_singleton_->Cleanup();
|
process_singleton_->Cleanup();
|
||||||
process_singleton_.reset();
|
process_singleton_.reset();
|
||||||
@@ -919,8 +945,9 @@ bool App::Relaunch(mate::Arguments* js_args) {
|
|||||||
|
|
||||||
void App::DisableHardwareAcceleration(mate::Arguments* args) {
|
void App::DisableHardwareAcceleration(mate::Arguments* args) {
|
||||||
if (Browser::Get()->is_ready()) {
|
if (Browser::Get()->is_ready()) {
|
||||||
args->ThrowError("app.disableHardwareAcceleration() can only be called "
|
args->ThrowError(
|
||||||
"before app is ready");
|
"app.disableHardwareAcceleration() can only be called "
|
||||||
|
"before app is ready");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
content::GpuDataManager::GetInstance()->DisableHardwareAcceleration();
|
content::GpuDataManager::GetInstance()->DisableHardwareAcceleration();
|
||||||
@@ -938,12 +965,12 @@ void App::DisableDomainBlockingFor3DAPIs(mate::Arguments* args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool App::IsAccessibilitySupportEnabled() {
|
bool App::IsAccessibilitySupportEnabled() {
|
||||||
auto ax_state = content::BrowserAccessibilityState::GetInstance();
|
auto* ax_state = content::BrowserAccessibilityState::GetInstance();
|
||||||
return ax_state->IsAccessibleBrowser();
|
return ax_state->IsAccessibleBrowser();
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::SetAccessibilitySupportEnabled(bool enabled) {
|
void App::SetAccessibilitySupportEnabled(bool enabled) {
|
||||||
auto ax_state = content::BrowserAccessibilityState::GetInstance();
|
auto* ax_state = content::BrowserAccessibilityState::GetInstance();
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
ax_state->OnScreenReaderDetected();
|
ax_state->OnScreenReaderDetected();
|
||||||
} else {
|
} else {
|
||||||
@@ -959,18 +986,15 @@ Browser::LoginItemSettings App::GetLoginItemSettings(mate::Arguments* args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_NSS_CERTS)
|
#if defined(USE_NSS_CERTS)
|
||||||
void App::ImportCertificate(
|
void App::ImportCertificate(const base::DictionaryValue& options,
|
||||||
const base::DictionaryValue& options,
|
const net::CompletionCallback& callback) {
|
||||||
const net::CompletionCallback& callback) {
|
|
||||||
auto browser_context = AtomBrowserContext::From("", false);
|
auto browser_context = AtomBrowserContext::From("", false);
|
||||||
if (!certificate_manager_model_) {
|
if (!certificate_manager_model_) {
|
||||||
std::unique_ptr<base::DictionaryValue> copy = options.CreateDeepCopy();
|
std::unique_ptr<base::DictionaryValue> copy = options.CreateDeepCopy();
|
||||||
CertificateManagerModel::Create(
|
CertificateManagerModel::Create(
|
||||||
browser_context.get(),
|
browser_context.get(),
|
||||||
base::Bind(&App::OnCertificateManagerModelCreated,
|
base::Bind(&App::OnCertificateManagerModelCreated,
|
||||||
base::Unretained(this),
|
base::Unretained(this), base::Passed(©), callback));
|
||||||
base::Passed(©),
|
|
||||||
callback));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -983,8 +1007,8 @@ void App::OnCertificateManagerModelCreated(
|
|||||||
const net::CompletionCallback& callback,
|
const net::CompletionCallback& callback,
|
||||||
std::unique_ptr<CertificateManagerModel> model) {
|
std::unique_ptr<CertificateManagerModel> model) {
|
||||||
certificate_manager_model_ = std::move(model);
|
certificate_manager_model_ = std::move(model);
|
||||||
int rv = ImportIntoCertStore(certificate_manager_model_.get(),
|
int rv =
|
||||||
*(options.get()));
|
ImportIntoCertStore(certificate_manager_model_.get(), *(options.get()));
|
||||||
callback.Run(rv);
|
callback.Run(rv);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1013,7 +1037,7 @@ JumpListResult App::SetJumpList(v8::Local<v8::Value> val,
|
|||||||
std::vector<JumpListCategory> categories;
|
std::vector<JumpListCategory> categories;
|
||||||
bool delete_jump_list = val->IsNull();
|
bool delete_jump_list = val->IsNull();
|
||||||
if (!delete_jump_list &&
|
if (!delete_jump_list &&
|
||||||
!mate::ConvertFromV8(args->isolate(), val, &categories)) {
|
!mate::ConvertFromV8(args->isolate(), val, &categories)) {
|
||||||
args->ThrowError("Argument must be null or an array of categories");
|
args->ThrowError("Argument must be null or an array of categories");
|
||||||
return JumpListResult::ARGUMENT_ERROR;
|
return JumpListResult::ARGUMENT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -1021,9 +1045,8 @@ JumpListResult App::SetJumpList(v8::Local<v8::Value> val,
|
|||||||
JumpList jump_list(Browser::Get()->GetAppUserModelID());
|
JumpList jump_list(Browser::Get()->GetAppUserModelID());
|
||||||
|
|
||||||
if (delete_jump_list) {
|
if (delete_jump_list) {
|
||||||
return jump_list.Delete()
|
return jump_list.Delete() ? JumpListResult::SUCCESS
|
||||||
? JumpListResult::SUCCESS
|
: JumpListResult::GENERIC_ERROR;
|
||||||
: JumpListResult::GENERIC_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start a transaction that updates the JumpList of this application.
|
// Start a transaction that updates the JumpList of this application.
|
||||||
@@ -1046,8 +1069,7 @@ JumpListResult App::SetJumpList(v8::Local<v8::Value> val,
|
|||||||
}
|
}
|
||||||
#endif // defined(OS_WIN)
|
#endif // defined(OS_WIN)
|
||||||
|
|
||||||
void App::GetFileIcon(const base::FilePath& path,
|
void App::GetFileIcon(const base::FilePath& path, mate::Arguments* args) {
|
||||||
mate::Arguments* args) {
|
|
||||||
mate::Dictionary options;
|
mate::Dictionary options;
|
||||||
IconLoader::IconSize icon_size;
|
IconLoader::IconSize icon_size;
|
||||||
FileIconCallback callback;
|
FileIconCallback callback;
|
||||||
@@ -1070,7 +1092,7 @@ void App::GetFileIcon(const base::FilePath& path,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto icon_manager = g_browser_process->GetIconManager();
|
auto* icon_manager = g_browser_process->GetIconManager();
|
||||||
gfx::Image* icon =
|
gfx::Image* icon =
|
||||||
icon_manager->LookupIconFromFilepath(normalized_path, icon_size);
|
icon_manager->LookupIconFromFilepath(normalized_path, icon_size);
|
||||||
if (icon) {
|
if (icon) {
|
||||||
@@ -1092,10 +1114,12 @@ std::vector<mate::Dictionary> App::GetAppMetrics(v8::Isolate* isolate) {
|
|||||||
mate::Dictionary memory_dict = mate::Dictionary::CreateEmpty(isolate);
|
mate::Dictionary memory_dict = mate::Dictionary::CreateEmpty(isolate);
|
||||||
mate::Dictionary cpu_dict = mate::Dictionary::CreateEmpty(isolate);
|
mate::Dictionary cpu_dict = mate::Dictionary::CreateEmpty(isolate);
|
||||||
|
|
||||||
memory_dict.Set("workingSetSize",
|
memory_dict.Set(
|
||||||
|
"workingSetSize",
|
||||||
static_cast<double>(
|
static_cast<double>(
|
||||||
process_metric.second->metrics->GetWorkingSetSize() >> 10));
|
process_metric.second->metrics->GetWorkingSetSize() >> 10));
|
||||||
memory_dict.Set("peakWorkingSetSize",
|
memory_dict.Set(
|
||||||
|
"peakWorkingSetSize",
|
||||||
static_cast<double>(
|
static_cast<double>(
|
||||||
process_metric.second->metrics->GetPeakWorkingSetSize() >> 10));
|
process_metric.second->metrics->GetPeakWorkingSetSize() >> 10));
|
||||||
|
|
||||||
@@ -1107,13 +1131,14 @@ std::vector<mate::Dictionary> App::GetAppMetrics(v8::Isolate* isolate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pid_dict.Set("memory", memory_dict);
|
pid_dict.Set("memory", memory_dict);
|
||||||
cpu_dict.Set("percentCPUUsage",
|
cpu_dict.Set(
|
||||||
process_metric.second->metrics->GetPlatformIndependentCPUUsage()
|
"percentCPUUsage",
|
||||||
/ processor_count);
|
process_metric.second->metrics->GetPlatformIndependentCPUUsage() /
|
||||||
|
processor_count);
|
||||||
|
|
||||||
#if !defined(OS_WIN)
|
#if !defined(OS_WIN)
|
||||||
cpu_dict.Set("idleWakeupsPerSecond",
|
cpu_dict.Set("idleWakeupsPerSecond",
|
||||||
process_metric.second->metrics->GetIdleWakeupsPerSecond());
|
process_metric.second->metrics->GetIdleWakeupsPerSecond());
|
||||||
#else
|
#else
|
||||||
// Chrome's underlying process_metrics.cc will throw a non-fatal warning
|
// Chrome's underlying process_metrics.cc will throw a non-fatal warning
|
||||||
// that this method isn't implemented on Windows, so set it to 0 instead
|
// that this method isn't implemented on Windows, so set it to 0 instead
|
||||||
@@ -1123,8 +1148,8 @@ std::vector<mate::Dictionary> App::GetAppMetrics(v8::Isolate* isolate) {
|
|||||||
|
|
||||||
pid_dict.Set("cpu", cpu_dict);
|
pid_dict.Set("cpu", cpu_dict);
|
||||||
pid_dict.Set("pid", process_metric.second->pid);
|
pid_dict.Set("pid", process_metric.second->pid);
|
||||||
pid_dict.Set("type",
|
pid_dict.Set("type", content::GetProcessTypeNameInEnglish(
|
||||||
content::GetProcessTypeNameInEnglish(process_metric.second->type));
|
process_metric.second->type));
|
||||||
result.push_back(pid_dict);
|
result.push_back(pid_dict);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1133,18 +1158,19 @@ std::vector<mate::Dictionary> App::GetAppMetrics(v8::Isolate* isolate) {
|
|||||||
|
|
||||||
v8::Local<v8::Value> App::GetGPUFeatureStatus(v8::Isolate* isolate) {
|
v8::Local<v8::Value> App::GetGPUFeatureStatus(v8::Isolate* isolate) {
|
||||||
auto status = content::GetFeatureStatus();
|
auto status = content::GetFeatureStatus();
|
||||||
return mate::ConvertToV8(isolate,
|
base::DictionaryValue temp;
|
||||||
status ? *status : base::DictionaryValue());
|
return mate::ConvertToV8(isolate, status ? *status : temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::EnableMixedSandbox(mate::Arguments* args) {
|
void App::EnableMixedSandbox(mate::Arguments* args) {
|
||||||
if (Browser::Get()->is_ready()) {
|
if (Browser::Get()->is_ready()) {
|
||||||
args->ThrowError("app.enableMixedSandbox() can only be called "
|
args->ThrowError(
|
||||||
"before app is ready");
|
"app.enableMixedSandbox() can only be called "
|
||||||
|
"before app is ready");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||||
if (command_line->HasSwitch(::switches::kNoSandbox)) {
|
if (command_line->HasSwitch(::switches::kNoSandbox)) {
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
const base::CommandLine::CharType* noSandboxArg = L"--no-sandbox";
|
const base::CommandLine::CharType* noSandboxArg = L"--no-sandbox";
|
||||||
@@ -1180,8 +1206,8 @@ mate::Handle<App> App::Create(v8::Isolate* isolate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void App::BuildPrototype(
|
void App::BuildPrototype(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
prototype->SetClassName(mate::StringToV8(isolate, "App"));
|
prototype->SetClassName(mate::StringToV8(isolate, "App"));
|
||||||
auto browser = base::Unretained(Browser::Get());
|
auto browser = base::Unretained(Browser::Get());
|
||||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
@@ -1242,8 +1268,9 @@ void App::BuildPrototype(
|
|||||||
#if defined(USE_NSS_CERTS)
|
#if defined(USE_NSS_CERTS)
|
||||||
.SetMethod("importCertificate", &App::ImportCertificate)
|
.SetMethod("importCertificate", &App::ImportCertificate)
|
||||||
#endif
|
#endif
|
||||||
.SetMethod("makeSingleInstance", &App::MakeSingleInstance)
|
.SetMethod("hasSingleInstanceLock", &App::HasSingleInstanceLock)
|
||||||
.SetMethod("releaseSingleInstance", &App::ReleaseSingleInstance)
|
.SetMethod("requestSingleInstanceLock", &App::RequestSingleInstanceLock)
|
||||||
|
.SetMethod("releaseSingleInstanceLock", &App::ReleaseSingleInstanceLock)
|
||||||
.SetMethod("relaunch", &App::Relaunch)
|
.SetMethod("relaunch", &App::Relaunch)
|
||||||
.SetMethod("isAccessibilitySupportEnabled",
|
.SetMethod("isAccessibilitySupportEnabled",
|
||||||
&App::IsAccessibilitySupportEnabled)
|
&App::IsAccessibilitySupportEnabled)
|
||||||
@@ -1256,15 +1283,15 @@ void App::BuildPrototype(
|
|||||||
.SetMethod("getFileIcon", &App::GetFileIcon)
|
.SetMethod("getFileIcon", &App::GetFileIcon)
|
||||||
.SetMethod("getAppMetrics", &App::GetAppMetrics)
|
.SetMethod("getAppMetrics", &App::GetAppMetrics)
|
||||||
.SetMethod("getGPUFeatureStatus", &App::GetGPUFeatureStatus)
|
.SetMethod("getGPUFeatureStatus", &App::GetGPUFeatureStatus)
|
||||||
// TODO(juturu): Remove in 2.0, deprecate before then with warnings
|
// TODO(juturu): Remove in 2.0, deprecate before then with warnings
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
.SetMethod("moveToApplicationsFolder", &App::MoveToApplicationsFolder)
|
.SetMethod("moveToApplicationsFolder", &App::MoveToApplicationsFolder)
|
||||||
.SetMethod("isInApplicationsFolder", &App::IsInApplicationsFolder)
|
.SetMethod("isInApplicationsFolder", &App::IsInApplicationsFolder)
|
||||||
#endif
|
#endif
|
||||||
#if defined(MAS_BUILD)
|
#if defined(MAS_BUILD)
|
||||||
.SetMethod("startAccessingSecurityScopedResource",
|
.SetMethod("startAccessingSecurityScopedResource",
|
||||||
&App::StartAccessingSecurityScopedResource)
|
&App::StartAccessingSecurityScopedResource)
|
||||||
#endif
|
#endif
|
||||||
.SetMethod("enableMixedSandbox", &App::EnableMixedSandbox);
|
.SetMethod("enableMixedSandbox", &App::EnableMixedSandbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1272,15 +1299,14 @@ void App::BuildPrototype(
|
|||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void AppendSwitch(const std::string& switch_string, mate::Arguments* args) {
|
void AppendSwitch(const std::string& switch_string, mate::Arguments* args) {
|
||||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||||
|
|
||||||
if (base::EndsWith(switch_string, "-path",
|
if (base::EndsWith(switch_string, "-path",
|
||||||
base::CompareCase::INSENSITIVE_ASCII) ||
|
base::CompareCase::INSENSITIVE_ASCII) ||
|
||||||
switch_string == switches::kLogNetLog) {
|
switch_string == network::switches::kLogNetLog) {
|
||||||
base::FilePath path;
|
base::FilePath path;
|
||||||
args->GetNext(&path);
|
args->GetNext(&path);
|
||||||
command_line->AppendSwitchPath(switch_string, path);
|
command_line->AppendSwitchPath(switch_string, path);
|
||||||
@@ -1309,18 +1335,19 @@ void DockSetMenu(atom::api::Menu* menu) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||||
|
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.Set("App", atom::api::App::GetConstructor(isolate)->GetFunction());
|
dict.Set("App", atom::api::App::GetConstructor(isolate)->GetFunction());
|
||||||
dict.Set("app", atom::api::App::Create(isolate));
|
dict.Set("app", atom::api::App::Create(isolate));
|
||||||
dict.SetMethod("appendSwitch", &AppendSwitch);
|
dict.SetMethod("appendSwitch", &AppendSwitch);
|
||||||
dict.SetMethod("appendArgument",
|
dict.SetMethod("appendArgument", base::Bind(&base::CommandLine::AppendArg,
|
||||||
base::Bind(&base::CommandLine::AppendArg,
|
base::Unretained(command_line)));
|
||||||
base::Unretained(command_line)));
|
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
auto browser = base::Unretained(Browser::Get());
|
auto browser = base::Unretained(Browser::Get());
|
||||||
dict.SetMethod("dockBounce", &DockBounce);
|
dict.SetMethod("dockBounce", &DockBounce);
|
||||||
@@ -1342,4 +1369,4 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_app, Initialize)
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_app, Initialize)
|
||||||
|
|||||||
@@ -52,11 +52,8 @@ struct ProcessMetric {
|
|||||||
|
|
||||||
ProcessMetric(int type,
|
ProcessMetric(int type,
|
||||||
base::ProcessId pid,
|
base::ProcessId pid,
|
||||||
std::unique_ptr<base::ProcessMetrics> metrics) {
|
std::unique_ptr<base::ProcessMetrics> metrics);
|
||||||
this->type = type;
|
~ProcessMetric();
|
||||||
this->pid = pid;
|
|
||||||
this->metrics = std::move(metrics);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
@@ -67,8 +64,8 @@ class App : public AtomBrowserClient::Delegate,
|
|||||||
public content::GpuDataManagerObserver,
|
public content::GpuDataManagerObserver,
|
||||||
public content::BrowserChildProcessObserver {
|
public content::BrowserChildProcessObserver {
|
||||||
public:
|
public:
|
||||||
using FileIconCallback = base::Callback<void(v8::Local<v8::Value>,
|
using FileIconCallback =
|
||||||
const gfx::Image&)>;
|
base::Callback<void(v8::Local<v8::Value>, const gfx::Image&)>;
|
||||||
|
|
||||||
static mate::Handle<App> Create(v8::Isolate* isolate);
|
static mate::Handle<App> Create(v8::Isolate* isolate);
|
||||||
|
|
||||||
@@ -101,21 +98,18 @@ class App : public AtomBrowserClient::Delegate,
|
|||||||
void OnActivate(bool has_visible_windows) override;
|
void OnActivate(bool has_visible_windows) override;
|
||||||
void OnWillFinishLaunching() override;
|
void OnWillFinishLaunching() override;
|
||||||
void OnFinishLaunching(const base::DictionaryValue& launch_info) override;
|
void OnFinishLaunching(const base::DictionaryValue& launch_info) override;
|
||||||
void OnLogin(LoginHandler* login_handler,
|
void OnLogin(scoped_refptr<LoginHandler> login_handler,
|
||||||
const base::DictionaryValue& request_details) override;
|
const base::DictionaryValue& request_details) override;
|
||||||
void OnAccessibilitySupportChanged() override;
|
void OnAccessibilitySupportChanged() override;
|
||||||
void OnPreMainMessageLoopRun() override;
|
void OnPreMainMessageLoopRun() override;
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
void OnWillContinueUserActivity(
|
void OnWillContinueUserActivity(bool* prevent_default,
|
||||||
bool* prevent_default,
|
const std::string& type) override;
|
||||||
const std::string& type) override;
|
void OnDidFailToContinueUserActivity(const std::string& type,
|
||||||
void OnDidFailToContinueUserActivity(
|
const std::string& error) override;
|
||||||
const std::string& type,
|
void OnContinueUserActivity(bool* prevent_default,
|
||||||
const std::string& error) override;
|
const std::string& type,
|
||||||
void OnContinueUserActivity(
|
const base::DictionaryValue& user_info) override;
|
||||||
bool* prevent_default,
|
|
||||||
const std::string& type,
|
|
||||||
const base::DictionaryValue& user_info) override;
|
|
||||||
void OnUserActivityWasContinued(
|
void OnUserActivityWasContinued(
|
||||||
const std::string& type,
|
const std::string& type,
|
||||||
const base::DictionaryValue& user_info) override;
|
const base::DictionaryValue& user_info) override;
|
||||||
@@ -133,7 +127,6 @@ class App : public AtomBrowserClient::Delegate,
|
|||||||
const net::SSLInfo& ssl_info,
|
const net::SSLInfo& ssl_info,
|
||||||
const GURL& request_url,
|
const GURL& request_url,
|
||||||
content::ResourceType resource_type,
|
content::ResourceType resource_type,
|
||||||
bool overridable,
|
|
||||||
bool strict_enforcement,
|
bool strict_enforcement,
|
||||||
bool expired_previous_decision,
|
bool expired_previous_decision,
|
||||||
const base::Callback<void(content::CertificateRequestResultType)>&
|
const base::Callback<void(content::CertificateRequestResultType)>&
|
||||||
@@ -154,7 +147,7 @@ class App : public AtomBrowserClient::Delegate,
|
|||||||
WindowOpenDisposition disposition,
|
WindowOpenDisposition disposition,
|
||||||
const blink::mojom::WindowFeatures& features,
|
const blink::mojom::WindowFeatures& features,
|
||||||
const std::vector<std::string>& additional_features,
|
const std::vector<std::string>& additional_features,
|
||||||
const scoped_refptr<content::ResourceRequestBody>& body,
|
const scoped_refptr<network::ResourceRequestBody>& body,
|
||||||
bool user_gesture,
|
bool user_gesture,
|
||||||
bool opener_suppressed,
|
bool opener_suppressed,
|
||||||
bool* no_javascript_access) override;
|
bool* no_javascript_access) override;
|
||||||
@@ -167,10 +160,10 @@ class App : public AtomBrowserClient::Delegate,
|
|||||||
const content::ChildProcessData& data) override;
|
const content::ChildProcessData& data) override;
|
||||||
void BrowserChildProcessHostDisconnected(
|
void BrowserChildProcessHostDisconnected(
|
||||||
const content::ChildProcessData& data) override;
|
const content::ChildProcessData& data) override;
|
||||||
void BrowserChildProcessCrashed(
|
void BrowserChildProcessCrashed(const content::ChildProcessData& data,
|
||||||
const content::ChildProcessData& data, int exit_code) override;
|
int exit_code) override;
|
||||||
void BrowserChildProcessKilled(
|
void BrowserChildProcessKilled(const content::ChildProcessData& data,
|
||||||
const content::ChildProcessData& data, int exit_code) override;
|
int exit_code) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetAppPath(const base::FilePath& app_path);
|
void SetAppPath(const base::FilePath& app_path);
|
||||||
@@ -185,9 +178,11 @@ class App : public AtomBrowserClient::Delegate,
|
|||||||
|
|
||||||
void SetDesktopName(const std::string& desktop_name);
|
void SetDesktopName(const std::string& desktop_name);
|
||||||
std::string GetLocale();
|
std::string GetLocale();
|
||||||
bool MakeSingleInstance(
|
void OnSecondInstance(const base::CommandLine::StringVector& cmd,
|
||||||
const ProcessSingleton::NotificationCallback& callback);
|
const base::FilePath& cwd);
|
||||||
void ReleaseSingleInstance();
|
bool HasSingleInstanceLock() const;
|
||||||
|
bool RequestSingleInstanceLock();
|
||||||
|
void ReleaseSingleInstanceLock();
|
||||||
bool Relaunch(mate::Arguments* args);
|
bool Relaunch(mate::Arguments* args);
|
||||||
void DisableHardwareAcceleration(mate::Arguments* args);
|
void DisableHardwareAcceleration(mate::Arguments* args);
|
||||||
void DisableDomainBlockingFor3DAPIs(mate::Arguments* args);
|
void DisableDomainBlockingFor3DAPIs(mate::Arguments* args);
|
||||||
@@ -198,8 +193,7 @@ class App : public AtomBrowserClient::Delegate,
|
|||||||
void ImportCertificate(const base::DictionaryValue& options,
|
void ImportCertificate(const base::DictionaryValue& options,
|
||||||
const net::CompletionCallback& callback);
|
const net::CompletionCallback& callback);
|
||||||
#endif
|
#endif
|
||||||
void GetFileIcon(const base::FilePath& path,
|
void GetFileIcon(const base::FilePath& path, mate::Arguments* args);
|
||||||
mate::Arguments* args);
|
|
||||||
|
|
||||||
std::vector<mate::Dictionary> GetAppMetrics(v8::Isolate* isolate);
|
std::vector<mate::Dictionary> GetAppMetrics(v8::Isolate* isolate);
|
||||||
v8::Local<v8::Value> GetGPUFeatureStatus(v8::Isolate* isolate);
|
v8::Local<v8::Value> GetGPUFeatureStatus(v8::Isolate* isolate);
|
||||||
@@ -211,7 +205,7 @@ class App : public AtomBrowserClient::Delegate,
|
|||||||
#endif
|
#endif
|
||||||
#if defined(MAS_BUILD)
|
#if defined(MAS_BUILD)
|
||||||
base::Callback<void()> StartAccessingSecurityScopedResource(
|
base::Callback<void()> StartAccessingSecurityScopedResource(
|
||||||
mate::Arguments* args);
|
mate::Arguments* args);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
@@ -234,8 +228,7 @@ class App : public AtomBrowserClient::Delegate,
|
|||||||
base::FilePath app_path_;
|
base::FilePath app_path_;
|
||||||
|
|
||||||
using ProcessMetricMap =
|
using ProcessMetricMap =
|
||||||
std::unordered_map<base::ProcessId,
|
std::unordered_map<base::ProcessId, std::unique_ptr<atom::ProcessMetric>>;
|
||||||
std::unique_ptr<atom::ProcessMetric>>;
|
|
||||||
ProcessMetricMap app_metrics_;
|
ProcessMetricMap app_metrics_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(App);
|
DISALLOW_COPY_AND_ASSIGN(App);
|
||||||
|
|||||||
@@ -19,23 +19,27 @@ void OnStopAccessingSecurityScopedResource(NSURL* bookmarkUrl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get base64 encoded NSData, create a bookmark for it and start accessing it.
|
// Get base64 encoded NSData, create a bookmark for it and start accessing it.
|
||||||
base::Callback<void ()> App::StartAccessingSecurityScopedResource(mate::Arguments* args) {
|
base::Callback<void()> App::StartAccessingSecurityScopedResource(
|
||||||
|
mate::Arguments* args) {
|
||||||
std::string data;
|
std::string data;
|
||||||
args->GetNext(&data);
|
args->GetNext(&data);
|
||||||
NSString *base64str = base::SysUTF8ToNSString(data);
|
NSString* base64str = base::SysUTF8ToNSString(data);
|
||||||
NSData *bookmarkData = [[NSData alloc] initWithBase64EncodedString: base64str options: 0];
|
NSData* bookmarkData =
|
||||||
|
[[NSData alloc] initWithBase64EncodedString:base64str options:0];
|
||||||
|
|
||||||
// Create bookmarkUrl from NSData.
|
// Create bookmarkUrl from NSData.
|
||||||
BOOL isStale = false;
|
BOOL isStale = false;
|
||||||
NSError *error = nil;
|
NSError* error = nil;
|
||||||
NSURL *bookmarkUrl = [NSURL URLByResolvingBookmarkData: bookmarkData
|
NSURL* bookmarkUrl =
|
||||||
options: NSURLBookmarkResolutionWithSecurityScope
|
[NSURL URLByResolvingBookmarkData:bookmarkData
|
||||||
relativeToURL: nil
|
options:NSURLBookmarkResolutionWithSecurityScope
|
||||||
bookmarkDataIsStale: &isStale
|
relativeToURL:nil
|
||||||
error: &error];
|
bookmarkDataIsStale:&isStale
|
||||||
|
error:&error];
|
||||||
|
|
||||||
if (error != nil) {
|
if (error != nil) {
|
||||||
NSString *err = [NSString stringWithFormat: @"NSError: %@ %@", error, [error userInfo]];
|
NSString* err =
|
||||||
|
[NSString stringWithFormat:@"NSError: %@ %@", error, [error userInfo]];
|
||||||
args->ThrowError(base::SysNSStringToUTF8(err));
|
args->ThrowError(base::SysNSStringToUTF8(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +58,6 @@ base::Callback<void ()> App::StartAccessingSecurityScopedResource(mate::Argument
|
|||||||
return base::Bind(&OnStopAccessingSecurityScopedResource, bookmarkUrl);
|
return base::Bind(&OnStopAccessingSecurityScopedResource, bookmarkUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
|
|||||||
@@ -16,12 +16,12 @@
|
|||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<base::Time> {
|
struct Converter<base::Time> {
|
||||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
const base::Time& val) {
|
const base::Time& val) {
|
||||||
v8::MaybeLocal<v8::Value> date = v8::Date::New(
|
v8::MaybeLocal<v8::Value> date =
|
||||||
isolate->GetCurrentContext(), val.ToJsTime());
|
v8::Date::New(isolate->GetCurrentContext(), val.ToJsTime());
|
||||||
if (date.IsEmpty())
|
if (date.IsEmpty())
|
||||||
return v8::Null(isolate);
|
return v8::Null(isolate);
|
||||||
else
|
else
|
||||||
@@ -49,21 +49,20 @@ void AutoUpdater::OnError(const std::string& message) {
|
|||||||
v8::HandleScope handle_scope(isolate());
|
v8::HandleScope handle_scope(isolate());
|
||||||
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
|
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
|
||||||
mate::EmitEvent(
|
mate::EmitEvent(
|
||||||
isolate(),
|
isolate(), GetWrapper(), "error",
|
||||||
GetWrapper(),
|
|
||||||
"error",
|
|
||||||
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked(),
|
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked(),
|
||||||
// Message is also emitted to keep compatibility with old code.
|
// Message is also emitted to keep compatibility with old code.
|
||||||
message);
|
message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoUpdater::OnError(const std::string& message,
|
void AutoUpdater::OnError(const std::string& message,
|
||||||
const int code, const std::string& domain) {
|
const int code,
|
||||||
|
const std::string& domain) {
|
||||||
v8::Locker locker(isolate());
|
v8::Locker locker(isolate());
|
||||||
v8::HandleScope handle_scope(isolate());
|
v8::HandleScope handle_scope(isolate());
|
||||||
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
|
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
|
||||||
auto errorObject = error->ToObject(
|
auto errorObject =
|
||||||
isolate()->GetCurrentContext()).ToLocalChecked();
|
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked();
|
||||||
|
|
||||||
// add two new params for better error handling
|
// add two new params for better error handling
|
||||||
errorObject->Set(mate::StringToV8(isolate(), "code"),
|
errorObject->Set(mate::StringToV8(isolate(), "code"),
|
||||||
@@ -104,6 +103,8 @@ void AutoUpdater::SetFeedURL(mate::Arguments* args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AutoUpdater::QuitAndInstall() {
|
void AutoUpdater::QuitAndInstall() {
|
||||||
|
Emit("before-quit-for-update");
|
||||||
|
|
||||||
// If we don't have any window then quitAndInstall immediately.
|
// If we don't have any window then quitAndInstall immediately.
|
||||||
if (WindowList::IsEmpty()) {
|
if (WindowList::IsEmpty()) {
|
||||||
auto_updater::AutoUpdater::QuitAndInstall();
|
auto_updater::AutoUpdater::QuitAndInstall();
|
||||||
@@ -121,8 +122,8 @@ mate::Handle<AutoUpdater> AutoUpdater::Create(v8::Isolate* isolate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void AutoUpdater::BuildPrototype(
|
void AutoUpdater::BuildPrototype(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
prototype->SetClassName(mate::StringToV8(isolate, "AutoUpdater"));
|
prototype->SetClassName(mate::StringToV8(isolate, "AutoUpdater"));
|
||||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
|
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
|
||||||
@@ -135,13 +136,14 @@ void AutoUpdater::BuildPrototype(
|
|||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using atom::api::AutoUpdater;
|
using atom::api::AutoUpdater;
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.Set("autoUpdater", AutoUpdater::Create(isolate));
|
dict.Set("autoUpdater", AutoUpdater::Create(isolate));
|
||||||
@@ -150,4 +152,4 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_auto_updater, Initialize)
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_auto_updater, Initialize)
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
|
|||||||
|
|
||||||
// Delegate implementations.
|
// Delegate implementations.
|
||||||
void OnError(const std::string& error) override;
|
void OnError(const std::string& error) override;
|
||||||
void OnError(const std::string& message, const int code,
|
void OnError(const std::string& message,
|
||||||
const std::string& domain);
|
const int code,
|
||||||
|
const std::string& domain) override;
|
||||||
void OnCheckingForUpdate() override;
|
void OnCheckingForUpdate() override;
|
||||||
void OnUpdateAvailable() override;
|
void OnUpdateAvailable() override;
|
||||||
void OnUpdateNotAvailable() override;
|
void OnUpdateNotAvailable() override;
|
||||||
|
|||||||
87
atom/browser/api/atom_api_box_layout.cc
Normal file
87
atom/browser/api/atom_api_box_layout.cc
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
// 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_box_layout.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "atom/browser/api/atom_api_view.h"
|
||||||
|
#include "atom/common/api/constructor.h"
|
||||||
|
#include "native_mate/dictionary.h"
|
||||||
|
|
||||||
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<views::BoxLayout::Orientation> {
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Handle<v8::Value> val,
|
||||||
|
views::BoxLayout::Orientation* out) {
|
||||||
|
std::string orientation;
|
||||||
|
if (!ConvertFromV8(isolate, val, &orientation))
|
||||||
|
return false;
|
||||||
|
if (orientation == "horizontal")
|
||||||
|
*out = views::BoxLayout::kHorizontal;
|
||||||
|
else if (orientation == "vertical")
|
||||||
|
*out = views::BoxLayout::kVertical;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mate
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
BoxLayout::BoxLayout(views::BoxLayout::Orientation orientation)
|
||||||
|
: LayoutManager(new views::BoxLayout(orientation)) {}
|
||||||
|
|
||||||
|
BoxLayout::~BoxLayout() {}
|
||||||
|
|
||||||
|
void BoxLayout::SetFlexForView(mate::Handle<View> view, int flex) {
|
||||||
|
auto* box_layout = static_cast<views::BoxLayout*>(layout_manager());
|
||||||
|
box_layout->SetFlexForView(view->view(), flex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
mate::WrappableBase* BoxLayout::New(mate::Arguments* args,
|
||||||
|
views::BoxLayout::Orientation orientation) {
|
||||||
|
auto* layout = new BoxLayout(orientation);
|
||||||
|
layout->InitWith(args->isolate(), args->GetThis());
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void BoxLayout::BuildPrototype(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
|
prototype->SetClassName(mate::StringToV8(isolate, "BoxLayout"));
|
||||||
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
|
.SetMethod("setFlexForView", &BoxLayout::SetFlexForView);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using atom::api::BoxLayout;
|
||||||
|
|
||||||
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
|
mate::Dictionary dict(isolate, exports);
|
||||||
|
dict.Set("BoxLayout", mate::CreateConstructor<BoxLayout>(
|
||||||
|
isolate, base::Bind(&BoxLayout::New)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_box_layout, Initialize)
|
||||||
40
atom/browser/api/atom_api_box_layout.h
Normal file
40
atom/browser/api/atom_api_box_layout.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// Copyright (c) 2018 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef ATOM_BROWSER_API_ATOM_API_BOX_LAYOUT_H_
|
||||||
|
#define ATOM_BROWSER_API_ATOM_API_BOX_LAYOUT_H_
|
||||||
|
|
||||||
|
#include "atom/browser/api/atom_api_layout_manager.h"
|
||||||
|
#include "native_mate/handle.h"
|
||||||
|
#include "ui/views/layout/box_layout.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
class View;
|
||||||
|
|
||||||
|
class BoxLayout : public LayoutManager {
|
||||||
|
public:
|
||||||
|
static mate::WrappableBase* New(mate::Arguments* args,
|
||||||
|
views::BoxLayout::Orientation orientation);
|
||||||
|
|
||||||
|
static void BuildPrototype(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype);
|
||||||
|
|
||||||
|
void SetFlexForView(mate::Handle<View> view, int flex);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit BoxLayout(views::BoxLayout::Orientation orientation);
|
||||||
|
~BoxLayout() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(BoxLayout);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
#endif // ATOM_BROWSER_API_ATOM_API_BOX_LAYOUT_H_
|
||||||
@@ -51,8 +51,7 @@ namespace api {
|
|||||||
|
|
||||||
BrowserView::BrowserView(v8::Isolate* isolate,
|
BrowserView::BrowserView(v8::Isolate* isolate,
|
||||||
v8::Local<v8::Object> wrapper,
|
v8::Local<v8::Object> wrapper,
|
||||||
const mate::Dictionary& options)
|
const mate::Dictionary& options) {
|
||||||
: api_web_contents_(nullptr) {
|
|
||||||
Init(isolate, wrapper, options);
|
Init(isolate, wrapper, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,8 +67,8 @@ void BrowserView::Init(v8::Isolate* isolate,
|
|||||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||||
api_web_contents_ = web_contents.get();
|
api_web_contents_ = web_contents.get();
|
||||||
|
|
||||||
view_.reset(NativeBrowserView::Create(
|
view_.reset(
|
||||||
api_web_contents_->managed_web_contents()->GetView()));
|
NativeBrowserView::Create(api_web_contents_->managed_web_contents()));
|
||||||
|
|
||||||
InitWith(isolate, wrapper);
|
InitWith(isolate, wrapper);
|
||||||
}
|
}
|
||||||
@@ -153,13 +152,13 @@ void Initialize(v8::Local<v8::Object> exports,
|
|||||||
mate::Dictionary browser_view(
|
mate::Dictionary browser_view(
|
||||||
isolate, BrowserView::GetConstructor(isolate)->GetFunction());
|
isolate, BrowserView::GetConstructor(isolate)->GetFunction());
|
||||||
browser_view.SetMethod("fromId",
|
browser_view.SetMethod("fromId",
|
||||||
&mate::TrackableObject<BrowserView>::FromWeakMapID);
|
&mate::TrackableObject<BrowserView>::FromWeakMapID);
|
||||||
browser_view.SetMethod("getAllViews",
|
browser_view.SetMethod("getAllViews",
|
||||||
&mate::TrackableObject<BrowserView>::GetAll);
|
&mate::TrackableObject<BrowserView>::GetAll);
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.Set("BrowserView", browser_view);
|
dict.Set("BrowserView", browser_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_browser_view, Initialize)
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_browser_view, Initialize)
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class BrowserView : public mate::TrackableObject<BrowserView> {
|
|||||||
v8::Local<v8::Value> GetWebContents();
|
v8::Local<v8::Value> GetWebContents();
|
||||||
|
|
||||||
v8::Global<v8::Value> web_contents_;
|
v8::Global<v8::Value> web_contents_;
|
||||||
class WebContents* api_web_contents_;
|
class WebContents* api_web_contents_ = nullptr;
|
||||||
|
|
||||||
std::unique_ptr<NativeBrowserView> view_;
|
std::unique_ptr<NativeBrowserView> view_;
|
||||||
|
|
||||||
|
|||||||
452
atom/browser/api/atom_api_browser_window.cc
Normal file
452
atom/browser/api/atom_api_browser_window.cc
Normal file
@@ -0,0 +1,452 @@
|
|||||||
|
// Copyright (c) 2013 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_browser_window.h"
|
||||||
|
|
||||||
|
#include "atom/browser/browser.h"
|
||||||
|
#include "atom/browser/unresponsive_suppressor.h"
|
||||||
|
#include "atom/browser/web_contents_preferences.h"
|
||||||
|
#include "atom/browser/window_list.h"
|
||||||
|
#include "atom/common/api/api_messages.h"
|
||||||
|
#include "atom/common/api/constructor.h"
|
||||||
|
#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/options_switches.h"
|
||||||
|
#include "base/threading/thread_task_runner_handle.h"
|
||||||
|
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||||
|
#include "content/public/browser/render_process_host.h"
|
||||||
|
#include "content/public/browser/render_view_host.h"
|
||||||
|
#include "native_mate/dictionary.h"
|
||||||
|
#include "ui/gl/gpu_switching_manager.h"
|
||||||
|
|
||||||
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
BrowserWindow::BrowserWindow(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Object> wrapper,
|
||||||
|
const mate::Dictionary& options)
|
||||||
|
: TopLevelWindow(isolate, options), weak_factory_(this) {
|
||||||
|
mate::Handle<class WebContents> web_contents;
|
||||||
|
|
||||||
|
// Use options.webPreferences in WebContents.
|
||||||
|
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
|
||||||
|
options.Get(options::kWebPreferences, &web_preferences);
|
||||||
|
|
||||||
|
// Copy the backgroundColor to webContents.
|
||||||
|
v8::Local<v8::Value> value;
|
||||||
|
if (options.Get(options::kBackgroundColor, &value))
|
||||||
|
web_preferences.Set(options::kBackgroundColor, value);
|
||||||
|
|
||||||
|
v8::Local<v8::Value> transparent;
|
||||||
|
if (options.Get("transparent", &transparent))
|
||||||
|
web_preferences.Set("transparent", transparent);
|
||||||
|
|
||||||
|
if (options.Get("webContents", &web_contents) && !web_contents.IsEmpty()) {
|
||||||
|
// Set webPreferences from options if using an existing webContents.
|
||||||
|
// These preferences will be used when the webContent launches new
|
||||||
|
// render processes.
|
||||||
|
auto* existing_preferences =
|
||||||
|
WebContentsPreferences::From(web_contents->web_contents());
|
||||||
|
base::DictionaryValue web_preferences_dict;
|
||||||
|
if (mate::ConvertFromV8(isolate, web_preferences.GetHandle(),
|
||||||
|
&web_preferences_dict)) {
|
||||||
|
existing_preferences->dict()->Clear();
|
||||||
|
existing_preferences->Merge(web_preferences_dict);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Creates the WebContents used by BrowserWindow.
|
||||||
|
web_contents = WebContents::Create(isolate, web_preferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||||
|
api_web_contents_ = web_contents.get();
|
||||||
|
api_web_contents_->AddObserver(this);
|
||||||
|
Observe(api_web_contents_->web_contents());
|
||||||
|
|
||||||
|
// Keep a copy of the options for later use.
|
||||||
|
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());
|
||||||
|
|
||||||
|
auto* host = web_contents->web_contents()->GetRenderViewHost();
|
||||||
|
if (host)
|
||||||
|
host->GetWidget()->AddInputEventObserver(this);
|
||||||
|
|
||||||
|
InitWith(isolate, wrapper);
|
||||||
|
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
if (!window()->has_frame())
|
||||||
|
OverrideNSWindowContentView(web_contents->managed_web_contents());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Init window after everything has been setup.
|
||||||
|
window()->InitFromOptions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
BrowserWindow::~BrowserWindow() {
|
||||||
|
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())
|
||||||
|
Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::OnInputEvent(const blink::WebInputEvent& event) {
|
||||||
|
switch (event.GetType()) {
|
||||||
|
case blink::WebInputEvent::kGestureScrollBegin:
|
||||||
|
case blink::WebInputEvent::kGestureScrollUpdate:
|
||||||
|
case blink::WebInputEvent::kGestureScrollEnd:
|
||||||
|
Emit("scroll-touch-edge");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::RenderViewHostChanged(content::RenderViewHost* old_host,
|
||||||
|
content::RenderViewHost* new_host) {
|
||||||
|
if (old_host)
|
||||||
|
old_host->GetWidget()->RemoveInputEventObserver(this);
|
||||||
|
if (new_host)
|
||||||
|
new_host->GetWidget()->AddInputEventObserver(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::RenderViewCreated(
|
||||||
|
content::RenderViewHost* render_view_host) {
|
||||||
|
if (!window()->transparent())
|
||||||
|
return;
|
||||||
|
|
||||||
|
content::RenderWidgetHostImpl* impl = content::RenderWidgetHostImpl::FromID(
|
||||||
|
render_view_host->GetProcess()->GetID(),
|
||||||
|
render_view_host->GetRoutingID());
|
||||||
|
if (impl)
|
||||||
|
impl->SetBackgroundOpaque(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::DidFirstVisuallyNonEmptyPaint() {
|
||||||
|
if (window()->IsVisible())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// When there is a non-empty first paint, resize the RenderWidget to force
|
||||||
|
// Chromium to draw.
|
||||||
|
auto* const view = web_contents()->GetRenderWidgetHostView();
|
||||||
|
view->Show();
|
||||||
|
view->SetSize(window()->GetContentSize());
|
||||||
|
|
||||||
|
// Emit the ReadyToShow event in next tick in case of pending drawing work.
|
||||||
|
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||||
|
FROM_HERE, base::BindOnce(
|
||||||
|
[](base::WeakPtr<BrowserWindow> self) {
|
||||||
|
if (self)
|
||||||
|
self->Emit("ready-to-show");
|
||||||
|
},
|
||||||
|
GetWeakPtr()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::BeforeUnloadDialogCancelled() {
|
||||||
|
WindowList::WindowCloseCancelled(window());
|
||||||
|
// Cancel unresponsive event when window close is cancelled.
|
||||||
|
window_unresponsive_closure_.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::OnRendererUnresponsive(content::RenderProcessHost*) {
|
||||||
|
// Schedule the unresponsive shortly later, since we may receive the
|
||||||
|
// responsive event soon. This could happen after the whole application had
|
||||||
|
// blocked for a while.
|
||||||
|
// Also notice that when closing this event would be ignored because we have
|
||||||
|
// explicitly started a close timeout counter. This is on purpose because we
|
||||||
|
// don't want the unresponsive event to be sent too early when user is closing
|
||||||
|
// the window.
|
||||||
|
ScheduleUnresponsiveEvent(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BrowserWindow::OnMessageReceived(const IPC::Message& message,
|
||||||
|
content::RenderFrameHost* rfh) {
|
||||||
|
bool handled = true;
|
||||||
|
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(BrowserWindow, message, rfh)
|
||||||
|
IPC_MESSAGE_HANDLER(AtomFrameHostMsg_UpdateDraggableRegions,
|
||||||
|
UpdateDraggableRegions)
|
||||||
|
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||||
|
IPC_END_MESSAGE_MAP()
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::OnCloseContents() {
|
||||||
|
DCHECK(web_contents());
|
||||||
|
|
||||||
|
// Close all child windows before closing current window.
|
||||||
|
v8::Locker locker(isolate());
|
||||||
|
v8::HandleScope handle_scope(isolate());
|
||||||
|
for (v8::Local<v8::Value> value : child_windows_.Values(isolate())) {
|
||||||
|
mate::Handle<BrowserWindow> child;
|
||||||
|
if (mate::ConvertFromV8(isolate(), value, &child) && !child.IsEmpty())
|
||||||
|
child->window()->CloseImmediately();
|
||||||
|
}
|
||||||
|
|
||||||
|
// When the web contents is gone, close the window immediately, but the
|
||||||
|
// memory will not be freed until you call delete.
|
||||||
|
// In this way, it would be safe to manage windows via smart pointers. If you
|
||||||
|
// want to free memory when the window is closed, you can do deleting by
|
||||||
|
// overriding the OnWindowClosed method in the observer.
|
||||||
|
window()->CloseImmediately();
|
||||||
|
|
||||||
|
// Do not sent "unresponsive" event after window is closed.
|
||||||
|
window_unresponsive_closure_.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::OnRendererResponsive() {
|
||||||
|
window_unresponsive_closure_.Cancel();
|
||||||
|
Emit("responsive");
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::RequestPreferredWidth(int* width) {
|
||||||
|
*width = web_contents()->GetPreferredSize().width();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
|
||||||
|
// When user tries to close the window by clicking the close button, we do
|
||||||
|
// not close the window immediately, instead we try to close the web page
|
||||||
|
// first, and when the web page is closed the window will also be closed.
|
||||||
|
*prevent_default = true;
|
||||||
|
|
||||||
|
// Assume the window is not responding if it doesn't cancel the close and is
|
||||||
|
// not closed in 5s, in this way we can quickly show the unresponsive
|
||||||
|
// dialog when the window is busy executing some script withouth waiting for
|
||||||
|
// the unresponsive timeout.
|
||||||
|
if (window_unresponsive_closure_.IsCancelled())
|
||||||
|
ScheduleUnresponsiveEvent(5000);
|
||||||
|
|
||||||
|
if (!web_contents())
|
||||||
|
// Already closed by renderer
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (web_contents()->NeedToFireBeforeUnload())
|
||||||
|
web_contents()->DispatchBeforeUnload();
|
||||||
|
else
|
||||||
|
web_contents()->Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::OnWindowClosed() {
|
||||||
|
Cleanup();
|
||||||
|
TopLevelWindow::OnWindowClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::OnWindowBlur() {
|
||||||
|
web_contents()->StoreFocus();
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
auto* rwhv = web_contents()->GetRenderWidgetHostView();
|
||||||
|
if (rwhv)
|
||||||
|
rwhv->SetActive(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TopLevelWindow::OnWindowBlur();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::OnWindowFocus() {
|
||||||
|
web_contents()->RestoreFocus();
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
auto* rwhv = web_contents()->GetRenderWidgetHostView();
|
||||||
|
if (rwhv)
|
||||||
|
rwhv->SetActive(true);
|
||||||
|
#else
|
||||||
|
if (!api_web_contents_->IsDevToolsOpened())
|
||||||
|
web_contents()->Focus();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TopLevelWindow::OnWindowFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::OnWindowResize() {
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
if (!draggable_regions_.empty())
|
||||||
|
UpdateDraggableRegions(nullptr, draggable_regions_);
|
||||||
|
#endif
|
||||||
|
TopLevelWindow::OnWindowResize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::OnWindowLeaveFullScreen() {
|
||||||
|
TopLevelWindow::OnWindowLeaveFullScreen();
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
if (web_contents()->IsFullscreenForCurrentTab())
|
||||||
|
web_contents()->ExitFullscreen(true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::Focus() {
|
||||||
|
if (api_web_contents_->IsOffScreen())
|
||||||
|
FocusOnWebView();
|
||||||
|
else
|
||||||
|
TopLevelWindow::Focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::Blur() {
|
||||||
|
if (api_web_contents_->IsOffScreen())
|
||||||
|
BlurWebView();
|
||||||
|
else
|
||||||
|
TopLevelWindow::Blur();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
|
||||||
|
TopLevelWindow::SetBackgroundColor(color_name);
|
||||||
|
auto* view = web_contents()->GetRenderWidgetHostView();
|
||||||
|
if (view)
|
||||||
|
view->SetBackgroundColor(ParseHexColor(color_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::SetBrowserView(v8::Local<v8::Value> value) {
|
||||||
|
TopLevelWindow::SetBrowserView(value);
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
UpdateDraggableRegions(nullptr, draggable_regions_);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::SetVibrancy(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Value> value) {
|
||||||
|
std::string type = mate::V8ToString(value);
|
||||||
|
|
||||||
|
auto* render_view_host = web_contents()->GetRenderViewHost();
|
||||||
|
if (render_view_host) {
|
||||||
|
auto* impl = content::RenderWidgetHostImpl::FromID(
|
||||||
|
render_view_host->GetProcess()->GetID(),
|
||||||
|
render_view_host->GetRoutingID());
|
||||||
|
if (impl)
|
||||||
|
impl->SetBackgroundOpaque(type.empty() ? !window_->transparent() : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TopLevelWindow::SetVibrancy(isolate, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::FocusOnWebView() {
|
||||||
|
web_contents()->GetRenderViewHost()->GetWidget()->Focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::BlurWebView() {
|
||||||
|
web_contents()->GetRenderViewHost()->GetWidget()->Blur();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BrowserWindow::IsWebViewFocused() {
|
||||||
|
auto* host_view = web_contents()->GetRenderViewHost()->GetWidget()->GetView();
|
||||||
|
return host_view && host_view->HasFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Local<v8::Value> BrowserWindow::GetWebContents(v8::Isolate* isolate) {
|
||||||
|
if (web_contents_.IsEmpty())
|
||||||
|
return v8::Null(isolate);
|
||||||
|
return v8::Local<v8::Value>::New(isolate, web_contents_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert draggable regions in raw format to SkRegion format.
|
||||||
|
std::unique_ptr<SkRegion> BrowserWindow::DraggableRegionsToSkRegion(
|
||||||
|
const std::vector<DraggableRegion>& regions) {
|
||||||
|
auto sk_region = std::make_unique<SkRegion>();
|
||||||
|
for (const DraggableRegion& region : regions) {
|
||||||
|
sk_region->op(
|
||||||
|
region.bounds.x(), region.bounds.y(), region.bounds.right(),
|
||||||
|
region.bounds.bottom(),
|
||||||
|
region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
|
||||||
|
}
|
||||||
|
return sk_region;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::ScheduleUnresponsiveEvent(int ms) {
|
||||||
|
if (!window_unresponsive_closure_.IsCancelled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
window_unresponsive_closure_.Reset(
|
||||||
|
base::Bind(&BrowserWindow::NotifyWindowUnresponsive, GetWeakPtr()));
|
||||||
|
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
|
||||||
|
FROM_HERE, window_unresponsive_closure_.callback(),
|
||||||
|
base::TimeDelta::FromMilliseconds(ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::NotifyWindowUnresponsive() {
|
||||||
|
window_unresponsive_closure_.Cancel();
|
||||||
|
if (!window_->IsClosed() && window_->IsEnabled() &&
|
||||||
|
!IsUnresponsiveEventSuppressed()) {
|
||||||
|
Emit("unresponsive");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::Cleanup() {
|
||||||
|
auto* host = web_contents()->GetRenderViewHost();
|
||||||
|
if (host)
|
||||||
|
host->GetWidget()->RemoveInputEventObserver(this);
|
||||||
|
|
||||||
|
api_web_contents_->DestroyWebContents(true /* async */);
|
||||||
|
Observe(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
mate::WrappableBase* BrowserWindow::New(mate::Arguments* args) {
|
||||||
|
if (!Browser::Get()->is_ready()) {
|
||||||
|
args->ThrowError("Cannot create BrowserWindow before app is ready");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->Length() > 1) {
|
||||||
|
args->ThrowError();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
mate::Dictionary options;
|
||||||
|
if (!(args->Length() == 1 && args->GetNext(&options))) {
|
||||||
|
options = mate::Dictionary::CreateEmpty(args->isolate());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BrowserWindow(args->isolate(), args->GetThis(), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void BrowserWindow::BuildPrototype(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
|
prototype->SetClassName(mate::StringToV8(isolate, "BrowserWindow"));
|
||||||
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
|
.SetMethod("focusOnWebView", &BrowserWindow::FocusOnWebView)
|
||||||
|
.SetMethod("blurWebView", &BrowserWindow::BlurWebView)
|
||||||
|
.SetMethod("isWebViewFocused", &BrowserWindow::IsWebViewFocused)
|
||||||
|
.SetProperty("webContents", &BrowserWindow::GetWebContents);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
v8::Local<v8::Value> BrowserWindow::From(v8::Isolate* isolate,
|
||||||
|
NativeWindow* native_window) {
|
||||||
|
auto* existing = TrackableObject::FromWrappedClass(isolate, native_window);
|
||||||
|
if (existing)
|
||||||
|
return existing->GetWrapper();
|
||||||
|
else
|
||||||
|
return v8::Null(isolate);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using atom::api::BrowserWindow;
|
||||||
|
using atom::api::TopLevelWindow;
|
||||||
|
|
||||||
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
|
mate::Dictionary dict(isolate, exports);
|
||||||
|
dict.Set("BrowserWindow", mate::CreateConstructor<BrowserWindow>(
|
||||||
|
isolate, base::Bind(&BrowserWindow::New)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)
|
||||||
126
atom/browser/api/atom_api_browser_window.h
Normal file
126
atom/browser/api/atom_api_browser_window.h
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
// Copyright (c) 2013 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_
|
||||||
|
#define ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "atom/browser/api/atom_api_top_level_window.h"
|
||||||
|
#include "atom/browser/api/atom_api_web_contents.h"
|
||||||
|
#include "base/cancelable_callback.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
class BrowserWindow : public TopLevelWindow,
|
||||||
|
public content::RenderWidgetHost::InputEventObserver,
|
||||||
|
public content::WebContentsObserver,
|
||||||
|
public ExtendedWebContentsObserver {
|
||||||
|
public:
|
||||||
|
static mate::WrappableBase* New(mate::Arguments* args);
|
||||||
|
|
||||||
|
static void BuildPrototype(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype);
|
||||||
|
|
||||||
|
// Returns the BrowserWindow object from |native_window|.
|
||||||
|
static v8::Local<v8::Value> From(v8::Isolate* isolate,
|
||||||
|
NativeWindow* native_window);
|
||||||
|
|
||||||
|
base::WeakPtr<BrowserWindow> GetWeakPtr() {
|
||||||
|
return weak_factory_.GetWeakPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BrowserWindow(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Object> wrapper,
|
||||||
|
const mate::Dictionary& options);
|
||||||
|
~BrowserWindow() override;
|
||||||
|
|
||||||
|
// content::RenderWidgetHost::InputEventObserver:
|
||||||
|
void OnInputEvent(const blink::WebInputEvent& event) override;
|
||||||
|
|
||||||
|
// content::WebContentsObserver:
|
||||||
|
void RenderViewHostChanged(content::RenderViewHost* old_host,
|
||||||
|
content::RenderViewHost* new_host) override;
|
||||||
|
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
|
||||||
|
void DidFirstVisuallyNonEmptyPaint() override;
|
||||||
|
void BeforeUnloadDialogCancelled() override;
|
||||||
|
void OnRendererUnresponsive(content::RenderProcessHost*) override;
|
||||||
|
bool OnMessageReceived(const IPC::Message& message,
|
||||||
|
content::RenderFrameHost* rfh) override;
|
||||||
|
|
||||||
|
// ExtendedWebContentsObserver:
|
||||||
|
void OnCloseContents() override;
|
||||||
|
void OnRendererResponsive() override;
|
||||||
|
|
||||||
|
// NativeWindowObserver:
|
||||||
|
void RequestPreferredWidth(int* width) override;
|
||||||
|
void OnCloseButtonClicked(bool* prevent_default) override;
|
||||||
|
|
||||||
|
// TopLevelWindow:
|
||||||
|
void OnWindowClosed() override;
|
||||||
|
void OnWindowBlur() override;
|
||||||
|
void OnWindowFocus() override;
|
||||||
|
void OnWindowResize() override;
|
||||||
|
void OnWindowLeaveFullScreen() override;
|
||||||
|
void Focus() override;
|
||||||
|
void Blur() override;
|
||||||
|
void SetBackgroundColor(const std::string& color_name) override;
|
||||||
|
void SetBrowserView(v8::Local<v8::Value> value) override;
|
||||||
|
void SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value) override;
|
||||||
|
|
||||||
|
// BrowserWindow APIs.
|
||||||
|
void FocusOnWebView();
|
||||||
|
void BlurWebView();
|
||||||
|
bool IsWebViewFocused();
|
||||||
|
v8::Local<v8::Value> GetWebContents(v8::Isolate* isolate);
|
||||||
|
|
||||||
|
private:
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
void OverrideNSWindowContentView(brightray::InspectableWebContents* iwc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Helpers.
|
||||||
|
|
||||||
|
// Called when the window needs to update its draggable region.
|
||||||
|
void UpdateDraggableRegions(content::RenderFrameHost* rfh,
|
||||||
|
const std::vector<DraggableRegion>& regions);
|
||||||
|
|
||||||
|
// Convert draggable regions in raw format to SkRegion format.
|
||||||
|
std::unique_ptr<SkRegion> DraggableRegionsToSkRegion(
|
||||||
|
const std::vector<DraggableRegion>& regions);
|
||||||
|
|
||||||
|
// Schedule a notification unresponsive event.
|
||||||
|
void ScheduleUnresponsiveEvent(int ms);
|
||||||
|
|
||||||
|
// Dispatch unresponsive event to observers.
|
||||||
|
void NotifyWindowUnresponsive();
|
||||||
|
|
||||||
|
// Cleanup our WebContents observers.
|
||||||
|
void Cleanup();
|
||||||
|
|
||||||
|
// Closure that would be called when window is unresponsive when closing,
|
||||||
|
// it should be cancelled when we can prove that the window is responsive.
|
||||||
|
base::CancelableClosure window_unresponsive_closure_;
|
||||||
|
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
std::vector<DraggableRegion> draggable_regions_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
v8::Global<v8::Value> web_contents_;
|
||||||
|
api::WebContents* api_web_contents_;
|
||||||
|
|
||||||
|
base::WeakPtrFactory<BrowserWindow> weak_factory_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(BrowserWindow);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_
|
||||||
130
atom/browser/api/atom_api_browser_window_mac.mm
Normal file
130
atom/browser/api/atom_api_browser_window_mac.mm
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
// 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_browser_window.h"
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
#include "atom/browser/native_browser_view.h"
|
||||||
|
#include "atom/browser/native_window_mac.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;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface ControlRegionView : NSView
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ControlRegionView
|
||||||
|
|
||||||
|
- (BOOL)mouseDownCanMoveWindow {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSView*)hitTest:(NSPoint)aPoint {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Return a vector of non-draggable regions that fill a window of size
|
||||||
|
// |width| by |height|, but leave gaps where the window should be draggable.
|
||||||
|
std::vector<gfx::Rect> CalculateNonDraggableRegions(
|
||||||
|
std::unique_ptr<SkRegion> draggable,
|
||||||
|
int width,
|
||||||
|
int height) {
|
||||||
|
std::vector<gfx::Rect> result;
|
||||||
|
SkRegion non_draggable;
|
||||||
|
non_draggable.op(0, 0, width, height, SkRegion::kUnion_Op);
|
||||||
|
non_draggable.op(*draggable, SkRegion::kDifference_Op);
|
||||||
|
for (SkRegion::Iterator it(non_draggable); !it.done(); it.next()) {
|
||||||
|
result.push_back(gfx::SkIRectToRect(it.rect()));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void BrowserWindow::OverrideNSWindowContentView(
|
||||||
|
brightray::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];
|
||||||
|
[webView setFrame:[contentView bounds]];
|
||||||
|
[contentView addSubview:webView];
|
||||||
|
[contentView viewDidMoveToWindow];
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::UpdateDraggableRegions(
|
||||||
|
content::RenderFrameHost* rfh,
|
||||||
|
const std::vector<DraggableRegion>& regions) {
|
||||||
|
if (window_->has_frame())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
NSInteger webViewWidth = NSWidth([webView bounds]);
|
||||||
|
NSInteger webViewHeight = NSHeight([webView bounds]);
|
||||||
|
|
||||||
|
if ([webView respondsToSelector:@selector(setMouseDownCanMoveWindow:)]) {
|
||||||
|
[webView setMouseDownCanMoveWindow:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove all ControlRegionViews that are added last time.
|
||||||
|
// Note that [webView subviews] returns the view's mutable internal array and
|
||||||
|
// it should be copied to avoid mutating the original array while enumerating
|
||||||
|
// it.
|
||||||
|
base::scoped_nsobject<NSArray> subviews([[webView subviews] copy]);
|
||||||
|
for (NSView* subview in subviews.get())
|
||||||
|
if ([subview isKindOfClass:[ControlRegionView class]])
|
||||||
|
[subview removeFromSuperview];
|
||||||
|
|
||||||
|
// Draggable regions is implemented by having the whole web view draggable
|
||||||
|
// (mouseDownCanMoveWindow) and overlaying regions that are not draggable.
|
||||||
|
draggable_regions_ = regions;
|
||||||
|
std::vector<gfx::Rect> drag_exclude_rects;
|
||||||
|
if (regions.empty()) {
|
||||||
|
drag_exclude_rects.push_back(gfx::Rect(0, 0, webViewWidth, webViewHeight));
|
||||||
|
} else {
|
||||||
|
drag_exclude_rects = CalculateNonDraggableRegions(
|
||||||
|
DraggableRegionsToSkRegion(regions), webViewWidth, webViewHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window_->browser_view())
|
||||||
|
window_->browser_view()->UpdateDraggableRegions(drag_exclude_rects);
|
||||||
|
|
||||||
|
// Create and add a ControlRegionView for each region that needs to be
|
||||||
|
// excluded from the dragging.
|
||||||
|
for (const auto& rect : drag_exclude_rects) {
|
||||||
|
base::scoped_nsobject<NSView> controlRegion(
|
||||||
|
[[ControlRegionView alloc] initWithFrame:NSZeroRect]);
|
||||||
|
[controlRegion setFrame:NSMakeRect(rect.x(), webViewHeight - rect.bottom(),
|
||||||
|
rect.width(), rect.height())];
|
||||||
|
[webView addSubview:controlRegion];
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppKit will not update its cache of mouseDownCanMoveWindow unless something
|
||||||
|
// changes. Previously we tried adding an NSView and removing it, but for some
|
||||||
|
// reason it required reposting the mouse-down event, and didn't always work.
|
||||||
|
// Calling the below seems to be an effective solution.
|
||||||
|
[[webView window] setMovableByWindowBackground:NO];
|
||||||
|
[[webView window] setMovableByWindowBackground:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
24
atom/browser/api/atom_api_browser_window_views.cc
Normal file
24
atom/browser/api/atom_api_browser_window_views.cc
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// 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_browser_window.h"
|
||||||
|
|
||||||
|
#include "atom/browser/native_window_views.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
void BrowserWindow::UpdateDraggableRegions(
|
||||||
|
content::RenderFrameHost* rfh,
|
||||||
|
const std::vector<DraggableRegion>& regions) {
|
||||||
|
if (window_->has_frame())
|
||||||
|
return;
|
||||||
|
static_cast<NativeWindowViews*>(window_.get())
|
||||||
|
->UpdateDraggableRegions(DraggableRegionsToSkRegion(regions));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
58
atom/browser/api/atom_api_button.cc
Normal file
58
atom/browser/api/atom_api_button.cc
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
// 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_button.h"
|
||||||
|
|
||||||
|
#include "atom/common/api/constructor.h"
|
||||||
|
#include "native_mate/dictionary.h"
|
||||||
|
|
||||||
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
Button::Button(views::Button* button) : View(button) {
|
||||||
|
view()->set_owned_by_client();
|
||||||
|
}
|
||||||
|
|
||||||
|
Button::~Button() {}
|
||||||
|
|
||||||
|
void Button::ButtonPressed(views::Button* sender, const ui::Event& event) {
|
||||||
|
Emit("click");
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
mate::WrappableBase* Button::New(mate::Arguments* args) {
|
||||||
|
args->ThrowError("Button can not be created directly");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void Button::BuildPrototype(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
|
prototype->SetClassName(mate::StringToV8(isolate, "Button"));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using atom::api::Button;
|
||||||
|
|
||||||
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
|
mate::Dictionary dict(isolate, exports);
|
||||||
|
dict.Set("Button",
|
||||||
|
mate::CreateConstructor<Button>(isolate, base::Bind(&Button::New)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_button, Initialize)
|
||||||
38
atom/browser/api/atom_api_button.h
Normal file
38
atom/browser/api/atom_api_button.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2018 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef ATOM_BROWSER_API_ATOM_API_BUTTON_H_
|
||||||
|
#define ATOM_BROWSER_API_ATOM_API_BUTTON_H_
|
||||||
|
|
||||||
|
#include "atom/browser/api/atom_api_view.h"
|
||||||
|
#include "native_mate/handle.h"
|
||||||
|
#include "ui/views/controls/button/button.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
class Button : public View, public views::ButtonListener {
|
||||||
|
public:
|
||||||
|
static mate::WrappableBase* New(mate::Arguments* args);
|
||||||
|
|
||||||
|
static void BuildPrototype(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit Button(views::Button* view);
|
||||||
|
~Button() override;
|
||||||
|
|
||||||
|
// views::ButtonListener:
|
||||||
|
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(Button);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
#endif // ATOM_BROWSER_API_ATOM_API_BUTTON_H_
|
||||||
@@ -18,7 +18,7 @@ using content::TracingController;
|
|||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<base::trace_event::TraceConfig> {
|
struct Converter<base::trace_event::TraceConfig> {
|
||||||
static bool FromV8(v8::Isolate* isolate,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
v8::Local<v8::Value> val,
|
v8::Local<v8::Value> val,
|
||||||
@@ -41,36 +41,39 @@ namespace {
|
|||||||
|
|
||||||
using CompletionCallback = base::Callback<void(const base::FilePath&)>;
|
using CompletionCallback = base::Callback<void(const base::FilePath&)>;
|
||||||
|
|
||||||
scoped_refptr<TracingController::TraceDataSink> GetTraceDataSink(
|
scoped_refptr<TracingController::TraceDataEndpoint> GetTraceDataEndpoint(
|
||||||
const base::FilePath& path, const CompletionCallback& callback) {
|
const base::FilePath& path,
|
||||||
|
const CompletionCallback& callback) {
|
||||||
base::FilePath result_file_path = path;
|
base::FilePath result_file_path = path;
|
||||||
if (result_file_path.empty() && !base::CreateTemporaryFile(&result_file_path))
|
if (result_file_path.empty() && !base::CreateTemporaryFile(&result_file_path))
|
||||||
LOG(ERROR) << "Creating temporary file failed";
|
LOG(ERROR) << "Creating temporary file failed";
|
||||||
|
|
||||||
return TracingController::CreateFileSink(result_file_path,
|
return TracingController::CreateFileEndpoint(
|
||||||
base::Bind(callback,
|
result_file_path, base::Bind(callback, result_file_path));
|
||||||
result_file_path));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopRecording(const base::FilePath& path,
|
void StopRecording(const base::FilePath& path,
|
||||||
const CompletionCallback& callback) {
|
const CompletionCallback& callback) {
|
||||||
TracingController::GetInstance()->StopTracing(
|
TracingController::GetInstance()->StopTracing(
|
||||||
GetTraceDataSink(path, callback));
|
GetTraceDataEndpoint(path, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
auto controller = base::Unretained(TracingController::GetInstance());
|
auto controller = base::Unretained(TracingController::GetInstance());
|
||||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||||
dict.SetMethod("getCategories", base::Bind(
|
dict.SetMethod("getCategories",
|
||||||
&TracingController::GetCategories, controller));
|
base::Bind(&TracingController::GetCategories, controller));
|
||||||
dict.SetMethod("startRecording", base::Bind(
|
dict.SetMethod("startRecording",
|
||||||
&TracingController::StartTracing, controller));
|
base::Bind(&TracingController::StartTracing, controller));
|
||||||
dict.SetMethod("stopRecording", &StopRecording);
|
dict.SetMethod("stopRecording", &StopRecording);
|
||||||
dict.SetMethod("getTraceBufferUsage", base::Bind(
|
dict.SetMethod(
|
||||||
&TracingController::GetTraceBufferUsage, controller));
|
"getTraceBufferUsage",
|
||||||
|
base::Bind(&TracingController::GetTraceBufferUsage, controller));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_content_tracing, Initialize)
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_content_tracing, Initialize)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "atom/browser/api/atom_api_cookies.h"
|
#include "atom/browser/api/atom_api_cookies.h"
|
||||||
|
|
||||||
#include "atom/browser/atom_browser_context.h"
|
#include "atom/browser/atom_browser_context.h"
|
||||||
|
#include "atom/browser/request_context_delegate.h"
|
||||||
#include "atom/common/native_mate_converters/callback.h"
|
#include "atom/common/native_mate_converters/callback.h"
|
||||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||||
#include "atom/common/native_mate_converters/value_converter.h"
|
#include "atom/common/native_mate_converters/value_converter.h"
|
||||||
@@ -14,18 +15,17 @@
|
|||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "native_mate/object_template_builder.h"
|
#include "native_mate/object_template_builder.h"
|
||||||
#include "net/cookies/cookie_monster.h"
|
#include "net/cookies/canonical_cookie.h"
|
||||||
#include "net/cookies/cookie_store.h"
|
#include "net/cookies/cookie_store.h"
|
||||||
#include "net/cookies/cookie_util.h"
|
#include "net/cookies/cookie_util.h"
|
||||||
#include "net/url_request/url_request_context.h"
|
#include "net/url_request/url_request_context.h"
|
||||||
#include "net/url_request/url_request_context_getter.h"
|
#include "net/url_request/url_request_context_getter.h"
|
||||||
|
|
||||||
using atom::AtomCookieDelegate;
|
|
||||||
using content::BrowserThread;
|
using content::BrowserThread;
|
||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<atom::api::Cookies::Error> {
|
struct Converter<atom::api::Cookies::Error> {
|
||||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
atom::api::Cookies::Error val) {
|
atom::api::Cookies::Error val) {
|
||||||
@@ -36,7 +36,7 @@ struct Converter<atom::api::Cookies::Error> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<net::CanonicalCookie> {
|
struct Converter<net::CanonicalCookie> {
|
||||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
const net::CanonicalCookie& val) {
|
const net::CanonicalCookie& val) {
|
||||||
@@ -55,25 +55,21 @@ struct Converter<net::CanonicalCookie> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<net::CookieStore::ChangeCause> {
|
struct Converter<net::CookieChangeCause> {
|
||||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
const net::CookieStore::ChangeCause& val) {
|
const net::CookieChangeCause& val) {
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case net::CookieStore::ChangeCause::INSERTED:
|
case net::CookieChangeCause::INSERTED:
|
||||||
case net::CookieStore::ChangeCause::EXPLICIT:
|
case net::CookieChangeCause::EXPLICIT:
|
||||||
case net::CookieStore::ChangeCause::EXPLICIT_DELETE_BETWEEN:
|
|
||||||
case net::CookieStore::ChangeCause::EXPLICIT_DELETE_PREDICATE:
|
|
||||||
case net::CookieStore::ChangeCause::EXPLICIT_DELETE_SINGLE:
|
|
||||||
case net::CookieStore::ChangeCause::EXPLICIT_DELETE_CANONICAL:
|
|
||||||
return mate::StringToV8(isolate, "explicit");
|
return mate::StringToV8(isolate, "explicit");
|
||||||
case net::CookieStore::ChangeCause::OVERWRITE:
|
case net::CookieChangeCause::OVERWRITE:
|
||||||
return mate::StringToV8(isolate, "overwrite");
|
return mate::StringToV8(isolate, "overwrite");
|
||||||
case net::CookieStore::ChangeCause::EXPIRED:
|
case net::CookieChangeCause::EXPIRED:
|
||||||
return mate::StringToV8(isolate, "expired");
|
return mate::StringToV8(isolate, "expired");
|
||||||
case net::CookieStore::ChangeCause::EVICTED:
|
case net::CookieChangeCause::EVICTED:
|
||||||
return mate::StringToV8(isolate, "evicted");
|
return mate::StringToV8(isolate, "evicted");
|
||||||
case net::CookieStore::ChangeCause::EXPIRED_OVERWRITE:
|
case net::CookieChangeCause::EXPIRED_OVERWRITE:
|
||||||
return mate::StringToV8(isolate, "expired-overwrite");
|
return mate::StringToV8(isolate, "expired-overwrite");
|
||||||
default:
|
default:
|
||||||
return mate::StringToV8(isolate, "unknown");
|
return mate::StringToV8(isolate, "unknown");
|
||||||
@@ -166,15 +162,16 @@ void GetCookiesOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
|||||||
GetCookieStore(getter)->GetAllCookiesAsync(filtered_callback);
|
GetCookieStore(getter)->GetAllCookiesAsync(filtered_callback);
|
||||||
else
|
else
|
||||||
GetCookieStore(getter)->GetAllCookiesForURLAsync(GURL(url),
|
GetCookieStore(getter)->GetAllCookiesForURLAsync(GURL(url),
|
||||||
filtered_callback);
|
filtered_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removes cookie with |url| and |name| in IO thread.
|
// Removes cookie with |url| and |name| in IO thread.
|
||||||
void RemoveCookieOnIOThread(scoped_refptr<net::URLRequestContextGetter> getter,
|
void RemoveCookieOnIOThread(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||||
const GURL& url, const std::string& name,
|
const GURL& url,
|
||||||
|
const std::string& name,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
GetCookieStore(getter)->DeleteCookieAsync(
|
GetCookieStore(getter)->DeleteCookieAsync(
|
||||||
url, name, base::Bind(RunCallbackInUI, callback));
|
url, name, base::BindOnce(RunCallbackInUI, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback of SetCookie.
|
// Callback of SetCookie.
|
||||||
@@ -187,7 +184,7 @@ void OnSetCookie(const Cookies::SetCallback& callback, bool success) {
|
|||||||
void FlushCookieStoreOnIOThread(
|
void FlushCookieStoreOnIOThread(
|
||||||
scoped_refptr<net::URLRequestContextGetter> getter,
|
scoped_refptr<net::URLRequestContextGetter> getter,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
GetCookieStore(getter)->FlushStore(base::Bind(RunCallbackInUI, callback));
|
GetCookieStore(getter)->FlushStore(base::BindOnce(RunCallbackInUI, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets cookie with |details| in IO thread.
|
// Sets cookie with |details| in IO thread.
|
||||||
@@ -210,90 +207,106 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
|||||||
|
|
||||||
base::Time creation_time;
|
base::Time creation_time;
|
||||||
if (details->GetDouble("creationDate", &creation_date)) {
|
if (details->GetDouble("creationDate", &creation_date)) {
|
||||||
creation_time = (creation_date == 0) ?
|
creation_time = (creation_date == 0)
|
||||||
base::Time::UnixEpoch() :
|
? base::Time::UnixEpoch()
|
||||||
base::Time::FromDoubleT(creation_date);
|
: base::Time::FromDoubleT(creation_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
base::Time expiration_time;
|
base::Time expiration_time;
|
||||||
if (details->GetDouble("expirationDate", &expiration_date)) {
|
if (details->GetDouble("expirationDate", &expiration_date)) {
|
||||||
expiration_time = (expiration_date == 0) ?
|
expiration_time = (expiration_date == 0)
|
||||||
base::Time::UnixEpoch() :
|
? base::Time::UnixEpoch()
|
||||||
base::Time::FromDoubleT(expiration_date);
|
: base::Time::FromDoubleT(expiration_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
base::Time last_access_time;
|
base::Time last_access_time;
|
||||||
if (details->GetDouble("lastAccessDate", &last_access_date)) {
|
if (details->GetDouble("lastAccessDate", &last_access_date)) {
|
||||||
last_access_time = (last_access_date == 0) ?
|
last_access_time = (last_access_date == 0)
|
||||||
base::Time::UnixEpoch() :
|
? base::Time::UnixEpoch()
|
||||||
base::Time::FromDoubleT(last_access_date);
|
: base::Time::FromDoubleT(last_access_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetCookieStore(getter)->SetCookieWithDetailsAsync(
|
std::unique_ptr<net::CanonicalCookie> canonical_cookie(
|
||||||
GURL(url), name, value, domain, path, creation_time,
|
net::CanonicalCookie::CreateSanitizedCookie(
|
||||||
expiration_time, last_access_time, secure, http_only,
|
GURL(url), name, value, domain, path, creation_time, expiration_time,
|
||||||
net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT,
|
last_access_time, secure, http_only,
|
||||||
base::Bind(OnSetCookie, callback));
|
net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT));
|
||||||
|
auto completion_callback = base::BindOnce(OnSetCookie, callback);
|
||||||
|
if (!canonical_cookie || !canonical_cookie->IsCanonical()) {
|
||||||
|
std::move(completion_callback).Run(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (url.empty()) {
|
||||||
|
std::move(completion_callback).Run(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (name.empty()) {
|
||||||
|
std::move(completion_callback).Run(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GetCookieStore(getter)->SetCanonicalCookieAsync(
|
||||||
|
std::move(canonical_cookie), secure, http_only,
|
||||||
|
std::move(completion_callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Cookies::Cookies(v8::Isolate* isolate,
|
Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||||
AtomBrowserContext* browser_context)
|
: browser_context_(browser_context) {
|
||||||
: request_context_getter_(browser_context->url_request_context_getter()),
|
|
||||||
cookie_delegate_(browser_context->cookie_delegate()) {
|
|
||||||
Init(isolate);
|
Init(isolate);
|
||||||
cookie_delegate_->AddObserver(this);
|
cookie_change_subscription_ =
|
||||||
|
browser_context->GetRequestContextDelegate()
|
||||||
|
->RegisterCookieChangeCallback(
|
||||||
|
base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Cookies::~Cookies() {
|
Cookies::~Cookies() {}
|
||||||
cookie_delegate_->RemoveObserver(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cookies::Get(const base::DictionaryValue& filter,
|
void Cookies::Get(const base::DictionaryValue& filter,
|
||||||
const GetCallback& callback) {
|
const GetCallback& callback) {
|
||||||
std::unique_ptr<base::DictionaryValue> copied(filter.CreateDeepCopy());
|
std::unique_ptr<base::DictionaryValue> copied(filter.CreateDeepCopy());
|
||||||
auto getter = make_scoped_refptr(request_context_getter_);
|
auto* getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
BrowserThread::IO, FROM_HERE,
|
BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(GetCookiesOnIO, getter, Passed(&copied), callback));
|
base::BindOnce(GetCookiesOnIO, base::RetainedRef(getter),
|
||||||
|
std::move(copied), callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cookies::Remove(const GURL& url, const std::string& name,
|
void Cookies::Remove(const GURL& url,
|
||||||
|
const std::string& name,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
auto getter = make_scoped_refptr(request_context_getter_);
|
auto* getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
BrowserThread::IO, FROM_HERE,
|
BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(RemoveCookieOnIOThread, getter, url, name, callback));
|
base::BindOnce(RemoveCookieOnIOThread, base::RetainedRef(getter), url,
|
||||||
|
name, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cookies::Set(const base::DictionaryValue& details,
|
void Cookies::Set(const base::DictionaryValue& details,
|
||||||
const SetCallback& callback) {
|
const SetCallback& callback) {
|
||||||
std::unique_ptr<base::DictionaryValue> copied(details.CreateDeepCopy());
|
std::unique_ptr<base::DictionaryValue> copied(details.CreateDeepCopy());
|
||||||
auto getter = make_scoped_refptr(request_context_getter_);
|
auto* getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
BrowserThread::IO, FROM_HERE,
|
BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(SetCookieOnIO, getter, Passed(&copied), callback));
|
base::BindOnce(SetCookieOnIO, base::RetainedRef(getter),
|
||||||
|
std::move(copied), callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cookies::FlushStore(const base::Closure& callback) {
|
void Cookies::FlushStore(const base::Closure& callback) {
|
||||||
auto getter = make_scoped_refptr(request_context_getter_);
|
auto* getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
BrowserThread::IO, FROM_HERE,
|
BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(FlushCookieStoreOnIOThread, getter, callback));
|
base::BindOnce(FlushCookieStoreOnIOThread, base::RetainedRef(getter),
|
||||||
|
callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cookies::OnCookieChanged(const net::CanonicalCookie& cookie,
|
void Cookies::OnCookieChanged(const CookieDetails* details) {
|
||||||
bool removed,
|
Emit("changed", *(details->cookie), details->cause, details->removed);
|
||||||
net::CookieStore::ChangeCause cause) {
|
|
||||||
Emit("changed", cookie, cause, removed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
mate::Handle<Cookies> Cookies::Create(
|
mate::Handle<Cookies> Cookies::Create(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate,
|
AtomBrowserContext* browser_context) {
|
||||||
AtomBrowserContext* browser_context) {
|
|
||||||
return mate::CreateHandle(isolate, new Cookies(isolate, browser_context));
|
return mate::CreateHandle(isolate, new Cookies(isolate, browser_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "atom/browser/api/trackable_object.h"
|
#include "atom/browser/api/trackable_object.h"
|
||||||
#include "atom/browser/net/atom_cookie_delegate.h"
|
#include "atom/browser/net/cookie_details.h"
|
||||||
#include "base/callback.h"
|
#include "base/callback_list.h"
|
||||||
#include "native_mate/handle.h"
|
#include "native_mate/handle.h"
|
||||||
#include "net/cookies/canonical_cookie.h"
|
#include "net/cookies/canonical_cookie.h"
|
||||||
|
|
||||||
@@ -27,8 +27,7 @@ class AtomBrowserContext;
|
|||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class Cookies : public mate::TrackableObject<Cookies>,
|
class Cookies : public mate::TrackableObject<Cookies> {
|
||||||
public AtomCookieDelegate::Observer {
|
|
||||||
public:
|
public:
|
||||||
enum Error {
|
enum Error {
|
||||||
SUCCESS,
|
SUCCESS,
|
||||||
@@ -50,19 +49,19 @@ class Cookies : public mate::TrackableObject<Cookies>,
|
|||||||
~Cookies() override;
|
~Cookies() override;
|
||||||
|
|
||||||
void Get(const base::DictionaryValue& filter, const GetCallback& callback);
|
void Get(const base::DictionaryValue& filter, const GetCallback& callback);
|
||||||
void Remove(const GURL& url, const std::string& name,
|
void Remove(const GURL& url,
|
||||||
|
const std::string& name,
|
||||||
const base::Closure& callback);
|
const base::Closure& callback);
|
||||||
void Set(const base::DictionaryValue& details, const SetCallback& callback);
|
void Set(const base::DictionaryValue& details, const SetCallback& callback);
|
||||||
void FlushStore(const base::Closure& callback);
|
void FlushStore(const base::Closure& callback);
|
||||||
|
|
||||||
// AtomCookieDelegate::Observer:
|
// AtomBrowserContext::RegisterCookieChangeCallback subscription:
|
||||||
void OnCookieChanged(const net::CanonicalCookie& cookie,
|
void OnCookieChanged(const CookieDetails*);
|
||||||
bool removed,
|
|
||||||
net::CookieStore::ChangeCause cause) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
net::URLRequestContextGetter* request_context_getter_;
|
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
|
||||||
scoped_refptr<AtomCookieDelegate> cookie_delegate_;
|
cookie_change_subscription_;
|
||||||
|
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Cookies);
|
DISALLOW_COPY_AND_ASSIGN(Cookies);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,16 +6,13 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "atom/browser/atom_browser_main_parts.h"
|
|
||||||
#include "atom/common/native_mate_converters/callback.h"
|
#include "atom/common/native_mate_converters/callback.h"
|
||||||
#include "atom/common/native_mate_converters/value_converter.h"
|
#include "atom/common/native_mate_converters/value_converter.h"
|
||||||
#include "base/json/json_reader.h"
|
#include "base/json/json_reader.h"
|
||||||
#include "base/json/json_writer.h"
|
#include "base/json/json_writer.h"
|
||||||
#include "base/memory/ptr_util.h"
|
|
||||||
#include "content/public/browser/devtools_agent_host.h"
|
#include "content/public/browser/devtools_agent_host.h"
|
||||||
#include "content/public/browser/web_contents.h"
|
#include "content/public/browser/web_contents.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "native_mate/object_template_builder.h"
|
|
||||||
|
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
@@ -26,25 +23,22 @@ namespace atom {
|
|||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
Debugger::Debugger(v8::Isolate* isolate, content::WebContents* web_contents)
|
Debugger::Debugger(v8::Isolate* isolate, content::WebContents* web_contents)
|
||||||
: web_contents_(web_contents),
|
: content::WebContentsObserver(web_contents), web_contents_(web_contents) {
|
||||||
previous_request_id_(0) {
|
|
||||||
Init(isolate);
|
Init(isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
Debugger::~Debugger() {
|
Debugger::~Debugger() {}
|
||||||
}
|
|
||||||
|
|
||||||
void Debugger::AgentHostClosed(DevToolsAgentHost* agent_host,
|
void Debugger::AgentHostClosed(DevToolsAgentHost* agent_host) {
|
||||||
bool replaced_with_another_client) {
|
DCHECK(agent_host == agent_host_);
|
||||||
std::string detach_reason = "target closed";
|
agent_host_ = nullptr;
|
||||||
if (replaced_with_another_client)
|
ClearPendingRequests();
|
||||||
detach_reason = "replaced with devtools";
|
Emit("detach", "target closed");
|
||||||
Emit("detach", detach_reason);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
|
void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
|
||||||
const std::string& message) {
|
const std::string& message) {
|
||||||
DCHECK(agent_host == agent_host_.get());
|
DCHECK(agent_host == agent_host_);
|
||||||
|
|
||||||
v8::Locker locker(isolate());
|
v8::Locker locker(isolate());
|
||||||
v8::HandleScope handle_scope(isolate());
|
v8::HandleScope handle_scope(isolate());
|
||||||
@@ -82,42 +76,52 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Debugger::RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
|
||||||
|
content::RenderFrameHost* new_rfh) {
|
||||||
|
if (agent_host_) {
|
||||||
|
agent_host_->DisconnectWebContents();
|
||||||
|
auto* web_contents = content::WebContents::FromRenderFrameHost(new_rfh);
|
||||||
|
agent_host_->ConnectWebContents(web_contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Debugger::Attach(mate::Arguments* args) {
|
void Debugger::Attach(mate::Arguments* args) {
|
||||||
std::string protocol_version;
|
std::string protocol_version;
|
||||||
args->GetNext(&protocol_version);
|
args->GetNext(&protocol_version);
|
||||||
|
|
||||||
|
if (agent_host_) {
|
||||||
|
args->ThrowError("Debugger is already attached to the target");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!protocol_version.empty() &&
|
if (!protocol_version.empty() &&
|
||||||
!DevToolsAgentHost::IsSupportedProtocolVersion(protocol_version)) {
|
!DevToolsAgentHost::IsSupportedProtocolVersion(protocol_version)) {
|
||||||
args->ThrowError("Requested protocol version is not supported");
|
args->ThrowError("Requested protocol version is not supported");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
agent_host_ = DevToolsAgentHost::GetOrCreateFor(web_contents_);
|
agent_host_ = DevToolsAgentHost::GetOrCreateFor(web_contents_);
|
||||||
if (!agent_host_.get()) {
|
if (!agent_host_) {
|
||||||
args->ThrowError("No target available");
|
args->ThrowError("No target available");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (agent_host_->IsAttached()) {
|
|
||||||
args->ThrowError("Another debugger is already attached to this target");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
agent_host_->AttachClient(this);
|
agent_host_->AttachClient(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Debugger::IsAttached() {
|
bool Debugger::IsAttached() {
|
||||||
return agent_host_.get() ? agent_host_->IsAttached() : false;
|
return agent_host_ && agent_host_->IsAttached();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::Detach() {
|
void Debugger::Detach() {
|
||||||
if (!agent_host_.get())
|
if (!agent_host_)
|
||||||
return;
|
return;
|
||||||
agent_host_->DetachClient(this);
|
agent_host_->DetachClient(this);
|
||||||
AgentHostClosed(agent_host_.get(), false);
|
AgentHostClosed(agent_host_.get());
|
||||||
agent_host_ = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::SendCommand(mate::Arguments* args) {
|
void Debugger::SendCommand(mate::Arguments* args) {
|
||||||
if (!agent_host_.get())
|
if (!agent_host_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::string method;
|
std::string method;
|
||||||
@@ -143,10 +147,19 @@ void Debugger::SendCommand(mate::Arguments* args) {
|
|||||||
agent_host_->DispatchProtocolMessage(this, json_args);
|
agent_host_->DispatchProtocolMessage(this, json_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
mate::Handle<Debugger> Debugger::Create(
|
mate::Handle<Debugger> Debugger::Create(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate,
|
content::WebContents* web_contents) {
|
||||||
content::WebContents* web_contents) {
|
|
||||||
return mate::CreateHandle(isolate, new Debugger(isolate, web_contents));
|
return mate::CreateHandle(isolate, new Debugger(isolate, web_contents));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,8 +182,10 @@ namespace {
|
|||||||
|
|
||||||
using atom::api::Debugger;
|
using atom::api::Debugger;
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
mate::Dictionary(isolate, exports)
|
mate::Dictionary(isolate, exports)
|
||||||
.Set("Debugger", Debugger::GetConstructor(isolate)->GetFunction());
|
.Set("Debugger", Debugger::GetConstructor(isolate)->GetFunction());
|
||||||
@@ -178,4 +193,4 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_debugger, Initialize);
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_debugger, Initialize);
|
||||||
|
|||||||
@@ -12,12 +12,13 @@
|
|||||||
#include "base/callback.h"
|
#include "base/callback.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
#include "content/public/browser/devtools_agent_host_client.h"
|
#include "content/public/browser/devtools_agent_host_client.h"
|
||||||
|
#include "content/public/browser/web_contents_observer.h"
|
||||||
#include "native_mate/handle.h"
|
#include "native_mate/handle.h"
|
||||||
|
|
||||||
namespace content {
|
namespace content {
|
||||||
class DevToolsAgentHost;
|
class DevToolsAgentHost;
|
||||||
class WebContents;
|
class WebContents;
|
||||||
}
|
} // namespace content
|
||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
class Arguments;
|
class Arguments;
|
||||||
@@ -27,15 +28,15 @@ namespace atom {
|
|||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class Debugger: public mate::TrackableObject<Debugger>,
|
class Debugger : public mate::TrackableObject<Debugger>,
|
||||||
public content::DevToolsAgentHostClient {
|
public content::DevToolsAgentHostClient,
|
||||||
|
public content::WebContentsObserver {
|
||||||
public:
|
public:
|
||||||
using SendCommandCallback =
|
using SendCommandCallback =
|
||||||
base::Callback<void(const base::DictionaryValue&,
|
base::Callback<void(const base::Value&, const base::Value&)>;
|
||||||
const base::DictionaryValue&)>;
|
|
||||||
|
|
||||||
static mate::Handle<Debugger> Create(
|
static mate::Handle<Debugger> Create(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate, content::WebContents* web_contents);
|
content::WebContents* web_contents);
|
||||||
|
|
||||||
// mate::TrackableObject:
|
// mate::TrackableObject:
|
||||||
static void BuildPrototype(v8::Isolate* isolate,
|
static void BuildPrototype(v8::Isolate* isolate,
|
||||||
@@ -46,11 +47,14 @@ class Debugger: public mate::TrackableObject<Debugger>,
|
|||||||
~Debugger() override;
|
~Debugger() override;
|
||||||
|
|
||||||
// content::DevToolsAgentHostClient:
|
// content::DevToolsAgentHostClient:
|
||||||
void AgentHostClosed(content::DevToolsAgentHost* agent_host,
|
void AgentHostClosed(content::DevToolsAgentHost* agent_host) override;
|
||||||
bool replaced_with_another_client) override;
|
|
||||||
void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host,
|
void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host,
|
||||||
const std::string& message) override;
|
const std::string& message) override;
|
||||||
|
|
||||||
|
// content::WebContentsObserver:
|
||||||
|
void RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
|
||||||
|
content::RenderFrameHost* new_rfh) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using PendingRequestMap = std::map<int, SendCommandCallback>;
|
using PendingRequestMap = std::map<int, SendCommandCallback>;
|
||||||
|
|
||||||
@@ -58,12 +62,13 @@ class Debugger: public mate::TrackableObject<Debugger>,
|
|||||||
bool IsAttached();
|
bool IsAttached();
|
||||||
void Detach();
|
void Detach();
|
||||||
void SendCommand(mate::Arguments* args);
|
void SendCommand(mate::Arguments* args);
|
||||||
|
void ClearPendingRequests();
|
||||||
|
|
||||||
content::WebContents* web_contents_; // Weak Reference.
|
content::WebContents* web_contents_; // Weak Reference.
|
||||||
scoped_refptr<content::DevToolsAgentHost> agent_host_;
|
scoped_refptr<content::DevToolsAgentHost> agent_host_;
|
||||||
|
|
||||||
PendingRequestMap pending_requests_;
|
PendingRequestMap pending_requests_;
|
||||||
int previous_request_id_;
|
int previous_request_id_ = 0;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Debugger);
|
DISALLOW_COPY_AND_ASSIGN(Debugger);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,85 +4,172 @@
|
|||||||
|
|
||||||
#include "atom/browser/api/atom_api_desktop_capturer.h"
|
#include "atom/browser/api/atom_api_desktop_capturer.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using base::PlatformThreadRef;
|
using base::PlatformThreadRef;
|
||||||
|
|
||||||
#include "atom/common/api/atom_api_native_image.h"
|
#include "atom/common/api/atom_api_native_image.h"
|
||||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||||
|
#include "base/strings/string_number_conversions.h"
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
#include "base/task_scheduler/post_task.h"
|
||||||
|
#include "base/threading/thread_task_runner_handle.h"
|
||||||
#include "chrome/browser/media/desktop_media_list.h"
|
#include "chrome/browser/media/desktop_media_list.h"
|
||||||
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "content/public/browser/desktop_capture.h"
|
#include "content/public/browser/desktop_capture.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
|
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
|
||||||
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
|
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
#include "third_party/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h"
|
||||||
|
#include "third_party/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h"
|
||||||
|
#include "ui/display/win/display_info.h"
|
||||||
|
#endif // defined(OS_WIN)
|
||||||
|
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<DesktopMediaList::Source> {
|
struct Converter<atom::api::DesktopCapturer::Source> {
|
||||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
static v8::Local<v8::Value> ToV8(
|
||||||
const DesktopMediaList::Source& source) {
|
v8::Isolate* isolate,
|
||||||
|
const atom::api::DesktopCapturer::Source& source) {
|
||||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||||
content::DesktopMediaID id = source.id;
|
content::DesktopMediaID id = source.media_list_source.id;
|
||||||
dict.Set("name", base::UTF16ToUTF8(source.name));
|
dict.Set("name", base::UTF16ToUTF8(source.media_list_source.name));
|
||||||
dict.Set("id", id.ToString());
|
dict.Set("id", id.ToString());
|
||||||
dict.Set(
|
dict.Set("thumbnail",
|
||||||
"thumbnail",
|
atom::api::NativeImage::Create(
|
||||||
atom::api::NativeImage::Create(isolate, gfx::Image(source.thumbnail)));
|
isolate, gfx::Image(source.media_list_source.thumbnail)));
|
||||||
|
dict.Set("display_id", source.display_id);
|
||||||
return ConvertToV8(isolate, dict);
|
return ConvertToV8(isolate, dict);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mate
|
} // namespace mate
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void EmitFinished(
|
||||||
|
const std::vector<atom::api::DesktopCapturer::Source>& sources,
|
||||||
|
atom::api::DesktopCapturer* cap) {
|
||||||
|
cap->Emit("finished", sources);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartHandlingTask(bool capture_window,
|
||||||
|
bool capture_screen,
|
||||||
|
const gfx::Size& thumbnail_size,
|
||||||
|
atom::api::DesktopCapturer* cap) {
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
if (content::desktop_capture::CreateDesktopCaptureOptions()
|
||||||
|
.allow_directx_capturer()) {
|
||||||
|
// DxgiDuplicatorController should be alive in this scope according to
|
||||||
|
// screen_capturer_win.cc.
|
||||||
|
auto duplicator = webrtc::DxgiDuplicatorController::Instance();
|
||||||
|
cap->using_directx_capturer_ =
|
||||||
|
webrtc::ScreenCapturerWinDirectx::IsSupported();
|
||||||
|
}
|
||||||
|
#endif // defined(OS_WIN)
|
||||||
|
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer(
|
||||||
|
capture_screen ? content::desktop_capture::CreateScreenCapturer()
|
||||||
|
: nullptr);
|
||||||
|
std::unique_ptr<webrtc::DesktopCapturer> window_capturer(
|
||||||
|
capture_window ? content::desktop_capture::CreateWindowCapturer()
|
||||||
|
: nullptr);
|
||||||
|
cap->media_list_.reset(new NativeDesktopMediaList(
|
||||||
|
std::move(screen_capturer), std::move(window_capturer)));
|
||||||
|
|
||||||
|
cap->media_list_->SetThumbnailSize(thumbnail_size);
|
||||||
|
cap->media_list_->StartUpdating(cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnRefreshFinishedTask(atom::api::DesktopCapturer* cap) {
|
||||||
|
const auto media_list_sources = cap->media_list_->GetSources();
|
||||||
|
std::vector<atom::api::DesktopCapturer::Source> sources;
|
||||||
|
for (const auto& media_list_source : media_list_sources) {
|
||||||
|
sources.emplace_back(
|
||||||
|
atom::api::DesktopCapturer::Source{media_list_source, std::string()});
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
// Gather the same unique screen IDs used by the electron.screen API in order
|
||||||
|
// to provide an association between it and desktopCapturer/getUserMedia.
|
||||||
|
// This is only required when using the DirectX capturer, otherwise the IDs
|
||||||
|
// across the APIs already match.
|
||||||
|
if (cap->using_directx_capturer_) {
|
||||||
|
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);
|
||||||
|
int device_name_index = 0;
|
||||||
|
for (auto& source : sources) {
|
||||||
|
if (source.media_list_source.id.type ==
|
||||||
|
content::DesktopMediaID::TYPE_SCREEN) {
|
||||||
|
const auto& device_name = device_names[device_name_index++];
|
||||||
|
std::wstring wide_device_name;
|
||||||
|
base::UTF8ToWide(device_name.c_str(), device_name.size(),
|
||||||
|
&wide_device_name);
|
||||||
|
const int64_t device_id =
|
||||||
|
display::win::DisplayInfo::DeviceIdFromDeviceName(
|
||||||
|
wide_device_name.c_str());
|
||||||
|
source.display_id = base::Int64ToString(device_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(OS_MACOSX)
|
||||||
|
// On Mac, the IDs across the APIs match.
|
||||||
|
for (auto& source : sources) {
|
||||||
|
if (source.media_list_source.id.type ==
|
||||||
|
content::DesktopMediaID::TYPE_SCREEN) {
|
||||||
|
source.display_id = base::Int64ToString(source.media_list_source.id.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // defined(OS_WIN)
|
||||||
|
// TODO(ajmacd): Add Linux support. The IDs across APIs differ but Chrome only
|
||||||
|
// supports capturing the entire desktop on Linux. Revisit this if individual
|
||||||
|
// screen support is added.
|
||||||
|
|
||||||
|
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
||||||
|
base::Bind(EmitFinished, sources, cap));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {
|
DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {
|
||||||
Init(isolate);
|
Init(isolate);
|
||||||
|
capture_thread_ = base::CreateSequencedTaskRunnerWithTraits(
|
||||||
|
{base::WithBaseSyncPrimitives(), base::MayBlock(),
|
||||||
|
base::TaskPriority::USER_VISIBLE});
|
||||||
}
|
}
|
||||||
|
|
||||||
DesktopCapturer::~DesktopCapturer() {
|
DesktopCapturer::~DesktopCapturer() {}
|
||||||
}
|
|
||||||
|
|
||||||
void DesktopCapturer::StartHandling(bool capture_window,
|
void DesktopCapturer::StartHandling(bool capture_window,
|
||||||
bool capture_screen,
|
bool capture_screen,
|
||||||
const gfx::Size& thumbnail_size) {
|
const gfx::Size& thumbnail_size) {
|
||||||
webrtc::DesktopCaptureOptions options =
|
capture_thread_->PostTask(
|
||||||
content::CreateDesktopCaptureOptions();
|
FROM_HERE, base::BindOnce(StartHandlingTask, capture_window,
|
||||||
|
capture_screen, thumbnail_size, this));
|
||||||
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer(
|
|
||||||
capture_screen ? webrtc::DesktopCapturer::CreateScreenCapturer(options)
|
|
||||||
: nullptr);
|
|
||||||
std::unique_ptr<webrtc::DesktopCapturer> window_capturer(
|
|
||||||
capture_window ? webrtc::DesktopCapturer::CreateWindowCapturer(options)
|
|
||||||
: nullptr);
|
|
||||||
media_list_.reset(new NativeDesktopMediaList(
|
|
||||||
std::move(screen_capturer), std::move(window_capturer)));
|
|
||||||
|
|
||||||
media_list_->SetThumbnailSize(thumbnail_size);
|
|
||||||
media_list_->StartUpdating(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopCapturer::OnSourceAdded(int index) {
|
void DesktopCapturer::OnSourceAdded(int index) {}
|
||||||
}
|
|
||||||
|
|
||||||
void DesktopCapturer::OnSourceRemoved(int index) {
|
void DesktopCapturer::OnSourceRemoved(int index) {}
|
||||||
}
|
|
||||||
|
|
||||||
void DesktopCapturer::OnSourceMoved(int old_index, int new_index) {
|
void DesktopCapturer::OnSourceMoved(int old_index, int new_index) {}
|
||||||
}
|
|
||||||
|
|
||||||
void DesktopCapturer::OnSourceNameChanged(int index) {
|
void DesktopCapturer::OnSourceNameChanged(int index) {}
|
||||||
}
|
|
||||||
|
|
||||||
void DesktopCapturer::OnSourceThumbnailChanged(int index) {
|
void DesktopCapturer::OnSourceThumbnailChanged(int index) {}
|
||||||
}
|
|
||||||
|
|
||||||
bool DesktopCapturer::OnRefreshFinished() {
|
bool DesktopCapturer::OnRefreshFinished() {
|
||||||
Emit("finished", media_list_->GetSources());
|
capture_thread_->PostTask(FROM_HERE,
|
||||||
|
base::BindOnce(OnRefreshFinishedTask, this));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +180,8 @@ mate::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
void DesktopCapturer::BuildPrototype(
|
void DesktopCapturer::BuildPrototype(
|
||||||
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
|
v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
prototype->SetClassName(mate::StringToV8(isolate, "DesktopCapturer"));
|
prototype->SetClassName(mate::StringToV8(isolate, "DesktopCapturer"));
|
||||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
|
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
|
||||||
@@ -105,8 +193,10 @@ void DesktopCapturer::BuildPrototype(
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.Set("desktopCapturer", atom::api::DesktopCapturer::Create(isolate));
|
dict.Set("desktopCapturer", atom::api::DesktopCapturer::Create(isolate));
|
||||||
@@ -114,4 +204,4 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_desktop_capturer, Initialize);
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_desktop_capturer, Initialize);
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
#ifndef ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
#ifndef ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||||
#define ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
#define ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "atom/browser/api/event_emitter.h"
|
#include "atom/browser/api/event_emitter.h"
|
||||||
#include "chrome/browser/media/desktop_media_list_observer.h"
|
#include "chrome/browser/media/desktop_media_list_observer.h"
|
||||||
#include "chrome/browser/media/native_desktop_media_list.h"
|
#include "chrome/browser/media/native_desktop_media_list.h"
|
||||||
@@ -14,9 +16,15 @@ namespace atom {
|
|||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class DesktopCapturer: public mate::EventEmitter<DesktopCapturer>,
|
class DesktopCapturer : public mate::EventEmitter<DesktopCapturer>,
|
||||||
public DesktopMediaListObserver {
|
public DesktopMediaListObserver {
|
||||||
public:
|
public:
|
||||||
|
struct Source {
|
||||||
|
DesktopMediaList::Source media_list_source;
|
||||||
|
// Will be an empty string if not available.
|
||||||
|
std::string display_id;
|
||||||
|
};
|
||||||
|
|
||||||
static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
|
static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
|
||||||
|
|
||||||
static void BuildPrototype(v8::Isolate* isolate,
|
static void BuildPrototype(v8::Isolate* isolate,
|
||||||
@@ -26,6 +34,11 @@ class DesktopCapturer: public mate::EventEmitter<DesktopCapturer>,
|
|||||||
bool capture_screen,
|
bool capture_screen,
|
||||||
const gfx::Size& thumbnail_size);
|
const gfx::Size& thumbnail_size);
|
||||||
|
|
||||||
|
std::unique_ptr<DesktopMediaList> media_list_;
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
bool using_directx_capturer_ = false;
|
||||||
|
#endif // defined(OS_WIN)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit DesktopCapturer(v8::Isolate* isolate);
|
explicit DesktopCapturer(v8::Isolate* isolate);
|
||||||
~DesktopCapturer() override;
|
~DesktopCapturer() override;
|
||||||
@@ -39,7 +52,7 @@ class DesktopCapturer: public mate::EventEmitter<DesktopCapturer>,
|
|||||||
bool OnRefreshFinished() override;
|
bool OnRefreshFinished() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<DesktopMediaList> media_list_;
|
scoped_refptr<base::SequencedTaskRunner> capture_thread_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(DesktopCapturer);
|
DISALLOW_COPY_AND_ASSIGN(DesktopCapturer);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "atom/browser/api/atom_api_window.h"
|
#include "atom/browser/api/atom_api_browser_window.h"
|
||||||
#include "atom/browser/native_window.h"
|
#include "atom/browser/native_window.h"
|
||||||
#include "atom/browser/ui/certificate_trust.h"
|
#include "atom/browser/ui/certificate_trust.h"
|
||||||
#include "atom/browser/ui/file_dialog.h"
|
#include "atom/browser/ui/file_dialog.h"
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<file_dialog::Filter> {
|
struct Converter<file_dialog::Filter> {
|
||||||
static bool FromV8(v8::Isolate* isolate,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
v8::Local<v8::Value> val,
|
v8::Local<v8::Value> val,
|
||||||
@@ -37,7 +37,7 @@ struct Converter<file_dialog::Filter> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<file_dialog::DialogSettings> {
|
struct Converter<file_dialog::DialogSettings> {
|
||||||
static bool FromV8(v8::Isolate* isolate,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
v8::Local<v8::Value> val,
|
v8::Local<v8::Value> val,
|
||||||
@@ -54,9 +54,9 @@ struct Converter<file_dialog::DialogSettings> {
|
|||||||
dict.Get("filters", &(out->filters));
|
dict.Get("filters", &(out->filters));
|
||||||
dict.Get("properties", &(out->properties));
|
dict.Get("properties", &(out->properties));
|
||||||
dict.Get("showsTagField", &(out->shows_tag_field));
|
dict.Get("showsTagField", &(out->shows_tag_field));
|
||||||
#if defined(MAS_BUILD)
|
#if defined(MAS_BUILD)
|
||||||
dict.Get("securityScopedBookmarks", &(out->security_scoped_bookmarks));
|
dict.Get("securityScopedBookmarks", &(out->security_scoped_bookmarks));
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -80,8 +80,7 @@ void ShowMessageBox(int type,
|
|||||||
mate::Arguments* args) {
|
mate::Arguments* args) {
|
||||||
v8::Local<v8::Value> peek = args->PeekNext();
|
v8::Local<v8::Value> peek = args->PeekNext();
|
||||||
atom::MessageBoxCallback callback;
|
atom::MessageBoxCallback callback;
|
||||||
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(),
|
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(), peek,
|
||||||
peek,
|
|
||||||
&callback)) {
|
&callback)) {
|
||||||
atom::ShowMessageBox(window, static_cast<atom::MessageBoxType>(type),
|
atom::ShowMessageBox(window, static_cast<atom::MessageBoxType>(type),
|
||||||
buttons, default_id, cancel_id, options, title,
|
buttons, default_id, cancel_id, options, title,
|
||||||
@@ -99,9 +98,8 @@ void ShowOpenDialog(const file_dialog::DialogSettings& settings,
|
|||||||
mate::Arguments* args) {
|
mate::Arguments* args) {
|
||||||
v8::Local<v8::Value> peek = args->PeekNext();
|
v8::Local<v8::Value> peek = args->PeekNext();
|
||||||
file_dialog::OpenDialogCallback callback;
|
file_dialog::OpenDialogCallback callback;
|
||||||
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(args->isolate(),
|
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(
|
||||||
peek,
|
args->isolate(), peek, &callback)) {
|
||||||
&callback)) {
|
|
||||||
file_dialog::ShowOpenDialog(settings, callback);
|
file_dialog::ShowOpenDialog(settings, callback);
|
||||||
} else {
|
} else {
|
||||||
std::vector<base::FilePath> paths;
|
std::vector<base::FilePath> paths;
|
||||||
@@ -114,9 +112,8 @@ void ShowSaveDialog(const file_dialog::DialogSettings& settings,
|
|||||||
mate::Arguments* args) {
|
mate::Arguments* args) {
|
||||||
v8::Local<v8::Value> peek = args->PeekNext();
|
v8::Local<v8::Value> peek = args->PeekNext();
|
||||||
file_dialog::SaveDialogCallback callback;
|
file_dialog::SaveDialogCallback callback;
|
||||||
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(args->isolate(),
|
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(
|
||||||
peek,
|
args->isolate(), peek, &callback)) {
|
||||||
&callback)) {
|
|
||||||
file_dialog::ShowSaveDialog(settings, callback);
|
file_dialog::ShowSaveDialog(settings, callback);
|
||||||
} else {
|
} else {
|
||||||
base::FilePath path;
|
base::FilePath path;
|
||||||
@@ -125,8 +122,10 @@ void ShowSaveDialog(const file_dialog::DialogSettings& settings,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||||
dict.SetMethod("showMessageBox", &ShowMessageBox);
|
dict.SetMethod("showMessageBox", &ShowMessageBox);
|
||||||
dict.SetMethod("showErrorBox", &atom::ShowErrorBox);
|
dict.SetMethod("showErrorBox", &atom::ShowErrorBox);
|
||||||
@@ -140,4 +139,4 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_dialog, Initialize)
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_dialog, Initialize)
|
||||||
|
|||||||
@@ -19,22 +19,23 @@
|
|||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<content::DownloadItem::DownloadState> {
|
struct Converter<download::DownloadItem::DownloadState> {
|
||||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
static v8::Local<v8::Value> ToV8(
|
||||||
content::DownloadItem::DownloadState state) {
|
v8::Isolate* isolate,
|
||||||
|
download::DownloadItem::DownloadState state) {
|
||||||
std::string download_state;
|
std::string download_state;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case content::DownloadItem::IN_PROGRESS:
|
case download::DownloadItem::IN_PROGRESS:
|
||||||
download_state = "progressing";
|
download_state = "progressing";
|
||||||
break;
|
break;
|
||||||
case content::DownloadItem::COMPLETE:
|
case download::DownloadItem::COMPLETE:
|
||||||
download_state = "completed";
|
download_state = "completed";
|
||||||
break;
|
break;
|
||||||
case content::DownloadItem::CANCELLED:
|
case download::DownloadItem::CANCELLED:
|
||||||
download_state = "cancelled";
|
download_state = "cancelled";
|
||||||
break;
|
break;
|
||||||
case content::DownloadItem::INTERRUPTED:
|
case download::DownloadItem::INTERRUPTED:
|
||||||
download_state = "interrupted";
|
download_state = "interrupted";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -57,7 +58,7 @@ std::map<uint32_t, v8::Global<v8::Object>> g_download_item_objects;
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
DownloadItem::DownloadItem(v8::Isolate* isolate,
|
DownloadItem::DownloadItem(v8::Isolate* isolate,
|
||||||
content::DownloadItem* download_item)
|
download::DownloadItem* download_item)
|
||||||
: download_item_(download_item) {
|
: download_item_(download_item) {
|
||||||
download_item_->AddObserver(this);
|
download_item_->AddObserver(this);
|
||||||
Init(isolate);
|
Init(isolate);
|
||||||
@@ -75,18 +76,18 @@ DownloadItem::~DownloadItem() {
|
|||||||
g_download_item_objects.erase(weak_map_id());
|
g_download_item_objects.erase(weak_map_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadItem::OnDownloadUpdated(content::DownloadItem* item) {
|
void DownloadItem::OnDownloadUpdated(download::DownloadItem* item) {
|
||||||
if (download_item_->IsDone()) {
|
if (download_item_->IsDone()) {
|
||||||
Emit("done", item->GetState());
|
Emit("done", item->GetState());
|
||||||
// Destroy the item once item is downloaded.
|
// Destroy the item once item is downloaded.
|
||||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
|
||||||
FROM_HERE, GetDestroyClosure());
|
GetDestroyClosure());
|
||||||
} else {
|
} else {
|
||||||
Emit("updated", item->GetState());
|
Emit("updated", item->GetState());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadItem::OnDownloadDestroyed(content::DownloadItem* download_item) {
|
void DownloadItem::OnDownloadDestroyed(download::DownloadItem* download_item) {
|
||||||
download_item_ = nullptr;
|
download_item_ = nullptr;
|
||||||
// Destroy the native class immediately when downloadItem is destroyed.
|
// Destroy the native class immediately when downloadItem is destroyed.
|
||||||
delete this;
|
delete this;
|
||||||
@@ -129,12 +130,11 @@ bool DownloadItem::HasUserGesture() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string DownloadItem::GetFilename() const {
|
std::string DownloadItem::GetFilename() const {
|
||||||
return base::UTF16ToUTF8(net::GenerateFileName(GetURL(),
|
return base::UTF16ToUTF8(
|
||||||
GetContentDisposition(),
|
net::GenerateFileName(GetURL(), GetContentDisposition(), std::string(),
|
||||||
std::string(),
|
download_item_->GetSuggestedFilename(),
|
||||||
download_item_->GetSuggestedFilename(),
|
GetMimeType(), "download")
|
||||||
GetMimeType(),
|
.LossyDisplayName());
|
||||||
"download").LossyDisplayName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DownloadItem::GetContentDisposition() const {
|
std::string DownloadItem::GetContentDisposition() const {
|
||||||
@@ -149,7 +149,7 @@ const std::vector<GURL>& DownloadItem::GetURLChain() const {
|
|||||||
return download_item_->GetUrlChain();
|
return download_item_->GetUrlChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
content::DownloadItem::DownloadState DownloadItem::GetState() const {
|
download::DownloadItem::DownloadState DownloadItem::GetState() const {
|
||||||
return download_item_->GetState();
|
return download_item_->GetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,9 +206,9 @@ void DownloadItem::BuildPrototype(v8::Isolate* isolate,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
mate::Handle<DownloadItem> DownloadItem::Create(
|
mate::Handle<DownloadItem> DownloadItem::Create(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate, content::DownloadItem* item) {
|
download::DownloadItem* item) {
|
||||||
auto existing = TrackableObject::FromWrappedClass(isolate, item);
|
auto* existing = TrackableObject::FromWrappedClass(isolate, item);
|
||||||
if (existing)
|
if (existing)
|
||||||
return mate::CreateHandle(isolate, static_cast<DownloadItem*>(existing));
|
return mate::CreateHandle(isolate, static_cast<DownloadItem*>(existing));
|
||||||
|
|
||||||
@@ -226,8 +226,10 @@ mate::Handle<DownloadItem> DownloadItem::Create(
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
mate::Dictionary(isolate, exports)
|
mate::Dictionary(isolate, exports)
|
||||||
.Set("DownloadItem",
|
.Set("DownloadItem",
|
||||||
@@ -236,4 +238,4 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_download_item, Initialize);
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_download_item, Initialize);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include "atom/browser/api/trackable_object.h"
|
#include "atom/browser/api/trackable_object.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "content/public/browser/download_item.h"
|
#include "components/download/public/common/download_item.h"
|
||||||
#include "native_mate/handle.h"
|
#include "native_mate/handle.h"
|
||||||
#include "url/gurl.h"
|
#include "url/gurl.h"
|
||||||
|
|
||||||
@@ -19,10 +19,10 @@ namespace atom {
|
|||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
||||||
public content::DownloadItem::Observer {
|
public download::DownloadItem::Observer {
|
||||||
public:
|
public:
|
||||||
static mate::Handle<DownloadItem> Create(v8::Isolate* isolate,
|
static mate::Handle<DownloadItem> Create(v8::Isolate* isolate,
|
||||||
content::DownloadItem* item);
|
download::DownloadItem* item);
|
||||||
|
|
||||||
static void BuildPrototype(v8::Isolate* isolate,
|
static void BuildPrototype(v8::Isolate* isolate,
|
||||||
v8::Local<v8::FunctionTemplate> prototype);
|
v8::Local<v8::FunctionTemplate> prototype);
|
||||||
@@ -40,7 +40,7 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
|||||||
std::string GetContentDisposition() const;
|
std::string GetContentDisposition() const;
|
||||||
const GURL& GetURL() const;
|
const GURL& GetURL() const;
|
||||||
const std::vector<GURL>& GetURLChain() const;
|
const std::vector<GURL>& GetURLChain() const;
|
||||||
content::DownloadItem::DownloadState GetState() const;
|
download::DownloadItem::DownloadState GetState() const;
|
||||||
bool IsDone() const;
|
bool IsDone() const;
|
||||||
void SetSavePath(const base::FilePath& path);
|
void SetSavePath(const base::FilePath& path);
|
||||||
base::FilePath GetSavePath() const;
|
base::FilePath GetSavePath() const;
|
||||||
@@ -49,16 +49,16 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
|||||||
double GetStartTime() const;
|
double GetStartTime() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DownloadItem(v8::Isolate* isolate, content::DownloadItem* download_item);
|
DownloadItem(v8::Isolate* isolate, download::DownloadItem* download_item);
|
||||||
~DownloadItem();
|
~DownloadItem() override;
|
||||||
|
|
||||||
// Override content::DownloadItem::Observer methods
|
// Override download::DownloadItem::Observer methods
|
||||||
void OnDownloadUpdated(content::DownloadItem* download) override;
|
void OnDownloadUpdated(download::DownloadItem* download) override;
|
||||||
void OnDownloadDestroyed(content::DownloadItem* download) override;
|
void OnDownloadDestroyed(download::DownloadItem* download) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
base::FilePath save_path_;
|
base::FilePath save_path_;
|
||||||
content::DownloadItem* download_item_;
|
download::DownloadItem* download_item_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(DownloadItem);
|
DISALLOW_COPY_AND_ASSIGN(DownloadItem);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
|
|||||||
|
|
||||||
bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
|
bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(
|
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(accelerator,
|
||||||
accelerator, this)) {
|
this)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,8 +54,8 @@ void GlobalShortcut::Unregister(const ui::Accelerator& accelerator) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
accelerator_callback_map_.erase(accelerator);
|
accelerator_callback_map_.erase(accelerator);
|
||||||
GlobalShortcutListener::GetInstance()->UnregisterAccelerator(
|
GlobalShortcutListener::GetInstance()->UnregisterAccelerator(accelerator,
|
||||||
accelerator, this);
|
this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GlobalShortcut::IsRegistered(const ui::Accelerator& accelerator) {
|
bool GlobalShortcut::IsRegistered(const ui::Accelerator& accelerator) {
|
||||||
@@ -73,8 +73,8 @@ mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void GlobalShortcut::BuildPrototype(
|
void GlobalShortcut::BuildPrototype(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
prototype->SetClassName(mate::StringToV8(isolate, "GlobalShortcut"));
|
prototype->SetClassName(mate::StringToV8(isolate, "GlobalShortcut"));
|
||||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
.SetMethod("register", &GlobalShortcut::Register)
|
.SetMethod("register", &GlobalShortcut::Register)
|
||||||
@@ -89,8 +89,10 @@ void GlobalShortcut::BuildPrototype(
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.Set("globalShortcut", atom::api::GlobalShortcut::Create(isolate));
|
dict.Set("globalShortcut", atom::api::GlobalShortcut::Create(isolate));
|
||||||
@@ -98,4 +100,4 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_global_shortcut, Initialize)
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_global_shortcut, Initialize)
|
||||||
|
|||||||
@@ -45,6 +45,29 @@ struct Converter<in_app_purchase::Transaction> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<in_app_purchase::Product> {
|
||||||
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
const in_app_purchase::Product& val) {
|
||||||
|
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||||
|
dict.SetHidden("simple", true);
|
||||||
|
dict.Set("productIdentifier", val.productIdentifier);
|
||||||
|
dict.Set("localizedDescription", val.localizedDescription);
|
||||||
|
dict.Set("localizedTitle", val.localizedTitle);
|
||||||
|
dict.Set("contentVersion", val.localizedTitle);
|
||||||
|
dict.Set("contentLengths", val.contentLengths);
|
||||||
|
|
||||||
|
// Pricing Information
|
||||||
|
dict.Set("price", val.price);
|
||||||
|
dict.Set("formattedPrice", val.formattedPrice);
|
||||||
|
|
||||||
|
// Downloadable Content Information
|
||||||
|
dict.Set("isDownloadable", val.downloadable);
|
||||||
|
|
||||||
|
return dict.GetHandle();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace mate
|
} // namespace mate
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
@@ -64,15 +87,19 @@ void InAppPurchase::BuildPrototype(v8::Isolate* isolate,
|
|||||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
.SetMethod("canMakePayments", &in_app_purchase::CanMakePayments)
|
.SetMethod("canMakePayments", &in_app_purchase::CanMakePayments)
|
||||||
.SetMethod("getReceiptURL", &in_app_purchase::GetReceiptURL)
|
.SetMethod("getReceiptURL", &in_app_purchase::GetReceiptURL)
|
||||||
.SetMethod("purchaseProduct", &InAppPurchase::PurchaseProduct);
|
.SetMethod("purchaseProduct", &InAppPurchase::PurchaseProduct)
|
||||||
|
.SetMethod("finishAllTransactions",
|
||||||
|
&in_app_purchase::FinishAllTransactions)
|
||||||
|
.SetMethod("finishTransactionByDate",
|
||||||
|
&in_app_purchase::FinishTransactionByDate)
|
||||||
|
.SetMethod("getProducts", &in_app_purchase::GetProducts);
|
||||||
}
|
}
|
||||||
|
|
||||||
InAppPurchase::InAppPurchase(v8::Isolate* isolate) {
|
InAppPurchase::InAppPurchase(v8::Isolate* isolate) {
|
||||||
Init(isolate);
|
Init(isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
InAppPurchase::~InAppPurchase() {
|
InAppPurchase::~InAppPurchase() {}
|
||||||
}
|
|
||||||
|
|
||||||
void InAppPurchase::PurchaseProduct(const std::string& product_id,
|
void InAppPurchase::PurchaseProduct(const std::string& product_id,
|
||||||
mate::Arguments* args) {
|
mate::Arguments* args) {
|
||||||
@@ -112,4 +139,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_in_app_purchase, Initialize)
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_in_app_purchase, Initialize)
|
||||||
|
|||||||
@@ -11,14 +11,15 @@
|
|||||||
#include "atom/browser/api/event_emitter.h"
|
#include "atom/browser/api/event_emitter.h"
|
||||||
#include "atom/browser/mac/in_app_purchase.h"
|
#include "atom/browser/mac/in_app_purchase.h"
|
||||||
#include "atom/browser/mac/in_app_purchase_observer.h"
|
#include "atom/browser/mac/in_app_purchase_observer.h"
|
||||||
|
#include "atom/browser/mac/in_app_purchase_product.h"
|
||||||
#include "native_mate/handle.h"
|
#include "native_mate/handle.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class InAppPurchase: public mate::EventEmitter<InAppPurchase>,
|
class InAppPurchase : public mate::EventEmitter<InAppPurchase>,
|
||||||
public in_app_purchase::TransactionObserver {
|
public in_app_purchase::TransactionObserver {
|
||||||
public:
|
public:
|
||||||
static mate::Handle<InAppPurchase> Create(v8::Isolate* isolate);
|
static mate::Handle<InAppPurchase> Create(v8::Isolate* isolate);
|
||||||
|
|
||||||
|
|||||||
58
atom/browser/api/atom_api_label_button.cc
Normal file
58
atom/browser/api/atom_api_label_button.cc
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
// 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_label_button.h"
|
||||||
|
|
||||||
|
#include "atom/common/api/constructor.h"
|
||||||
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
#include "native_mate/dictionary.h"
|
||||||
|
#include "ui/views/controls/button/label_button.h"
|
||||||
|
|
||||||
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
LabelButton::LabelButton(const std::string& text)
|
||||||
|
: Button(new views::LabelButton(this, base::UTF8ToUTF16(text))) {}
|
||||||
|
|
||||||
|
LabelButton::~LabelButton() {}
|
||||||
|
|
||||||
|
// static
|
||||||
|
mate::WrappableBase* LabelButton::New(mate::Arguments* args,
|
||||||
|
const std::string& text) {
|
||||||
|
// Constructor call.
|
||||||
|
auto* view = new LabelButton(text);
|
||||||
|
view->InitWith(args->isolate(), args->GetThis());
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void LabelButton::BuildPrototype(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
|
prototype->SetClassName(mate::StringToV8(isolate, "LabelButton"));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using atom::api::LabelButton;
|
||||||
|
|
||||||
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
|
mate::Dictionary dict(isolate, exports);
|
||||||
|
dict.Set("LabelButton", mate::CreateConstructor<LabelButton>(
|
||||||
|
isolate, base::Bind(&LabelButton::New)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_label_button, Initialize)
|
||||||
36
atom/browser/api/atom_api_label_button.h
Normal file
36
atom/browser/api/atom_api_label_button.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// Copyright (c) 2018 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef ATOM_BROWSER_API_ATOM_API_LABEL_BUTTON_H_
|
||||||
|
#define ATOM_BROWSER_API_ATOM_API_LABEL_BUTTON_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "atom/browser/api/atom_api_button.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
class LabelButton : public Button {
|
||||||
|
public:
|
||||||
|
static mate::WrappableBase* New(mate::Arguments* args,
|
||||||
|
const std::string& text);
|
||||||
|
|
||||||
|
static void BuildPrototype(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit LabelButton(const std::string& text);
|
||||||
|
~LabelButton() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(LabelButton);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
#endif // ATOM_BROWSER_API_ATOM_API_LABEL_BUTTON_H_
|
||||||
63
atom/browser/api/atom_api_layout_manager.cc
Normal file
63
atom/browser/api/atom_api_layout_manager.cc
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
// 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_layout_manager.h"
|
||||||
|
|
||||||
|
#include "atom/common/api/constructor.h"
|
||||||
|
#include "native_mate/dictionary.h"
|
||||||
|
|
||||||
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
LayoutManager::LayoutManager(views::LayoutManager* layout_manager)
|
||||||
|
: layout_manager_(layout_manager) {
|
||||||
|
DCHECK(layout_manager_);
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutManager::~LayoutManager() {
|
||||||
|
if (managed_by_us_)
|
||||||
|
delete layout_manager_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<views::LayoutManager> LayoutManager::TakeOver() {
|
||||||
|
if (!managed_by_us_) // already taken over.
|
||||||
|
return nullptr;
|
||||||
|
managed_by_us_ = false;
|
||||||
|
return std::unique_ptr<views::LayoutManager>(layout_manager_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
mate::WrappableBase* LayoutManager::New(mate::Arguments* args) {
|
||||||
|
args->ThrowError("LayoutManager can not be created directly");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void LayoutManager::BuildPrototype(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype) {}
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using atom::api::LayoutManager;
|
||||||
|
|
||||||
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
|
mate::Dictionary dict(isolate, exports);
|
||||||
|
dict.Set("LayoutManager", mate::CreateConstructor<LayoutManager>(
|
||||||
|
isolate, base::Bind(&LayoutManager::New)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_layout_manager, Initialize)
|
||||||
44
atom/browser/api/atom_api_layout_manager.h
Normal file
44
atom/browser/api/atom_api_layout_manager.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (c) 2018 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef ATOM_BROWSER_API_ATOM_API_LAYOUT_MANAGER_H_
|
||||||
|
#define ATOM_BROWSER_API_ATOM_API_LAYOUT_MANAGER_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "atom/browser/api/trackable_object.h"
|
||||||
|
#include "ui/views/layout/layout_manager.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
class LayoutManager : public mate::TrackableObject<LayoutManager> {
|
||||||
|
public:
|
||||||
|
static mate::WrappableBase* New(mate::Arguments* args);
|
||||||
|
|
||||||
|
static void BuildPrototype(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype);
|
||||||
|
|
||||||
|
// Take over the ownership of the LayoutManager, and leave weak ref here.
|
||||||
|
std::unique_ptr<views::LayoutManager> TakeOver();
|
||||||
|
|
||||||
|
views::LayoutManager* layout_manager() const { return layout_manager_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit LayoutManager(views::LayoutManager* layout_manager);
|
||||||
|
~LayoutManager() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool managed_by_us_ = true;
|
||||||
|
views::LayoutManager* layout_manager_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(LayoutManager);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
#endif // ATOM_BROWSER_API_ATOM_API_LAYOUT_MANAGER_H_
|
||||||
@@ -20,8 +20,7 @@ namespace atom {
|
|||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
Menu::Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
Menu::Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
||||||
: model_(new AtomMenuModel(this)),
|
: model_(new AtomMenuModel(this)) {
|
||||||
parent_(nullptr) {
|
|
||||||
InitWith(isolate, wrapper);
|
InitWith(isolate, wrapper);
|
||||||
model_->AddObserver(this);
|
model_->AddObserver(this);
|
||||||
}
|
}
|
||||||
@@ -70,18 +69,17 @@ bool Menu::GetAcceleratorForCommandIdWithParams(
|
|||||||
ui::Accelerator* accelerator) const {
|
ui::Accelerator* accelerator) const {
|
||||||
v8::Locker locker(isolate());
|
v8::Locker locker(isolate());
|
||||||
v8::HandleScope handle_scope(isolate());
|
v8::HandleScope handle_scope(isolate());
|
||||||
v8::Local<v8::Value> val = get_accelerator_.Run(
|
v8::Local<v8::Value> val =
|
||||||
GetWrapper(), command_id, use_default_accelerator);
|
get_accelerator_.Run(GetWrapper(), command_id, use_default_accelerator);
|
||||||
return mate::ConvertFromV8(isolate(), val, accelerator);
|
return mate::ConvertFromV8(isolate(), val, accelerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::ExecuteCommand(int command_id, int flags) {
|
void Menu::ExecuteCommand(int command_id, int flags) {
|
||||||
v8::Locker locker(isolate());
|
v8::Locker locker(isolate());
|
||||||
v8::HandleScope handle_scope(isolate());
|
v8::HandleScope handle_scope(isolate());
|
||||||
execute_command_.Run(
|
execute_command_.Run(GetWrapper(),
|
||||||
GetWrapper(),
|
mate::internal::CreateEventFromFlags(isolate(), flags),
|
||||||
mate::internal::CreateEventFromFlags(isolate(), flags),
|
command_id);
|
||||||
command_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
|
void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
|
||||||
@@ -90,8 +88,9 @@ void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
|
|||||||
menu_will_show_.Run(GetWrapper());
|
menu_will_show_.Run(GetWrapper());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::InsertItemAt(
|
void Menu::InsertItemAt(int index,
|
||||||
int index, int command_id, const base::string16& label) {
|
int command_id,
|
||||||
|
const base::string16& label) {
|
||||||
model_->InsertItemAt(index, command_id, label);
|
model_->InsertItemAt(index, command_id, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,13 +206,14 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
|
|||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using atom::api::Menu;
|
using atom::api::Menu;
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
Menu::SetConstructor(isolate, base::Bind(&Menu::New));
|
Menu::SetConstructor(isolate, base::Bind(&Menu::New));
|
||||||
|
|
||||||
@@ -228,4 +228,4 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_menu, Initialize)
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_menu, Initialize)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "atom/browser/api/atom_api_window.h"
|
#include "atom/browser/api/atom_api_top_level_window.h"
|
||||||
#include "atom/browser/api/trackable_object.h"
|
#include "atom/browser/api/trackable_object.h"
|
||||||
#include "atom/browser/ui/atom_menu_model.h"
|
#include "atom/browser/ui/atom_menu_model.h"
|
||||||
#include "base/callback.h"
|
#include "base/callback.h"
|
||||||
@@ -18,8 +18,8 @@ namespace atom {
|
|||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class Menu : public mate::TrackableObject<Menu>,
|
class Menu : public mate::TrackableObject<Menu>,
|
||||||
public AtomMenuModel::Delegate,
|
public AtomMenuModel::Delegate,
|
||||||
public AtomMenuModel::Observer {
|
public AtomMenuModel::Observer {
|
||||||
public:
|
public:
|
||||||
static mate::WrappableBase* New(mate::Arguments* args);
|
static mate::WrappableBase* New(mate::Arguments* args);
|
||||||
|
|
||||||
@@ -54,12 +54,15 @@ class Menu : public mate::TrackableObject<Menu>,
|
|||||||
void ExecuteCommand(int command_id, int event_flags) override;
|
void ExecuteCommand(int command_id, int event_flags) override;
|
||||||
void MenuWillShow(ui::SimpleMenuModel* source) override;
|
void MenuWillShow(ui::SimpleMenuModel* source) override;
|
||||||
|
|
||||||
virtual void PopupAt(Window* window, int x, int y, int positioning_item,
|
virtual void PopupAt(TopLevelWindow* window,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int positioning_item,
|
||||||
const base::Closure& callback) = 0;
|
const base::Closure& callback) = 0;
|
||||||
virtual void ClosePopupAt(int32_t window_id) = 0;
|
virtual void ClosePopupAt(int32_t window_id) = 0;
|
||||||
|
|
||||||
std::unique_ptr<AtomMenuModel> model_;
|
std::unique_ptr<AtomMenuModel> model_;
|
||||||
Menu* parent_;
|
Menu* parent_ = nullptr;
|
||||||
|
|
||||||
// Observable:
|
// Observable:
|
||||||
void OnMenuWillClose() override;
|
void OnMenuWillClose() override;
|
||||||
@@ -109,12 +112,12 @@ class Menu : public mate::TrackableObject<Menu>,
|
|||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<atom::AtomMenuModel*> {
|
struct Converter<atom::AtomMenuModel*> {
|
||||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Value> val,
|
||||||
atom::AtomMenuModel** out) {
|
atom::AtomMenuModel** out) {
|
||||||
// null would be tranfered to NULL.
|
// null would be tranfered to NULL.
|
||||||
if (val->IsNull()) {
|
if (val->IsNull()) {
|
||||||
|
|||||||
@@ -21,8 +21,12 @@ namespace api {
|
|||||||
class MenuMac : public Menu {
|
class MenuMac : public Menu {
|
||||||
protected:
|
protected:
|
||||||
MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
||||||
|
~MenuMac() override;
|
||||||
|
|
||||||
void PopupAt(Window* window, int x, int y, int positioning_item,
|
void PopupAt(TopLevelWindow* window,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int positioning_item,
|
||||||
const base::Closure& callback) override;
|
const base::Closure& callback) override;
|
||||||
void PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
void PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||||
int32_t window_id,
|
int32_t window_id,
|
||||||
|
|||||||
@@ -9,8 +9,6 @@
|
|||||||
#include "base/mac/scoped_sending_event.h"
|
#include "base/mac/scoped_sending_event.h"
|
||||||
#include "base/message_loop/message_loop.h"
|
#include "base/message_loop/message_loop.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
#include "brightray/browser/inspectable_web_contents.h"
|
|
||||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "content/public/browser/web_contents.h"
|
#include "content/public/browser/web_contents.h"
|
||||||
|
|
||||||
@@ -18,24 +16,33 @@
|
|||||||
|
|
||||||
using content::BrowserThread;
|
using content::BrowserThread;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static scoped_nsobject<NSMenu> applicationMenu_;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
MenuMac::MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
MenuMac::MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
||||||
: Menu(isolate, wrapper),
|
: Menu(isolate, wrapper), weak_factory_(this) {}
|
||||||
weak_factory_(this) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item,
|
MenuMac::~MenuMac() = default;
|
||||||
|
|
||||||
|
void MenuMac::PopupAt(TopLevelWindow* window,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int positioning_item,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
NativeWindow* native_window = window->window();
|
NativeWindow* native_window = window->window();
|
||||||
if (!native_window)
|
if (!native_window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto popup = base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
|
auto popup = base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
|
||||||
native_window->GetWeakPtr(), window->ID(), x, y,
|
native_window->GetWeakPtr(), window->weak_map_id(), x,
|
||||||
positioning_item, callback);
|
y, positioning_item, callback);
|
||||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, popup);
|
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,18 +54,15 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
|||||||
base::Closure callback) {
|
base::Closure callback) {
|
||||||
if (!native_window)
|
if (!native_window)
|
||||||
return;
|
return;
|
||||||
brightray::InspectableWebContents* web_contents =
|
NSWindow* nswindow = native_window->GetNativeWindow();
|
||||||
native_window->inspectable_web_contents();
|
|
||||||
if (!web_contents)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto close_callback = base::Bind(
|
auto close_callback = base::Bind(
|
||||||
&MenuMac::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
|
&MenuMac::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
|
||||||
popup_controllers_[window_id] = base::scoped_nsobject<AtomMenuController>(
|
popup_controllers_[window_id] = base::scoped_nsobject<AtomMenuController>([
|
||||||
[[AtomMenuController alloc] initWithModel:model()
|
[AtomMenuController alloc] initWithModel:model()
|
||||||
useDefaultAccelerator:NO]);
|
useDefaultAccelerator:NO]);
|
||||||
NSMenu* menu = [popup_controllers_[window_id] menu];
|
NSMenu* menu = [popup_controllers_[window_id] menu];
|
||||||
NSView* view = web_contents->GetView()->GetNativeView();
|
NSView* view = [nswindow contentView];
|
||||||
|
|
||||||
// Which menu item to show.
|
// Which menu item to show.
|
||||||
NSMenuItem* item = nil;
|
NSMenuItem* item = nil;
|
||||||
@@ -68,7 +72,6 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
|||||||
// (-1, -1) means showing on mouse location.
|
// (-1, -1) means showing on mouse location.
|
||||||
NSPoint position;
|
NSPoint position;
|
||||||
if (x == -1 || y == -1) {
|
if (x == -1 || y == -1) {
|
||||||
NSWindow* nswindow = native_window->GetNativeWindow();
|
|
||||||
position = [view convertPoint:[nswindow mouseLocationOutsideOfEventStream]
|
position = [view convertPoint:[nswindow mouseLocationOutsideOfEventStream]
|
||||||
fromView:nil];
|
fromView:nil];
|
||||||
} else {
|
} else {
|
||||||
@@ -132,10 +135,21 @@ void MenuMac::OnClosed(int32_t window_id, base::Closure callback) {
|
|||||||
// static
|
// static
|
||||||
void Menu::SetApplicationMenu(Menu* base_menu) {
|
void Menu::SetApplicationMenu(Menu* base_menu) {
|
||||||
MenuMac* menu = static_cast<MenuMac*>(base_menu);
|
MenuMac* menu = static_cast<MenuMac*>(base_menu);
|
||||||
base::scoped_nsobject<AtomMenuController> menu_controller(
|
base::scoped_nsobject<AtomMenuController> menu_controller([
|
||||||
[[AtomMenuController alloc] initWithModel:menu->model_.get()
|
[AtomMenuController alloc] initWithModel:menu->model_.get()
|
||||||
useDefaultAccelerator:YES]);
|
useDefaultAccelerator:YES]);
|
||||||
[NSApp setMainMenu:[menu_controller menu]];
|
|
||||||
|
NSRunLoop* currentRunLoop = [NSRunLoop currentRunLoop];
|
||||||
|
[currentRunLoop cancelPerformSelector:@selector(setMainMenu:)
|
||||||
|
target:NSApp
|
||||||
|
argument:applicationMenu_];
|
||||||
|
applicationMenu_.reset([[menu_controller menu] retain]);
|
||||||
|
[[NSRunLoop currentRunLoop]
|
||||||
|
performSelector:@selector(setMainMenu:)
|
||||||
|
target:NSApp
|
||||||
|
argument:applicationMenu_
|
||||||
|
order:0
|
||||||
|
modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
|
||||||
|
|
||||||
// Ensure the menu_controller_ is destroyed after main menu is set.
|
// Ensure the menu_controller_ is destroyed after main menu is set.
|
||||||
menu_controller.swap(menu->menu_controller_);
|
menu_controller.swap(menu->menu_controller_);
|
||||||
|
|||||||
@@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
#include "atom/browser/native_window_views.h"
|
#include "atom/browser/native_window_views.h"
|
||||||
#include "atom/browser/unresponsive_suppressor.h"
|
#include "atom/browser/unresponsive_suppressor.h"
|
||||||
#include "brightray/browser/inspectable_web_contents.h"
|
|
||||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
|
||||||
#include "ui/display/screen.h"
|
#include "ui/display/screen.h"
|
||||||
|
|
||||||
using views::MenuRunner;
|
using views::MenuRunner;
|
||||||
@@ -17,26 +15,25 @@ namespace atom {
|
|||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
||||||
: Menu(isolate, wrapper),
|
: Menu(isolate, wrapper), weak_factory_(this) {}
|
||||||
weak_factory_(this) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item,
|
MenuViews::~MenuViews() = default;
|
||||||
|
|
||||||
|
void MenuViews::PopupAt(TopLevelWindow* window,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int positioning_item,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
NativeWindow* native_window = static_cast<NativeWindow*>(window->window());
|
auto* native_window = static_cast<NativeWindowViews*>(window->window());
|
||||||
if (!native_window)
|
if (!native_window)
|
||||||
return;
|
return;
|
||||||
auto* web_contents = native_window->inspectable_web_contents();
|
|
||||||
if (!web_contents)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// (-1, -1) means showing on mouse location.
|
// (-1, -1) means showing on mouse location.
|
||||||
gfx::Point location;
|
gfx::Point location;
|
||||||
if (x == -1 || y == -1) {
|
if (x == -1 || y == -1) {
|
||||||
location = display::Screen::GetScreen()->GetCursorScreenPoint();
|
location = display::Screen::GetScreen()->GetCursorScreenPoint();
|
||||||
} else {
|
} else {
|
||||||
auto* view = web_contents->GetView()->GetWebView();
|
gfx::Point origin = native_window->GetContentBounds().origin();
|
||||||
gfx::Point origin = view->bounds().origin();
|
|
||||||
location = gfx::Point(origin.x() + x, origin.y() + y);
|
location = gfx::Point(origin.x() + x, origin.y() + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,17 +43,14 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item,
|
|||||||
atom::UnresponsiveSuppressor suppressor;
|
atom::UnresponsiveSuppressor suppressor;
|
||||||
|
|
||||||
// Show the menu.
|
// Show the menu.
|
||||||
int32_t window_id = window->ID();
|
int32_t window_id = window->weak_map_id();
|
||||||
auto close_callback = base::Bind(
|
auto close_callback = base::Bind(
|
||||||
&MenuViews::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
|
&MenuViews::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
|
||||||
menu_runners_[window_id] = std::unique_ptr<MenuRunner>(new MenuRunner(
|
menu_runners_[window_id] =
|
||||||
model(), flags, close_callback));
|
std::make_unique<MenuRunner>(model(), flags, close_callback);
|
||||||
menu_runners_[window_id]->RunMenuAt(
|
menu_runners_[window_id]->RunMenuAt(
|
||||||
static_cast<NativeWindowViews*>(window->window())->widget(),
|
native_window->widget(), NULL, gfx::Rect(location, gfx::Size()),
|
||||||
NULL,
|
views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE);
|
||||||
gfx::Rect(location, gfx::Size()),
|
|
||||||
views::MENU_ANCHOR_TOPLEFT,
|
|
||||||
ui::MENU_SOURCE_MOUSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuViews::ClosePopupAt(int32_t window_id) {
|
void MenuViews::ClosePopupAt(int32_t window_id) {
|
||||||
|
|||||||
@@ -19,9 +19,13 @@ namespace api {
|
|||||||
class MenuViews : public Menu {
|
class MenuViews : public Menu {
|
||||||
public:
|
public:
|
||||||
MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
||||||
|
~MenuViews() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void PopupAt(Window* window, int x, int y, int positioning_item,
|
void PopupAt(TopLevelWindow* window,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int positioning_item,
|
||||||
const base::Closure& callback) override;
|
const base::Closure& callback) override;
|
||||||
void ClosePopupAt(int32_t window_id) override;
|
void ClosePopupAt(int32_t window_id) override;
|
||||||
|
|
||||||
|
|||||||
@@ -58,4 +58,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_net, Initialize)
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_net, Initialize)
|
||||||
|
|||||||
90
atom/browser/api/atom_api_net_log.cc
Normal file
90
atom/browser/api/atom_api_net_log.cc
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
// 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_net_log.h"
|
||||||
|
#include "atom/browser/atom_browser_client.h"
|
||||||
|
#include "atom/common/native_mate_converters/callback.h"
|
||||||
|
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||||
|
#include "base/callback.h"
|
||||||
|
#include "content/public/common/content_switches.h"
|
||||||
|
#include "native_mate/dictionary.h"
|
||||||
|
#include "native_mate/handle.h"
|
||||||
|
|
||||||
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
NetLog::NetLog(v8::Isolate* isolate) {
|
||||||
|
Init(isolate);
|
||||||
|
|
||||||
|
net_log_ = atom::AtomBrowserClient::Get()->GetNetLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
NetLog::~NetLog() {}
|
||||||
|
|
||||||
|
// static
|
||||||
|
v8::Local<v8::Value> NetLog::Create(v8::Isolate* isolate) {
|
||||||
|
return mate::CreateHandle(isolate, new NetLog(isolate)).ToV8();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetLog::StartLogging(mate::Arguments* args) {
|
||||||
|
base::FilePath log_path;
|
||||||
|
if (!args->GetNext(&log_path) || log_path.empty()) {
|
||||||
|
args->ThrowError("The first parameter must be a valid string");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
net_log_->StartDynamicLogging(log_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetLog::IsCurrentlyLogging() {
|
||||||
|
return net_log_->IsDynamicLogging();
|
||||||
|
}
|
||||||
|
|
||||||
|
base::FilePath::StringType NetLog::GetCurrentlyLoggingPath() {
|
||||||
|
return net_log_->GetDynamicLoggingPath().value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetLog::StopLogging(mate::Arguments* args) {
|
||||||
|
base::OnceClosure callback;
|
||||||
|
args->GetNext(&callback);
|
||||||
|
|
||||||
|
net_log_->StopDynamicLogging(std::move(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void NetLog::BuildPrototype(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
|
prototype->SetClassName(mate::StringToV8(isolate, "NetLog"));
|
||||||
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
|
.SetProperty("currentlyLogging", &NetLog::IsCurrentlyLogging)
|
||||||
|
.SetProperty("currentlyLoggingPath", &NetLog::GetCurrentlyLoggingPath)
|
||||||
|
.SetMethod("startLogging", &NetLog::StartLogging)
|
||||||
|
.SetMethod("_stopLogging", &NetLog::StopLogging);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using atom::api::NetLog;
|
||||||
|
|
||||||
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
|
|
||||||
|
mate::Dictionary dict(isolate, exports);
|
||||||
|
dict.Set("netLog", NetLog::Create(isolate));
|
||||||
|
dict.Set("NetLog", NetLog::GetConstructor(isolate)->GetFunction());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_net_log, Initialize)
|
||||||
42
atom/browser/api/atom_api_net_log.h
Normal file
42
atom/browser/api/atom_api_net_log.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// Copyright (c) 2018 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef ATOM_BROWSER_API_ATOM_API_NET_LOG_H_
|
||||||
|
#define ATOM_BROWSER_API_ATOM_API_NET_LOG_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "brightray/browser/net_log.h"
|
||||||
|
#include "native_mate/wrappable.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
class NetLog : public mate::Wrappable<NetLog> {
|
||||||
|
public:
|
||||||
|
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||||
|
|
||||||
|
static void BuildPrototype(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype);
|
||||||
|
|
||||||
|
void StartLogging(mate::Arguments* args);
|
||||||
|
bool IsCurrentlyLogging();
|
||||||
|
base::FilePath::StringType GetCurrentlyLoggingPath();
|
||||||
|
void StopLogging(mate::Arguments* args);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit NetLog(v8::Isolate* isolate);
|
||||||
|
~NetLog() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
brightray::NetLog* net_log_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(NetLog);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
#endif // ATOM_BROWSER_API_ATOM_API_NET_LOG_H_
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "atom/common/native_mate_converters/gfx_converter.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/image_converter.h"
|
||||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||||
|
#include "base/guid.h"
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "brightray/browser/browser_client.h"
|
#include "brightray/browser/browser_client.h"
|
||||||
#include "native_mate/constructor.h"
|
#include "native_mate/constructor.h"
|
||||||
@@ -20,10 +21,11 @@
|
|||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
template<>
|
template <>
|
||||||
struct Converter<brightray::NotificationAction> {
|
struct Converter<brightray::NotificationAction> {
|
||||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
brightray::NotificationAction* out) {
|
v8::Local<v8::Value> val,
|
||||||
|
brightray::NotificationAction* out) {
|
||||||
mate::Dictionary dict;
|
mate::Dictionary dict;
|
||||||
if (!ConvertFromV8(isolate, val, &dict))
|
if (!ConvertFromV8(isolate, val, &dict))
|
||||||
return false;
|
return false;
|
||||||
@@ -36,7 +38,7 @@ struct Converter<brightray::NotificationAction> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
brightray::NotificationAction val) {
|
brightray::NotificationAction val) {
|
||||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||||
dict.Set("text", val.text);
|
dict.Set("text", val.text);
|
||||||
dict.Set("type", val.type);
|
dict.Set("type", val.type);
|
||||||
@@ -155,7 +157,7 @@ void Notification::SetSound(const base::string16& new_sound) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Notification::SetActions(
|
void Notification::SetActions(
|
||||||
const std::vector<brightray::NotificationAction>& actions) {
|
const std::vector<brightray::NotificationAction>& actions) {
|
||||||
actions_ = actions;
|
actions_ = actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,8 +181,7 @@ void Notification::NotificationDisplayed() {
|
|||||||
Emit("show");
|
Emit("show");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notification::NotificationDestroyed() {
|
void Notification::NotificationDestroyed() {}
|
||||||
}
|
|
||||||
|
|
||||||
void Notification::NotificationClosed() {
|
void Notification::NotificationClosed() {
|
||||||
Emit("close");
|
Emit("close");
|
||||||
@@ -197,7 +198,7 @@ void Notification::Close() {
|
|||||||
void Notification::Show() {
|
void Notification::Show() {
|
||||||
Close();
|
Close();
|
||||||
if (presenter_) {
|
if (presenter_) {
|
||||||
notification_ = presenter_->CreateNotification(this);
|
notification_ = presenter_->CreateNotification(this, base::GenerateGUID());
|
||||||
if (notification_) {
|
if (notification_) {
|
||||||
brightray::NotificationOptions options;
|
brightray::NotificationOptions options;
|
||||||
options.title = title_;
|
options.title = title_;
|
||||||
@@ -232,14 +233,12 @@ void Notification::BuildPrototype(v8::Isolate* isolate,
|
|||||||
.SetProperty("subtitle", &Notification::GetSubtitle,
|
.SetProperty("subtitle", &Notification::GetSubtitle,
|
||||||
&Notification::SetSubtitle)
|
&Notification::SetSubtitle)
|
||||||
.SetProperty("body", &Notification::GetBody, &Notification::SetBody)
|
.SetProperty("body", &Notification::GetBody, &Notification::SetBody)
|
||||||
.SetProperty("silent", &Notification::GetSilent,
|
.SetProperty("silent", &Notification::GetSilent, &Notification::SetSilent)
|
||||||
&Notification::SetSilent)
|
|
||||||
.SetProperty("hasReply", &Notification::GetHasReply,
|
.SetProperty("hasReply", &Notification::GetHasReply,
|
||||||
&Notification::SetHasReply)
|
&Notification::SetHasReply)
|
||||||
.SetProperty("replyPlaceholder", &Notification::GetReplyPlaceholder,
|
.SetProperty("replyPlaceholder", &Notification::GetReplyPlaceholder,
|
||||||
&Notification::SetReplyPlaceholder)
|
&Notification::SetReplyPlaceholder)
|
||||||
.SetProperty("sound", &Notification::GetSound,
|
.SetProperty("sound", &Notification::GetSound, &Notification::SetSound)
|
||||||
&Notification::SetSound)
|
|
||||||
.SetProperty("actions", &Notification::GetActions,
|
.SetProperty("actions", &Notification::GetActions,
|
||||||
&Notification::SetActions)
|
&Notification::SetActions)
|
||||||
.SetProperty("closeButtonText", &Notification::GetCloseButtonText,
|
.SetProperty("closeButtonText", &Notification::GetCloseButtonText,
|
||||||
@@ -270,4 +269,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_notification, Initialize)
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_notification, Initialize)
|
||||||
|
|||||||
@@ -5,26 +5,50 @@
|
|||||||
#include "atom/browser/api/atom_api_power_monitor.h"
|
#include "atom/browser/api/atom_api_power_monitor.h"
|
||||||
|
|
||||||
#include "atom/browser/browser.h"
|
#include "atom/browser/browser.h"
|
||||||
|
#include "atom/common/native_mate_converters/callback.h"
|
||||||
#include "base/power_monitor/power_monitor.h"
|
#include "base/power_monitor/power_monitor.h"
|
||||||
#include "base/power_monitor/power_monitor_device_source.h"
|
#include "base/power_monitor/power_monitor_device_source.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
|
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
template <>
|
||||||
|
struct Converter<ui::IdleState> {
|
||||||
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
const ui::IdleState& in) {
|
||||||
|
switch (in) {
|
||||||
|
case ui::IDLE_STATE_ACTIVE:
|
||||||
|
return mate::StringToV8(isolate, "active");
|
||||||
|
case ui::IDLE_STATE_IDLE:
|
||||||
|
return mate::StringToV8(isolate, "idle");
|
||||||
|
case ui::IDLE_STATE_LOCKED:
|
||||||
|
return mate::StringToV8(isolate, "locked");
|
||||||
|
case ui::IDLE_STATE_UNKNOWN:
|
||||||
|
default:
|
||||||
|
return mate::StringToV8(isolate, "unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace mate
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
PowerMonitor::PowerMonitor(v8::Isolate* isolate) {
|
PowerMonitor::PowerMonitor(v8::Isolate* isolate) {
|
||||||
#if defined(OS_LINUX)
|
#if defined(OS_LINUX)
|
||||||
SetShutdownHandler(base::Bind(&PowerMonitor::ShouldShutdown,
|
SetShutdownHandler(
|
||||||
base::Unretained(this)));
|
base::Bind(&PowerMonitor::ShouldShutdown, base::Unretained(this)));
|
||||||
#elif defined(OS_MACOSX)
|
#elif defined(OS_MACOSX)
|
||||||
Browser::Get()->SetShutdownHandler(base::Bind(&PowerMonitor::ShouldShutdown,
|
Browser::Get()->SetShutdownHandler(
|
||||||
base::Unretained(this)));
|
base::Bind(&PowerMonitor::ShouldShutdown, base::Unretained(this)));
|
||||||
#endif
|
#endif
|
||||||
base::PowerMonitor::Get()->AddObserver(this);
|
base::PowerMonitor::Get()->AddObserver(this);
|
||||||
Init(isolate);
|
Init(isolate);
|
||||||
|
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||||
|
InitPlatformSpecificMonitors();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
PowerMonitor::~PowerMonitor() {
|
PowerMonitor::~PowerMonitor() {
|
||||||
@@ -60,6 +84,21 @@ void PowerMonitor::OnResume() {
|
|||||||
Emit("resume");
|
Emit("resume");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PowerMonitor::QuerySystemIdleState(v8::Isolate* isolate,
|
||||||
|
int idle_threshold,
|
||||||
|
const ui::IdleCallback& callback) {
|
||||||
|
if (idle_threshold > 0) {
|
||||||
|
ui::CalculateIdleState(idle_threshold, callback);
|
||||||
|
} else {
|
||||||
|
isolate->ThrowException(v8::Exception::TypeError(mate::StringToV8(
|
||||||
|
isolate, "Invalid idle threshold, must be greater than 0")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerMonitor::QuerySystemIdleTime(const ui::IdleTimeCallback& callback) {
|
||||||
|
ui::CalculateIdleTime(callback);
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
|
v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
|
||||||
if (!Browser::Get()->is_ready()) {
|
if (!Browser::Get()->is_ready()) {
|
||||||
@@ -73,27 +112,32 @@ v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void PowerMonitor::BuildPrototype(
|
void PowerMonitor::BuildPrototype(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
prototype->SetClassName(mate::StringToV8(isolate, "PowerMonitor"));
|
prototype->SetClassName(mate::StringToV8(isolate, "PowerMonitor"));
|
||||||
#if defined(OS_LINUX)
|
|
||||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
|
.MakeDestroyable()
|
||||||
|
#if defined(OS_LINUX)
|
||||||
.SetMethod("blockShutdown", &PowerMonitor::BlockShutdown)
|
.SetMethod("blockShutdown", &PowerMonitor::BlockShutdown)
|
||||||
.SetMethod("unblockShutdown", &PowerMonitor::UnblockShutdown);
|
.SetMethod("unblockShutdown", &PowerMonitor::UnblockShutdown)
|
||||||
#endif
|
#endif
|
||||||
|
.SetMethod("querySystemIdleState", &PowerMonitor::QuerySystemIdleState)
|
||||||
|
.SetMethod("querySystemIdleTime", &PowerMonitor::QuerySystemIdleTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using atom::api::PowerMonitor;
|
using atom::api::PowerMonitor;
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.Set("powerMonitor", PowerMonitor::Create(isolate));
|
dict.Set("powerMonitor", PowerMonitor::Create(isolate));
|
||||||
@@ -103,4 +147,4 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_power_monitor, Initialize)
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_monitor, Initialize)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "atom/browser/lib/power_observer.h"
|
#include "atom/browser/lib/power_observer.h"
|
||||||
#include "base/compiler_specific.h"
|
#include "base/compiler_specific.h"
|
||||||
#include "native_mate/handle.h"
|
#include "native_mate/handle.h"
|
||||||
|
#include "ui/base/idle/idle.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
@@ -35,12 +36,43 @@ class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
|
|||||||
void UnblockShutdown();
|
void UnblockShutdown();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||||
|
void InitPlatformSpecificMonitors();
|
||||||
|
#endif
|
||||||
|
|
||||||
// base::PowerObserver implementations:
|
// base::PowerObserver implementations:
|
||||||
void OnPowerStateChange(bool on_battery_power) override;
|
void OnPowerStateChange(bool on_battery_power) override;
|
||||||
void OnSuspend() override;
|
void OnSuspend() override;
|
||||||
void OnResume() override;
|
void OnResume() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void QuerySystemIdleState(v8::Isolate* isolate,
|
||||||
|
int idle_threshold,
|
||||||
|
const ui::IdleCallback& callback);
|
||||||
|
void QuerySystemIdleTime(const ui::IdleTimeCallback& callback);
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
// Static callback invoked when a message comes in to our messaging window.
|
||||||
|
static LRESULT CALLBACK WndProcStatic(HWND hwnd,
|
||||||
|
UINT message,
|
||||||
|
WPARAM wparam,
|
||||||
|
LPARAM lparam);
|
||||||
|
|
||||||
|
LRESULT CALLBACK WndProc(HWND hwnd,
|
||||||
|
UINT message,
|
||||||
|
WPARAM wparam,
|
||||||
|
LPARAM lparam);
|
||||||
|
|
||||||
|
// The window class of |window_|.
|
||||||
|
ATOM atom_;
|
||||||
|
|
||||||
|
// The handle of the module that contains the window procedure of |window_|.
|
||||||
|
HMODULE instance_;
|
||||||
|
|
||||||
|
// The window used for processing events.
|
||||||
|
HWND window_;
|
||||||
|
#endif
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
|
DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
74
atom/browser/api/atom_api_power_monitor_mac.mm
Normal file
74
atom/browser/api/atom_api_power_monitor_mac.mm
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
// Copyright (c) 2013 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_power_monitor.h"
|
||||||
|
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface MacLockMonitor : NSObject {
|
||||||
|
@private
|
||||||
|
std::vector<atom::api::PowerMonitor*> emitters;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)addEmitter:(atom::api::PowerMonitor*)monitor_;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MacLockMonitor
|
||||||
|
|
||||||
|
- (id)init {
|
||||||
|
if ((self = [super init])) {
|
||||||
|
NSDistributedNotificationCenter* distCenter =
|
||||||
|
[NSDistributedNotificationCenter defaultCenter];
|
||||||
|
[distCenter addObserver:self
|
||||||
|
selector:@selector(onScreenLocked:)
|
||||||
|
name:@"com.apple.screenIsLocked"
|
||||||
|
object:nil];
|
||||||
|
[distCenter addObserver:self
|
||||||
|
selector:@selector(onScreenUnlocked:)
|
||||||
|
name:@"com.apple.screenIsUnlocked"
|
||||||
|
object:nil];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)addEmitter:(atom::api::PowerMonitor*)monitor_ {
|
||||||
|
self->emitters.push_back(monitor_);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)onScreenLocked:(NSNotification*)notification {
|
||||||
|
for (auto*& emitter : self->emitters) {
|
||||||
|
emitter->Emit("lock-screen");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)onScreenUnlocked:(NSNotification*)notification {
|
||||||
|
for (auto*& emitter : self->emitters) {
|
||||||
|
emitter->Emit("unlock-screen");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
static MacLockMonitor* g_lock_monitor = nil;
|
||||||
|
|
||||||
|
void PowerMonitor::InitPlatformSpecificMonitors() {
|
||||||
|
if (!g_lock_monitor)
|
||||||
|
g_lock_monitor = [[MacLockMonitor alloc] init];
|
||||||
|
[g_lock_monitor addEmitter:this];
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
71
atom/browser/api/atom_api_power_monitor_win.cc
Normal file
71
atom/browser/api/atom_api_power_monitor_win.cc
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
// Copyright (c) 2013 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_power_monitor.h"
|
||||||
|
|
||||||
|
#include "base/win/wrapped_window_proc.h"
|
||||||
|
#include "ui/base/win/shell.h"
|
||||||
|
#include "ui/gfx/win/hwnd_util.h"
|
||||||
|
#include "Wtsapi32.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const wchar_t kPowerMonitorWindowClass[] =
|
||||||
|
L"Electron_PowerMonitorHostWindow";
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
void PowerMonitor::InitPlatformSpecificMonitors() {
|
||||||
|
WNDCLASSEX window_class;
|
||||||
|
base::win::InitializeWindowClass(
|
||||||
|
kPowerMonitorWindowClass,
|
||||||
|
&base::win::WrappedWindowProc<PowerMonitor::WndProcStatic>, 0, 0, 0,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, &window_class);
|
||||||
|
instance_ = window_class.hInstance;
|
||||||
|
atom_ = RegisterClassEx(&window_class);
|
||||||
|
|
||||||
|
// Create an offscreen window for receiving broadcast messages for the
|
||||||
|
// session lock and unlock events.
|
||||||
|
window_ = CreateWindow(MAKEINTATOM(atom_), 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0,
|
||||||
|
instance_, 0);
|
||||||
|
gfx::CheckWindowCreated(window_);
|
||||||
|
gfx::SetWindowUserData(window_, this);
|
||||||
|
|
||||||
|
// Tel windows we want to be notified with session events
|
||||||
|
WTSRegisterSessionNotification(window_, NOTIFY_FOR_THIS_SESSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT CALLBACK PowerMonitor::WndProcStatic(HWND hwnd,
|
||||||
|
UINT message,
|
||||||
|
WPARAM wparam,
|
||||||
|
LPARAM lparam) {
|
||||||
|
PowerMonitor* msg_wnd = reinterpret_cast<PowerMonitor*>(
|
||||||
|
GetWindowLongPtr(hwnd, GWLP_USERDATA));
|
||||||
|
if (msg_wnd)
|
||||||
|
return msg_wnd->WndProc(hwnd, message, wparam, lparam);
|
||||||
|
else
|
||||||
|
return ::DefWindowProc(hwnd, message, wparam, lparam);
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT CALLBACK PowerMonitor::WndProc(HWND hwnd,
|
||||||
|
UINT message,
|
||||||
|
WPARAM wparam,
|
||||||
|
LPARAM lparam) {
|
||||||
|
if (message == WM_WTSSESSION_CHANGE) {
|
||||||
|
if (wparam == WTS_SESSION_LOCK) {
|
||||||
|
Emit("lock-screen");
|
||||||
|
} else if (wparam == WTS_SESSION_UNLOCK) {
|
||||||
|
Emit("unlock-screen");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ::DefWindowProc(hwnd, message, wparam, lparam);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
@@ -6,28 +6,26 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "base/task_scheduler/post_task.h"
|
||||||
|
#include "base/threading/thread_task_runner_handle.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
|
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
using content::BrowserThread;
|
|
||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<device::PowerSaveBlocker::PowerSaveBlockerType> {
|
struct Converter<device::mojom::WakeLockType> {
|
||||||
static bool FromV8(v8::Isolate* isolate,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
v8::Local<v8::Value> val,
|
v8::Local<v8::Value> val,
|
||||||
device::PowerSaveBlocker::PowerSaveBlockerType* out) {
|
device::mojom::WakeLockType* out) {
|
||||||
using device::PowerSaveBlocker;
|
|
||||||
std::string type;
|
std::string type;
|
||||||
if (!ConvertFromV8(isolate, val, &type))
|
if (!ConvertFromV8(isolate, val, &type))
|
||||||
return false;
|
return false;
|
||||||
if (type == "prevent-app-suspension")
|
if (type == "prevent-app-suspension")
|
||||||
*out = PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
|
*out = device::mojom::WakeLockType::kPreventAppSuspension;
|
||||||
else if (type == "prevent-display-sleep")
|
else if (type == "prevent-display-sleep")
|
||||||
*out = PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
|
*out = device::mojom::WakeLockType::kPreventDisplaySleep;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@@ -42,12 +40,11 @@ namespace api {
|
|||||||
|
|
||||||
PowerSaveBlocker::PowerSaveBlocker(v8::Isolate* isolate)
|
PowerSaveBlocker::PowerSaveBlocker(v8::Isolate* isolate)
|
||||||
: current_blocker_type_(
|
: current_blocker_type_(
|
||||||
device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
|
device::mojom::WakeLockType::kPreventAppSuspension) {
|
||||||
Init(isolate);
|
Init(isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
PowerSaveBlocker::~PowerSaveBlocker() {
|
PowerSaveBlocker::~PowerSaveBlocker() {}
|
||||||
}
|
|
||||||
|
|
||||||
void PowerSaveBlocker::UpdatePowerSaveBlocker() {
|
void PowerSaveBlocker::UpdatePowerSaveBlocker() {
|
||||||
if (power_save_blocker_types_.empty()) {
|
if (power_save_blocker_types_.empty()) {
|
||||||
@@ -55,38 +52,39 @@ void PowerSaveBlocker::UpdatePowerSaveBlocker() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// |kPowerSaveBlockPreventAppSuspension| keeps system active, but allows
|
// |WakeLockType::kPreventAppSuspension| keeps system active, but allows
|
||||||
// screen to be turned off.
|
// screen to be turned off.
|
||||||
// |kPowerSaveBlockPreventDisplaySleep| keeps system and screen active, has a
|
// |WakeLockType::kPreventDisplaySleep| keeps system and screen active, has a
|
||||||
// higher precedence level than |kPowerSaveBlockPreventAppSuspension|.
|
// higher precedence level than |WakeLockType::kPreventAppSuspension|.
|
||||||
//
|
//
|
||||||
// Only the highest-precedence blocker type takes effect.
|
// Only the highest-precedence blocker type takes effect.
|
||||||
device::PowerSaveBlocker::PowerSaveBlockerType new_blocker_type =
|
device::mojom::WakeLockType new_blocker_type =
|
||||||
device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
|
device::mojom::WakeLockType::kPreventAppSuspension;
|
||||||
for (const auto& element : power_save_blocker_types_) {
|
for (const auto& element : power_save_blocker_types_) {
|
||||||
if (element.second ==
|
if (element.second ==
|
||||||
device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep) {
|
device::mojom::WakeLockType::kPreventDisplaySleep) {
|
||||||
new_blocker_type =
|
new_blocker_type =
|
||||||
device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
|
device::mojom::WakeLockType::kPreventDisplaySleep;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!power_save_blocker_ || new_blocker_type != current_blocker_type_) {
|
if (!power_save_blocker_ || new_blocker_type != current_blocker_type_) {
|
||||||
std::unique_ptr<device::PowerSaveBlocker> new_blocker(
|
auto new_blocker = std::make_unique<device::PowerSaveBlocker>(
|
||||||
new device::PowerSaveBlocker(
|
new_blocker_type, device::mojom::WakeLockReason::kOther,
|
||||||
new_blocker_type,
|
ATOM_PRODUCT_NAME, base::ThreadTaskRunnerHandle::Get(),
|
||||||
device::PowerSaveBlocker::kReasonOther,
|
// This task runner may be used by some device service
|
||||||
ATOM_PRODUCT_NAME,
|
// implementation bits to interface with dbus client code, which in
|
||||||
BrowserThread::GetTaskRunnerForThread(BrowserThread::UI),
|
// turn imposes some subtle thread affinity on the clients. We
|
||||||
BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE)));
|
// therefore require a single-thread runner.
|
||||||
|
base::CreateSingleThreadTaskRunnerWithTraits(
|
||||||
|
{base::MayBlock(), base::TaskPriority::BACKGROUND}));
|
||||||
power_save_blocker_.swap(new_blocker);
|
power_save_blocker_.swap(new_blocker);
|
||||||
current_blocker_type_ = new_blocker_type;
|
current_blocker_type_ = new_blocker_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int PowerSaveBlocker::Start(
|
int PowerSaveBlocker::Start(device::mojom::WakeLockType type) {
|
||||||
device::PowerSaveBlocker::PowerSaveBlockerType type) {
|
|
||||||
static int count = 0;
|
static int count = 0;
|
||||||
power_save_blocker_types_[count] = type;
|
power_save_blocker_types_[count] = type;
|
||||||
UpdatePowerSaveBlocker();
|
UpdatePowerSaveBlocker();
|
||||||
@@ -110,7 +108,8 @@ mate::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
void PowerSaveBlocker::BuildPrototype(
|
void PowerSaveBlocker::BuildPrototype(
|
||||||
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
|
v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
prototype->SetClassName(mate::StringToV8(isolate, "PowerSaveBlocker"));
|
prototype->SetClassName(mate::StringToV8(isolate, "PowerSaveBlocker"));
|
||||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
.SetMethod("start", &PowerSaveBlocker::Start)
|
.SetMethod("start", &PowerSaveBlocker::Start)
|
||||||
@@ -124,8 +123,10 @@ void PowerSaveBlocker::BuildPrototype(
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.Set("powerSaveBlocker", atom::api::PowerSaveBlocker::Create(isolate));
|
dict.Set("powerSaveBlocker", atom::api::PowerSaveBlocker::Create(isolate));
|
||||||
@@ -133,4 +134,4 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_power_save_blocker, Initialize);
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_save_blocker, Initialize);
|
||||||
|
|||||||
@@ -33,19 +33,18 @@ class PowerSaveBlocker : public mate::TrackableObject<PowerSaveBlocker> {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void UpdatePowerSaveBlocker();
|
void UpdatePowerSaveBlocker();
|
||||||
int Start(device::PowerSaveBlocker::PowerSaveBlockerType type);
|
int Start(device::mojom::WakeLockType type);
|
||||||
bool Stop(int id);
|
bool Stop(int id);
|
||||||
bool IsStarted(int id);
|
bool IsStarted(int id);
|
||||||
|
|
||||||
std::unique_ptr<device::PowerSaveBlocker> power_save_blocker_;
|
std::unique_ptr<device::PowerSaveBlocker> power_save_blocker_;
|
||||||
|
|
||||||
// Currnet blocker type used by |power_save_blocker_|
|
// Current blocker type used by |power_save_blocker_|
|
||||||
device::PowerSaveBlocker::PowerSaveBlockerType current_blocker_type_;
|
device::mojom::WakeLockType current_blocker_type_;
|
||||||
|
|
||||||
// Map from id to the corresponding blocker type for each request.
|
// Map from id to the corresponding blocker type for each request.
|
||||||
using PowerSaveBlockerTypeMap =
|
using WakeLockTypeMap = std::map<int, device::mojom::WakeLockType>;
|
||||||
std::map<int, device::PowerSaveBlocker::PowerSaveBlockerType>;
|
WakeLockTypeMap power_save_blocker_types_;
|
||||||
PowerSaveBlockerTypeMap power_save_blocker_types_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
|
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,14 +33,6 @@ namespace {
|
|||||||
// List of registered custom standard schemes.
|
// List of registered custom standard schemes.
|
||||||
std::vector<std::string> g_standard_schemes;
|
std::vector<std::string> g_standard_schemes;
|
||||||
|
|
||||||
// Clear protocol handlers in IO thread.
|
|
||||||
void ClearJobFactoryInIO(
|
|
||||||
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter) {
|
|
||||||
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
|
|
||||||
request_context_getter->job_factory());
|
|
||||||
job_factory->Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::vector<std::string> GetStandardSchemes() {
|
std::vector<std::string> GetStandardSchemes() {
|
||||||
@@ -71,44 +63,39 @@ void RegisterStandardSchemes(const std::vector<std::string>& schemes,
|
|||||||
atom::switches::kStandardSchemes, base::JoinString(schemes, ","));
|
atom::switches::kStandardSchemes, base::JoinString(schemes, ","));
|
||||||
if (secure) {
|
if (secure) {
|
||||||
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
|
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
|
||||||
atom::switches::kSecureSchemes, base::JoinString(schemes, ","));
|
atom::switches::kSecureSchemes, base::JoinString(schemes, ","));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||||
: request_context_getter_(browser_context->GetRequestContext()),
|
: browser_context_(browser_context), weak_factory_(this) {
|
||||||
weak_factory_(this) {
|
|
||||||
Init(isolate);
|
Init(isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
Protocol::~Protocol() {
|
Protocol::~Protocol() {}
|
||||||
content::BrowserThread::PostTask(
|
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
|
||||||
base::Bind(ClearJobFactoryInIO, request_context_getter_));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Protocol::RegisterServiceWorkerSchemes(
|
void Protocol::RegisterServiceWorkerSchemes(
|
||||||
const std::vector<std::string>& schemes) {
|
const std::vector<std::string>& schemes) {
|
||||||
atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes);
|
atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Protocol::UnregisterProtocol(
|
void Protocol::UnregisterProtocol(const std::string& scheme,
|
||||||
const std::string& scheme, mate::Arguments* args) {
|
mate::Arguments* args) {
|
||||||
CompletionCallback callback;
|
CompletionCallback callback;
|
||||||
args->GetNext(&callback);
|
args->GetNext(&callback);
|
||||||
|
auto* getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(&Protocol::UnregisterProtocolInIO,
|
base::BindOnce(&Protocol::UnregisterProtocolInIO,
|
||||||
request_context_getter_, scheme),
|
base::RetainedRef(getter), scheme),
|
||||||
base::Bind(&Protocol::OnIOCompleted,
|
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||||
GetWeakPtr(), callback));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
|
Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
|
||||||
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
|
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
|
||||||
const std::string& scheme) {
|
const std::string& scheme) {
|
||||||
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
|
auto* job_factory = static_cast<AtomURLRequestJobFactory*>(
|
||||||
request_context_getter->job_factory());
|
request_context_getter->job_factory());
|
||||||
if (!job_factory->HasProtocolHandler(scheme))
|
if (!job_factory->HasProtocolHandler(scheme))
|
||||||
return PROTOCOL_NOT_REGISTERED;
|
return PROTOCOL_NOT_REGISTERED;
|
||||||
@@ -118,10 +105,11 @@ Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
|
|||||||
|
|
||||||
void Protocol::IsProtocolHandled(const std::string& scheme,
|
void Protocol::IsProtocolHandled(const std::string& scheme,
|
||||||
const BooleanCallback& callback) {
|
const BooleanCallback& callback) {
|
||||||
|
auto* getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(&Protocol::IsProtocolHandledInIO,
|
base::Bind(&Protocol::IsProtocolHandledInIO, base::RetainedRef(getter),
|
||||||
request_context_getter_, scheme),
|
scheme),
|
||||||
callback);
|
callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,16 +120,16 @@ bool Protocol::IsProtocolHandledInIO(
|
|||||||
return request_context_getter->job_factory()->IsHandledProtocol(scheme);
|
return request_context_getter->job_factory()->IsHandledProtocol(scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Protocol::UninterceptProtocol(
|
void Protocol::UninterceptProtocol(const std::string& scheme,
|
||||||
const std::string& scheme, mate::Arguments* args) {
|
mate::Arguments* args) {
|
||||||
CompletionCallback callback;
|
CompletionCallback callback;
|
||||||
args->GetNext(&callback);
|
args->GetNext(&callback);
|
||||||
|
auto* getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(&Protocol::UninterceptProtocolInIO,
|
base::BindOnce(&Protocol::UninterceptProtocolInIO,
|
||||||
request_context_getter_, scheme),
|
base::RetainedRef(getter), scheme),
|
||||||
base::Bind(&Protocol::OnIOCompleted,
|
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||||
GetWeakPtr(), callback));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
@@ -149,12 +137,14 @@ Protocol::ProtocolError Protocol::UninterceptProtocolInIO(
|
|||||||
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
|
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
|
||||||
const std::string& scheme) {
|
const std::string& scheme) {
|
||||||
return static_cast<AtomURLRequestJobFactory*>(
|
return static_cast<AtomURLRequestJobFactory*>(
|
||||||
request_context_getter->job_factory())->UninterceptProtocol(scheme) ?
|
request_context_getter->job_factory())
|
||||||
PROTOCOL_OK : PROTOCOL_NOT_INTERCEPTED;
|
->UninterceptProtocol(scheme)
|
||||||
|
? PROTOCOL_OK
|
||||||
|
: PROTOCOL_NOT_INTERCEPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Protocol::OnIOCompleted(
|
void Protocol::OnIOCompleted(const CompletionCallback& callback,
|
||||||
const CompletionCallback& callback, ProtocolError error) {
|
ProtocolError error) {
|
||||||
// The completion callback is optional.
|
// The completion callback is optional.
|
||||||
if (callback.is_null())
|
if (callback.is_null())
|
||||||
return;
|
return;
|
||||||
@@ -172,31 +162,30 @@ void Protocol::OnIOCompleted(
|
|||||||
|
|
||||||
std::string Protocol::ErrorCodeToString(ProtocolError error) {
|
std::string Protocol::ErrorCodeToString(ProtocolError error) {
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case PROTOCOL_FAIL: return "Failed to manipulate protocol factory";
|
case PROTOCOL_FAIL:
|
||||||
case PROTOCOL_REGISTERED: return "The scheme has been registered";
|
return "Failed to manipulate protocol factory";
|
||||||
case PROTOCOL_NOT_REGISTERED: return "The scheme has not been registered";
|
case PROTOCOL_REGISTERED:
|
||||||
case PROTOCOL_INTERCEPTED: return "The scheme has been intercepted";
|
return "The scheme has been registered";
|
||||||
case PROTOCOL_NOT_INTERCEPTED: return "The scheme has not been intercepted";
|
case PROTOCOL_NOT_REGISTERED:
|
||||||
default: return "Unexpected error";
|
return "The scheme has not been registered";
|
||||||
|
case PROTOCOL_INTERCEPTED:
|
||||||
|
return "The scheme has been intercepted";
|
||||||
|
case PROTOCOL_NOT_INTERCEPTED:
|
||||||
|
return "The scheme has not been intercepted";
|
||||||
|
default:
|
||||||
|
return "Unexpected error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AtomURLRequestJobFactory* Protocol::GetJobFactoryInIO() const {
|
|
||||||
request_context_getter_->GetURLRequestContext(); // Force init.
|
|
||||||
return static_cast<AtomURLRequestJobFactory*>(
|
|
||||||
static_cast<brightray::URLRequestContextGetter*>(
|
|
||||||
request_context_getter_.get())->job_factory());
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
mate::Handle<Protocol> Protocol::Create(
|
mate::Handle<Protocol> Protocol::Create(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate, AtomBrowserContext* browser_context) {
|
AtomBrowserContext* browser_context) {
|
||||||
return mate::CreateHandle(isolate, new Protocol(isolate, browser_context));
|
return mate::CreateHandle(isolate, new Protocol(isolate, browser_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Protocol::BuildPrototype(
|
void Protocol::BuildPrototype(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
prototype->SetClassName(mate::StringToV8(isolate, "Protocol"));
|
prototype->SetClassName(mate::StringToV8(isolate, "Protocol"));
|
||||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
.SetMethod("registerServiceWorkerSchemes",
|
.SetMethod("registerServiceWorkerSchemes",
|
||||||
@@ -232,19 +221,22 @@ void Protocol::BuildPrototype(
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void RegisterStandardSchemes(
|
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
|
||||||
const std::vector<std::string>& schemes, mate::Arguments* args) {
|
mate::Arguments* args) {
|
||||||
if (atom::Browser::Get()->is_ready()) {
|
if (atom::Browser::Get()->is_ready()) {
|
||||||
args->ThrowError("protocol.registerStandardSchemes should be called before "
|
args->ThrowError(
|
||||||
"app is ready");
|
"protocol.registerStandardSchemes should be called before "
|
||||||
|
"app is ready");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
atom::api::RegisterStandardSchemes(schemes, args);
|
atom::api::RegisterStandardSchemes(schemes, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.SetMethod("registerStandardSchemes", &RegisterStandardSchemes);
|
dict.SetMethod("registerStandardSchemes", &RegisterStandardSchemes);
|
||||||
@@ -253,4 +245,4 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_protocol, Initialize)
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_protocol, Initialize)
|
||||||
|
|||||||
@@ -39,20 +39,20 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
|||||||
using CompletionCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
using CompletionCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||||
using BooleanCallback = base::Callback<void(bool)>;
|
using BooleanCallback = base::Callback<void(bool)>;
|
||||||
|
|
||||||
static mate::Handle<Protocol> Create(
|
static mate::Handle<Protocol> Create(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
AtomBrowserContext* browser_context);
|
||||||
|
|
||||||
static void BuildPrototype(v8::Isolate* isolate,
|
static void BuildPrototype(v8::Isolate* isolate,
|
||||||
v8::Local<v8::FunctionTemplate> prototype);
|
v8::Local<v8::FunctionTemplate> prototype);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||||
~Protocol();
|
~Protocol() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Possible errors.
|
// Possible errors.
|
||||||
enum ProtocolError {
|
enum ProtocolError {
|
||||||
PROTOCOL_OK, // no error
|
PROTOCOL_OK, // no error
|
||||||
PROTOCOL_FAIL, // operation failed, should never occur
|
PROTOCOL_FAIL, // operation failed, should never occur
|
||||||
PROTOCOL_REGISTERED,
|
PROTOCOL_REGISTERED,
|
||||||
PROTOCOL_NOT_REGISTERED,
|
PROTOCOL_NOT_REGISTERED,
|
||||||
@@ -62,14 +62,13 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
|||||||
|
|
||||||
// The protocol handler that will create a protocol handler for certain
|
// The protocol handler that will create a protocol handler for certain
|
||||||
// request job.
|
// request job.
|
||||||
template<typename RequestJob>
|
template <typename RequestJob>
|
||||||
class CustomProtocolHandler
|
class CustomProtocolHandler
|
||||||
: public net::URLRequestJobFactory::ProtocolHandler {
|
: public net::URLRequestJobFactory::ProtocolHandler {
|
||||||
public:
|
public:
|
||||||
CustomProtocolHandler(
|
CustomProtocolHandler(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate,
|
net::URLRequestContextGetter* request_context,
|
||||||
net::URLRequestContextGetter* request_context,
|
const Handler& handler)
|
||||||
const Handler& handler)
|
|
||||||
: isolate_(isolate),
|
: isolate_(isolate),
|
||||||
request_context_(request_context),
|
request_context_(request_context),
|
||||||
handler_(handler) {}
|
handler_(handler) {}
|
||||||
@@ -79,13 +78,13 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
|||||||
net::URLRequest* request,
|
net::URLRequest* request,
|
||||||
net::NetworkDelegate* network_delegate) const override {
|
net::NetworkDelegate* network_delegate) const override {
|
||||||
RequestJob* request_job = new RequestJob(request, network_delegate);
|
RequestJob* request_job = new RequestJob(request, network_delegate);
|
||||||
request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_);
|
request_job->SetHandlerInfo(isolate_, request_context_, handler_);
|
||||||
return request_job;
|
return request_job;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
v8::Isolate* isolate_;
|
v8::Isolate* isolate_;
|
||||||
scoped_refptr<net::URLRequestContextGetter> request_context_;
|
net::URLRequestContextGetter* request_context_;
|
||||||
Protocol::Handler handler_;
|
Protocol::Handler handler_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
|
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
|
||||||
@@ -95,32 +94,31 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
|||||||
void RegisterServiceWorkerSchemes(const std::vector<std::string>& schemes);
|
void RegisterServiceWorkerSchemes(const std::vector<std::string>& schemes);
|
||||||
|
|
||||||
// Register the protocol with certain request job.
|
// Register the protocol with certain request job.
|
||||||
template<typename RequestJob>
|
template <typename RequestJob>
|
||||||
void RegisterProtocol(const std::string& scheme,
|
void RegisterProtocol(const std::string& scheme,
|
||||||
const Handler& handler,
|
const Handler& handler,
|
||||||
mate::Arguments* args) {
|
mate::Arguments* args) {
|
||||||
CompletionCallback callback;
|
CompletionCallback callback;
|
||||||
args->GetNext(&callback);
|
args->GetNext(&callback);
|
||||||
|
auto* getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(&Protocol::RegisterProtocolInIO<RequestJob>,
|
base::BindOnce(&Protocol::RegisterProtocolInIO<RequestJob>,
|
||||||
request_context_getter_, isolate(), scheme, handler),
|
base::RetainedRef(getter), isolate(), scheme, handler),
|
||||||
base::Bind(&Protocol::OnIOCompleted,
|
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||||
GetWeakPtr(), callback));
|
|
||||||
}
|
}
|
||||||
template<typename RequestJob>
|
template <typename RequestJob>
|
||||||
static ProtocolError RegisterProtocolInIO(
|
static ProtocolError RegisterProtocolInIO(
|
||||||
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
|
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
|
||||||
v8::Isolate* isolate,
|
v8::Isolate* isolate,
|
||||||
const std::string& scheme,
|
const std::string& scheme,
|
||||||
const Handler& handler) {
|
const Handler& handler) {
|
||||||
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
|
auto* job_factory = static_cast<AtomURLRequestJobFactory*>(
|
||||||
request_context_getter->job_factory());
|
request_context_getter->job_factory());
|
||||||
if (job_factory->IsHandledProtocol(scheme))
|
if (job_factory->IsHandledProtocol(scheme))
|
||||||
return PROTOCOL_REGISTERED;
|
return PROTOCOL_REGISTERED;
|
||||||
std::unique_ptr<CustomProtocolHandler<RequestJob>> protocol_handler(
|
auto protocol_handler = std::make_unique<CustomProtocolHandler<RequestJob>>(
|
||||||
new CustomProtocolHandler<RequestJob>(
|
isolate, request_context_getter.get(), handler);
|
||||||
isolate, request_context_getter.get(), handler));
|
|
||||||
if (job_factory->SetProtocolHandler(scheme, std::move(protocol_handler)))
|
if (job_factory->SetProtocolHandler(scheme, std::move(protocol_handler)))
|
||||||
return PROTOCOL_OK;
|
return PROTOCOL_OK;
|
||||||
else
|
else
|
||||||
@@ -141,35 +139,34 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
|||||||
const std::string& scheme);
|
const std::string& scheme);
|
||||||
|
|
||||||
// Replace the protocol handler with a new one.
|
// Replace the protocol handler with a new one.
|
||||||
template<typename RequestJob>
|
template <typename RequestJob>
|
||||||
void InterceptProtocol(const std::string& scheme,
|
void InterceptProtocol(const std::string& scheme,
|
||||||
const Handler& handler,
|
const Handler& handler,
|
||||||
mate::Arguments* args) {
|
mate::Arguments* args) {
|
||||||
CompletionCallback callback;
|
CompletionCallback callback;
|
||||||
args->GetNext(&callback);
|
args->GetNext(&callback);
|
||||||
|
auto* getter = browser_context_->GetRequestContext();
|
||||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(&Protocol::InterceptProtocolInIO<RequestJob>,
|
base::BindOnce(&Protocol::InterceptProtocolInIO<RequestJob>,
|
||||||
request_context_getter_, isolate(), scheme, handler),
|
base::RetainedRef(getter), isolate(), scheme, handler),
|
||||||
base::Bind(&Protocol::OnIOCompleted,
|
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||||
GetWeakPtr(), callback));
|
|
||||||
}
|
}
|
||||||
template<typename RequestJob>
|
template <typename RequestJob>
|
||||||
static ProtocolError InterceptProtocolInIO(
|
static ProtocolError InterceptProtocolInIO(
|
||||||
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
|
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
|
||||||
v8::Isolate* isolate,
|
v8::Isolate* isolate,
|
||||||
const std::string& scheme,
|
const std::string& scheme,
|
||||||
const Handler& handler) {
|
const Handler& handler) {
|
||||||
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
|
auto* job_factory = static_cast<AtomURLRequestJobFactory*>(
|
||||||
request_context_getter->job_factory());
|
request_context_getter->job_factory());
|
||||||
if (!job_factory->IsHandledProtocol(scheme))
|
if (!job_factory->IsHandledProtocol(scheme))
|
||||||
return PROTOCOL_NOT_REGISTERED;
|
return PROTOCOL_NOT_REGISTERED;
|
||||||
// It is possible a protocol is handled but can not be intercepted.
|
// It is possible a protocol is handled but can not be intercepted.
|
||||||
if (!job_factory->HasProtocolHandler(scheme))
|
if (!job_factory->HasProtocolHandler(scheme))
|
||||||
return PROTOCOL_FAIL;
|
return PROTOCOL_FAIL;
|
||||||
std::unique_ptr<CustomProtocolHandler<RequestJob>> protocol_handler(
|
auto protocol_handler = std::make_unique<CustomProtocolHandler<RequestJob>>(
|
||||||
new CustomProtocolHandler<RequestJob>(
|
isolate, request_context_getter.get(), handler);
|
||||||
isolate, request_context_getter.get(), handler));
|
|
||||||
if (!job_factory->InterceptProtocol(scheme, std::move(protocol_handler)))
|
if (!job_factory->InterceptProtocol(scheme, std::move(protocol_handler)))
|
||||||
return PROTOCOL_INTERCEPTED;
|
return PROTOCOL_INTERCEPTED;
|
||||||
return PROTOCOL_OK;
|
return PROTOCOL_OK;
|
||||||
@@ -187,13 +184,9 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
|||||||
// Convert error code to string.
|
// Convert error code to string.
|
||||||
std::string ErrorCodeToString(ProtocolError error);
|
std::string ErrorCodeToString(ProtocolError error);
|
||||||
|
|
||||||
AtomURLRequestJobFactory* GetJobFactoryInIO() const;
|
base::WeakPtr<Protocol> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
|
||||||
|
|
||||||
base::WeakPtr<Protocol> GetWeakPtr() {
|
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||||
return weak_factory_.GetWeakPtr();
|
|
||||||
}
|
|
||||||
|
|
||||||
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter_;
|
|
||||||
base::WeakPtrFactory<Protocol> weak_factory_;
|
base::WeakPtrFactory<Protocol> weak_factory_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Protocol);
|
DISALLOW_COPY_AND_ASSIGN(Protocol);
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ namespace {
|
|||||||
|
|
||||||
bool IsWebContents(v8::Isolate* isolate, content::RenderProcessHost* process) {
|
bool IsWebContents(v8::Isolate* isolate, content::RenderProcessHost* process) {
|
||||||
content::WebContents* web_contents =
|
content::WebContents* web_contents =
|
||||||
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())->
|
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())
|
||||||
GetWebContentsFromProcessID(process->GetID());
|
->GetWebContentsFromProcessID(process->GetID());
|
||||||
if (!web_contents)
|
if (!web_contents)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -41,8 +41,7 @@ RenderProcessPreferences::RenderProcessPreferences(
|
|||||||
Init(isolate);
|
Init(isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderProcessPreferences::~RenderProcessPreferences() {
|
RenderProcessPreferences::~RenderProcessPreferences() {}
|
||||||
}
|
|
||||||
|
|
||||||
int RenderProcessPreferences::AddEntry(const base::DictionaryValue& entry) {
|
int RenderProcessPreferences::AddEntry(const base::DictionaryValue& entry) {
|
||||||
return preferences_.AddEntry(entry);
|
return preferences_.AddEntry(entry);
|
||||||
@@ -54,7 +53,8 @@ void RenderProcessPreferences::RemoveEntry(int id) {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
void RenderProcessPreferences::BuildPrototype(
|
void RenderProcessPreferences::BuildPrototype(
|
||||||
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
|
v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
prototype->SetClassName(
|
prototype->SetClassName(
|
||||||
mate::StringToV8(isolate, "RenderProcessPreferences"));
|
mate::StringToV8(isolate, "RenderProcessPreferences"));
|
||||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
@@ -65,10 +65,9 @@ void RenderProcessPreferences::BuildPrototype(
|
|||||||
// static
|
// static
|
||||||
mate::Handle<RenderProcessPreferences>
|
mate::Handle<RenderProcessPreferences>
|
||||||
RenderProcessPreferences::ForAllWebContents(v8::Isolate* isolate) {
|
RenderProcessPreferences::ForAllWebContents(v8::Isolate* isolate) {
|
||||||
return mate::CreateHandle(
|
return mate::CreateHandle(isolate,
|
||||||
isolate,
|
new RenderProcessPreferences(
|
||||||
new RenderProcessPreferences(isolate,
|
isolate, base::Bind(&IsWebContents, isolate)));
|
||||||
base::Bind(&IsWebContents, isolate)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
@@ -77,8 +76,10 @@ RenderProcessPreferences::ForAllWebContents(v8::Isolate* isolate) {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||||
dict.SetMethod("forAllWebContents",
|
dict.SetMethod("forAllWebContents",
|
||||||
&atom::api::RenderProcessPreferences::ForAllWebContents);
|
&atom::api::RenderProcessPreferences::ForAllWebContents);
|
||||||
@@ -86,5 +87,5 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_render_process_preferences,
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_render_process_preferences,
|
||||||
Initialize)
|
Initialize)
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ namespace api {
|
|||||||
class RenderProcessPreferences
|
class RenderProcessPreferences
|
||||||
: public mate::Wrappable<RenderProcessPreferences> {
|
: public mate::Wrappable<RenderProcessPreferences> {
|
||||||
public:
|
public:
|
||||||
static mate::Handle<RenderProcessPreferences>
|
static mate::Handle<RenderProcessPreferences> ForAllWebContents(
|
||||||
ForAllWebContents(v8::Isolate* isolate);
|
v8::Isolate* isolate);
|
||||||
|
|
||||||
static void BuildPrototype(v8::Isolate* isolate,
|
static void BuildPrototype(v8::Isolate* isolate,
|
||||||
v8::Local<v8::FunctionTemplate> prototype);
|
v8::Local<v8::FunctionTemplate> prototype);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "atom/browser/api/atom_api_browser_window.h"
|
||||||
#include "atom/browser/browser.h"
|
#include "atom/browser/browser.h"
|
||||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
@@ -16,6 +17,10 @@
|
|||||||
#include "ui/display/screen.h"
|
#include "ui/display/screen.h"
|
||||||
#include "ui/gfx/geometry/point.h"
|
#include "ui/gfx/geometry/point.h"
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
#include "ui/display/win/screen_win.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
@@ -25,9 +30,9 @@ namespace api {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Find an item in container according to its ID.
|
// Find an item in container according to its ID.
|
||||||
template<class T>
|
template <class T>
|
||||||
typename T::iterator FindById(T* container, int id) {
|
typename T::iterator FindById(T* container, int id) {
|
||||||
auto predicate = [id] (const typename T::value_type& item) -> bool {
|
auto predicate = [id](const typename T::value_type& item) -> bool {
|
||||||
return item.id() == id;
|
return item.id() == id;
|
||||||
};
|
};
|
||||||
return std::find_if(container->begin(), container->end(), predicate);
|
return std::find_if(container->begin(), container->end(), predicate);
|
||||||
@@ -79,6 +84,22 @@ display::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) {
|
|||||||
return screen_->GetDisplayMatching(match_rect);
|
return screen_->GetDisplayMatching(match_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
|
||||||
|
static gfx::Rect ScreenToDIPRect(atom::NativeWindow* window,
|
||||||
|
const gfx::Rect& rect) {
|
||||||
|
HWND hwnd = window ? window->GetAcceleratedWidget() : nullptr;
|
||||||
|
return display::win::ScreenWin::ScreenToDIPRect(hwnd, rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gfx::Rect DIPToScreenRect(atom::NativeWindow* window,
|
||||||
|
const gfx::Rect& rect) {
|
||||||
|
HWND hwnd = window ? window->GetAcceleratedWidget() : nullptr;
|
||||||
|
return display::win::ScreenWin::DIPToScreenRect(hwnd, rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void Screen::OnDisplayAdded(const display::Display& new_display) {
|
void Screen::OnDisplayAdded(const display::Display& new_display) {
|
||||||
Emit("display-added", new_display);
|
Emit("display-added", new_display);
|
||||||
}
|
}
|
||||||
@@ -96,15 +117,14 @@ void Screen::OnDisplayMetricsChanged(const display::Display& display,
|
|||||||
v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
|
v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
|
||||||
if (!Browser::Get()->is_ready()) {
|
if (!Browser::Get()->is_ready()) {
|
||||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||||
isolate,
|
isolate, "Cannot require \"screen\" module before app is ready")));
|
||||||
"Cannot require \"screen\" module before app is ready")));
|
|
||||||
return v8::Null(isolate);
|
return v8::Null(isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
display::Screen* screen = display::Screen::GetScreen();
|
display::Screen* screen = display::Screen::GetScreen();
|
||||||
if (!screen) {
|
if (!screen) {
|
||||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
isolate->ThrowException(v8::Exception::Error(
|
||||||
isolate, "Failed to get screen information")));
|
mate::StringToV8(isolate, "Failed to get screen information")));
|
||||||
return v8::Null(isolate);
|
return v8::Null(isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,16 +132,19 @@ v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Screen::BuildPrototype(
|
void Screen::BuildPrototype(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
prototype->SetClassName(mate::StringToV8(isolate, "Screen"));
|
prototype->SetClassName(mate::StringToV8(isolate, "Screen"));
|
||||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
.SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint)
|
.SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint)
|
||||||
.SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
|
.SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
|
||||||
.SetMethod("getAllDisplays", &Screen::GetAllDisplays)
|
.SetMethod("getAllDisplays", &Screen::GetAllDisplays)
|
||||||
.SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint)
|
.SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint)
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_WIN)
|
||||||
.SetMethod("getMenuBarHeight", &Screen::getMenuBarHeight)
|
.SetMethod("screenToDipPoint", &display::win::ScreenWin::ScreenToDIPPoint)
|
||||||
|
.SetMethod("dipToScreenPoint", &display::win::ScreenWin::DIPToScreenPoint)
|
||||||
|
.SetMethod("screenToDipRect", &ScreenToDIPRect)
|
||||||
|
.SetMethod("dipToScreenRect", &DIPToScreenRect)
|
||||||
#endif
|
#endif
|
||||||
.SetMethod("getDisplayMatching", &Screen::GetDisplayMatching);
|
.SetMethod("getDisplayMatching", &Screen::GetDisplayMatching);
|
||||||
}
|
}
|
||||||
@@ -134,8 +157,10 @@ namespace {
|
|||||||
|
|
||||||
using atom::api::Screen;
|
using atom::api::Screen;
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.Set("screen", Screen::Create(isolate));
|
dict.Set("screen", Screen::Create(isolate));
|
||||||
@@ -144,4 +169,4 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_screen, Initialize)
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_screen, Initialize)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace gfx {
|
|||||||
class Point;
|
class Point;
|
||||||
class Rect;
|
class Rect;
|
||||||
class Screen;
|
class Screen;
|
||||||
}
|
} // namespace gfx
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
@@ -40,10 +40,6 @@ class Screen : public mate::EventEmitter<Screen>,
|
|||||||
display::Display GetDisplayNearestPoint(const gfx::Point& point);
|
display::Display GetDisplayNearestPoint(const gfx::Point& point);
|
||||||
display::Display GetDisplayMatching(const gfx::Rect& match_rect);
|
display::Display GetDisplayMatching(const gfx::Rect& match_rect);
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
int getMenuBarHeight();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// display::DisplayObserver:
|
// display::DisplayObserver:
|
||||||
void OnDisplayAdded(const display::Display& new_display) override;
|
void OnDisplayAdded(const display::Display& new_display) override;
|
||||||
void OnDisplayRemoved(const display::Display& old_display) override;
|
void OnDisplayRemoved(const display::Display& old_display) override;
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
// Copyright (c) 2017 GitHub, Inc.
|
|
||||||
// Use of this source code is governed by the MIT license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#import "atom/browser/api/atom_api_screen.h"
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
|
|
||||||
namespace atom {
|
|
||||||
|
|
||||||
namespace api {
|
|
||||||
|
|
||||||
int Screen::getMenuBarHeight() {
|
|
||||||
return [[NSApp mainMenu] menuBarHeight];
|
|
||||||
}
|
|
||||||
|
|
||||||
}// namespace api
|
|
||||||
|
|
||||||
}// namespace atom
|
|
||||||
@@ -31,12 +31,12 @@
|
|||||||
#include "base/strings/string_util.h"
|
#include "base/strings/string_util.h"
|
||||||
#include "base/threading/thread_task_runner_handle.h"
|
#include "base/threading/thread_task_runner_handle.h"
|
||||||
#include "brightray/browser/media/media_device_id_salt.h"
|
#include "brightray/browser/media/media_device_id_salt.h"
|
||||||
#include "brightray/browser/net/devtools_network_conditions.h"
|
|
||||||
#include "brightray/browser/net/devtools_network_controller_handle.h"
|
|
||||||
#include "chrome/browser/browser_process.h"
|
#include "chrome/browser/browser_process.h"
|
||||||
#include "chrome/common/pref_names.h"
|
#include "chrome/common/pref_names.h"
|
||||||
|
#include "components/download/public/common/download_danger_type.h"
|
||||||
#include "components/prefs/pref_service.h"
|
#include "components/prefs/pref_service.h"
|
||||||
#include "content/public/browser/browser_thread.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/download_manager_delegate.h"
|
||||||
#include "content/public/browser/storage_partition.h"
|
#include "content/public/browser/storage_partition.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
@@ -46,11 +46,13 @@
|
|||||||
#include "net/dns/host_cache.h"
|
#include "net/dns/host_cache.h"
|
||||||
#include "net/http/http_auth_handler_factory.h"
|
#include "net/http/http_auth_handler_factory.h"
|
||||||
#include "net/http/http_auth_preferences.h"
|
#include "net/http/http_auth_preferences.h"
|
||||||
#include "net/proxy/proxy_config_service_fixed.h"
|
#include "net/proxy_resolution/proxy_config_service_fixed.h"
|
||||||
#include "net/proxy/proxy_service.h"
|
#include "net/proxy_resolution/proxy_service.h"
|
||||||
#include "net/url_request/static_http_user_agent_settings.h"
|
#include "net/url_request/static_http_user_agent_settings.h"
|
||||||
#include "net/url_request/url_request_context.h"
|
#include "net/url_request/url_request_context.h"
|
||||||
#include "net/url_request/url_request_context_getter.h"
|
#include "net/url_request/url_request_context_getter.h"
|
||||||
|
#include "services/network/throttling/network_conditions.h"
|
||||||
|
#include "services/network/throttling/throttling_controller.h"
|
||||||
#include "ui/base/l10n/l10n_util.h"
|
#include "ui/base/l10n/l10n_util.h"
|
||||||
|
|
||||||
using atom::api::Cookies;
|
using atom::api::Cookies;
|
||||||
@@ -94,6 +96,8 @@ uint32_t GetStorageMask(const std::vector<std::string>& storage_types) {
|
|||||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_WEBSQL;
|
storage_mask |= StoragePartition::REMOVE_DATA_MASK_WEBSQL;
|
||||||
else if (type == "serviceworkers")
|
else if (type == "serviceworkers")
|
||||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS;
|
storage_mask |= StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS;
|
||||||
|
else if (type == "cachestorage")
|
||||||
|
storage_mask |= StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE;
|
||||||
}
|
}
|
||||||
return storage_mask;
|
return storage_mask;
|
||||||
}
|
}
|
||||||
@@ -137,7 +141,7 @@ void SetUserAgentInIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
|||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<ClearStorageDataOptions> {
|
struct Converter<ClearStorageDataOptions> {
|
||||||
static bool FromV8(v8::Isolate* isolate,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
v8::Local<v8::Value> val,
|
v8::Local<v8::Value> val,
|
||||||
@@ -206,7 +210,7 @@ struct Converter<net::ProxyConfig> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct Converter<atom::VerifyRequestParams> {
|
struct Converter<atom::VerifyRequestParams> {
|
||||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
atom::VerifyRequestParams val) {
|
atom::VerifyRequestParams val) {
|
||||||
@@ -240,19 +244,17 @@ class ResolveProxyHelper {
|
|||||||
: callback_(callback),
|
: callback_(callback),
|
||||||
original_thread_(base::ThreadTaskRunnerHandle::Get()) {
|
original_thread_(base::ThreadTaskRunnerHandle::Get()) {
|
||||||
scoped_refptr<net::URLRequestContextGetter> context_getter =
|
scoped_refptr<net::URLRequestContextGetter> context_getter =
|
||||||
browser_context->url_request_context_getter();
|
browser_context->GetRequestContext();
|
||||||
context_getter->GetNetworkTaskRunner()->PostTask(
|
context_getter->GetNetworkTaskRunner()->PostTask(
|
||||||
FROM_HERE,
|
FROM_HERE, base::BindOnce(&ResolveProxyHelper::ResolveProxy,
|
||||||
base::Bind(&ResolveProxyHelper::ResolveProxy,
|
base::Unretained(this), context_getter, url));
|
||||||
base::Unretained(this), context_getter, url));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnResolveProxyCompleted(int result) {
|
void OnResolveProxyCompleted(int result) {
|
||||||
std::string proxy;
|
std::string proxy;
|
||||||
if (result == net::OK)
|
if (result == net::OK)
|
||||||
proxy = proxy_info_.ToPacString();
|
proxy = proxy_info_.ToPacString();
|
||||||
original_thread_->PostTask(FROM_HERE,
|
original_thread_->PostTask(FROM_HERE, base::BindOnce(callback_, proxy));
|
||||||
base::Bind(callback_, proxy));
|
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,16 +263,15 @@ class ResolveProxyHelper {
|
|||||||
const GURL& url) {
|
const GURL& url) {
|
||||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||||
|
|
||||||
net::ProxyService* proxy_service =
|
net::ProxyResolutionService* proxy_service =
|
||||||
context_getter->GetURLRequestContext()->proxy_service();
|
context_getter->GetURLRequestContext()->proxy_resolution_service();
|
||||||
net::CompletionCallback completion_callback =
|
net::CompletionCallback completion_callback = base::Bind(
|
||||||
base::Bind(&ResolveProxyHelper::OnResolveProxyCompleted,
|
&ResolveProxyHelper::OnResolveProxyCompleted, base::Unretained(this));
|
||||||
base::Unretained(this));
|
|
||||||
|
|
||||||
// Start the request.
|
// Start the request.
|
||||||
int result = proxy_service->ResolveProxy(
|
int result = proxy_service->ResolveProxy(url, "GET", &proxy_info_,
|
||||||
url, "GET", &proxy_info_, completion_callback, &pac_req_, nullptr,
|
completion_callback, &pac_req_,
|
||||||
net::NetLogWithSource());
|
nullptr, net::NetLogWithSource());
|
||||||
|
|
||||||
// Completed synchronously.
|
// Completed synchronously.
|
||||||
if (result != net::ERR_IO_PENDING)
|
if (result != net::ERR_IO_PENDING)
|
||||||
@@ -279,7 +280,7 @@ class ResolveProxyHelper {
|
|||||||
|
|
||||||
Session::ResolveProxyCallback callback_;
|
Session::ResolveProxyCallback callback_;
|
||||||
net::ProxyInfo proxy_info_;
|
net::ProxyInfo proxy_info_;
|
||||||
net::ProxyService::PacRequest* pac_req_;
|
net::ProxyResolutionService::Request* pac_req_;
|
||||||
scoped_refptr<base::SingleThreadTaskRunner> original_thread_;
|
scoped_refptr<base::SingleThreadTaskRunner> original_thread_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
|
DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
|
||||||
@@ -289,10 +290,10 @@ class ResolveProxyHelper {
|
|||||||
void RunCallbackInUI(const base::Callback<void()>& callback) {
|
void RunCallbackInUI(const base::Callback<void()>& callback) {
|
||||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
|
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
|
||||||
}
|
}
|
||||||
template<typename ...T>
|
template <typename... T>
|
||||||
void RunCallbackInUI(const base::Callback<void(T...)>& callback, T... result) {
|
void RunCallbackInUI(const base::Callback<void(T...)>& callback, T... result) {
|
||||||
BrowserThread::PostTask(
|
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||||
BrowserThread::UI, FROM_HERE, base::Bind(callback, result...));
|
base::BindOnce(callback, result...));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback of HttpCache::GetBackend.
|
// Callback of HttpCache::GetBackend.
|
||||||
@@ -304,8 +305,8 @@ void OnGetBackend(disk_cache::Backend** backend_ptr,
|
|||||||
RunCallbackInUI(callback, result);
|
RunCallbackInUI(callback, result);
|
||||||
} else if (backend_ptr && *backend_ptr) {
|
} else if (backend_ptr && *backend_ptr) {
|
||||||
if (action == Session::CacheAction::CLEAR) {
|
if (action == Session::CacheAction::CLEAR) {
|
||||||
(*backend_ptr)->DoomAllEntries(base::Bind(&RunCallbackInUI<int>,
|
(*backend_ptr)
|
||||||
callback));
|
->DoomAllEntries(base::Bind(&RunCallbackInUI<int>, callback));
|
||||||
} else if (action == Session::CacheAction::STATS) {
|
} else if (action == Session::CacheAction::STATS) {
|
||||||
base::StringPairs stats;
|
base::StringPairs stats;
|
||||||
(*backend_ptr)->GetStats(&stats);
|
(*backend_ptr)->GetStats(&stats);
|
||||||
@@ -327,14 +328,14 @@ void DoCacheActionInIO(
|
|||||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||||
Session::CacheAction action,
|
Session::CacheAction action,
|
||||||
const net::CompletionCallback& callback) {
|
const net::CompletionCallback& callback) {
|
||||||
auto request_context = context_getter->GetURLRequestContext();
|
auto* request_context = context_getter->GetURLRequestContext();
|
||||||
auto http_cache = request_context->http_transaction_factory()->GetCache();
|
auto* http_cache = request_context->http_transaction_factory()->GetCache();
|
||||||
if (!http_cache)
|
if (!http_cache)
|
||||||
RunCallbackInUI<int>(callback, net::ERR_FAILED);
|
RunCallbackInUI<int>(callback, net::ERR_FAILED);
|
||||||
|
|
||||||
// Call GetBackend and make the backend's ptr accessable in OnGetBackend.
|
// Call GetBackend and make the backend's ptr accessable in OnGetBackend.
|
||||||
using BackendPtr = disk_cache::Backend*;
|
using BackendPtr = disk_cache::Backend*;
|
||||||
auto* backend_ptr = new BackendPtr(nullptr);
|
auto** backend_ptr = new BackendPtr(nullptr);
|
||||||
net::CompletionCallback on_get_backend =
|
net::CompletionCallback on_get_backend =
|
||||||
base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, callback);
|
base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, callback);
|
||||||
int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
|
int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
|
||||||
@@ -342,12 +343,13 @@ void DoCacheActionInIO(
|
|||||||
on_get_backend.Run(net::OK);
|
on_get_backend.Run(net::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetProxyInIO(net::URLRequestContextGetter* getter,
|
void SetProxyInIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||||
const net::ProxyConfig& config,
|
const net::ProxyConfig& config,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
auto proxy_service = getter->GetURLRequestContext()->proxy_service();
|
auto* proxy_service =
|
||||||
proxy_service->ResetConfigService(base::WrapUnique(
|
getter->GetURLRequestContext()->proxy_resolution_service();
|
||||||
new net::ProxyConfigServiceFixed(config)));
|
proxy_service->ResetConfigService(
|
||||||
|
base::WrapUnique(new net::ProxyConfigServiceFixed(config)));
|
||||||
// Refetches and applies the new pac script if provided.
|
// Refetches and applies the new pac script if provided.
|
||||||
proxy_service->ForceReloadProxyConfig();
|
proxy_service->ForceReloadProxyConfig();
|
||||||
RunCallbackInUI(callback);
|
RunCallbackInUI(callback);
|
||||||
@@ -356,16 +358,16 @@ void SetProxyInIO(net::URLRequestContextGetter* getter,
|
|||||||
void SetCertVerifyProcInIO(
|
void SetCertVerifyProcInIO(
|
||||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||||
const AtomCertVerifier::VerifyProc& proc) {
|
const AtomCertVerifier::VerifyProc& proc) {
|
||||||
auto request_context = context_getter->GetURLRequestContext();
|
auto* request_context = context_getter->GetURLRequestContext();
|
||||||
static_cast<AtomCertVerifier*>(request_context->cert_verifier())->
|
static_cast<AtomCertVerifier*>(request_context->cert_verifier())
|
||||||
SetVerifyProc(proc);
|
->SetVerifyProc(proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearHostResolverCacheInIO(
|
void ClearHostResolverCacheInIO(
|
||||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
auto request_context = context_getter->GetURLRequestContext();
|
auto* request_context = context_getter->GetURLRequestContext();
|
||||||
auto cache = request_context->host_resolver()->GetHostCache();
|
auto* cache = request_context->host_resolver()->GetHostCache();
|
||||||
if (cache) {
|
if (cache) {
|
||||||
cache->clear();
|
cache->clear();
|
||||||
DCHECK_EQ(0u, cache->size());
|
DCHECK_EQ(0u, cache->size());
|
||||||
@@ -378,12 +380,12 @@ void ClearAuthCacheInIO(
|
|||||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||||
const ClearAuthCacheOptions& options,
|
const ClearAuthCacheOptions& options,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
auto request_context = context_getter->GetURLRequestContext();
|
auto* request_context = context_getter->GetURLRequestContext();
|
||||||
auto network_session =
|
auto* network_session =
|
||||||
request_context->http_transaction_factory()->GetSession();
|
request_context->http_transaction_factory()->GetSession();
|
||||||
if (network_session) {
|
if (network_session) {
|
||||||
if (options.type == "password") {
|
if (options.type == "password") {
|
||||||
auto auth_cache = network_session->http_auth_cache();
|
auto* auth_cache = network_session->http_auth_cache();
|
||||||
if (!options.origin.is_empty()) {
|
if (!options.origin.is_empty()) {
|
||||||
auth_cache->Remove(
|
auth_cache->Remove(
|
||||||
options.origin, options.realm, options.auth_scheme,
|
options.origin, options.realm, options.auth_scheme,
|
||||||
@@ -392,7 +394,7 @@ void ClearAuthCacheInIO(
|
|||||||
auth_cache->ClearEntriesAddedWithin(base::TimeDelta::Max());
|
auth_cache->ClearEntriesAddedWithin(base::TimeDelta::Max());
|
||||||
}
|
}
|
||||||
} else if (options.type == "clientCertificate") {
|
} else if (options.type == "clientCertificate") {
|
||||||
auto client_auth_cache = network_session->ssl_client_auth_cache();
|
auto* client_auth_cache = network_session->ssl_client_auth_cache();
|
||||||
client_auth_cache->Remove(net::HostPortPair::FromURL(options.origin));
|
client_auth_cache->Remove(net::HostPortPair::FromURL(options.origin));
|
||||||
}
|
}
|
||||||
network_session->CloseAllConnections();
|
network_session->CloseAllConnections();
|
||||||
@@ -404,13 +406,13 @@ void ClearAuthCacheInIO(
|
|||||||
void AllowNTLMCredentialsForDomainsInIO(
|
void AllowNTLMCredentialsForDomainsInIO(
|
||||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||||
const std::string& domains) {
|
const std::string& domains) {
|
||||||
auto request_context = context_getter->GetURLRequestContext();
|
auto* request_context = context_getter->GetURLRequestContext();
|
||||||
auto auth_handler = request_context->http_auth_handler_factory();
|
auto* auth_handler = request_context->http_auth_handler_factory();
|
||||||
if (auth_handler) {
|
if (auth_handler) {
|
||||||
auto auth_preferences = const_cast<net::HttpAuthPreferences*>(
|
auto* auth_preferences = const_cast<net::HttpAuthPreferences*>(
|
||||||
auth_handler->http_auth_preferences());
|
auth_handler->http_auth_preferences());
|
||||||
if (auth_preferences)
|
if (auth_preferences)
|
||||||
auth_preferences->set_server_whitelist(domains);
|
auth_preferences->SetServerWhitelist(domains);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,22 +435,39 @@ void DownloadIdCallback(content::DownloadManager* download_manager,
|
|||||||
base::GenerateGUID(), id, path, path, url_chain, GURL(), GURL(), GURL(),
|
base::GenerateGUID(), id, path, path, url_chain, GURL(), GURL(), GURL(),
|
||||||
GURL(), mime_type, mime_type, start_time, base::Time(), etag,
|
GURL(), mime_type, mime_type, start_time, base::Time(), etag,
|
||||||
last_modified, offset, length, std::string(),
|
last_modified, offset, length, std::string(),
|
||||||
content::DownloadItem::INTERRUPTED,
|
download::DownloadItem::INTERRUPTED,
|
||||||
content::DownloadDangerType::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||||
content::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, false,
|
download::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, false, base::Time(),
|
||||||
base::Time(), false,
|
false, std::vector<download::DownloadItem::ReceivedSlice>());
|
||||||
std::vector<content::DownloadItem::ReceivedSlice>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDevToolsNetworkEmulationClientIdInIO(
|
void SetDevToolsNetworkEmulationClientIdInIO(
|
||||||
brightray::URLRequestContextGetter* context_getter,
|
brightray::URLRequestContextGetter* url_request_context_getter,
|
||||||
const std::string& client_id) {
|
const std::string& client_id) {
|
||||||
if (!context_getter)
|
if (!url_request_context_getter)
|
||||||
return;
|
return;
|
||||||
auto network_delegate =
|
net::URLRequestContext* context =
|
||||||
static_cast<AtomNetworkDelegate*>(context_getter->network_delegate());
|
url_request_context_getter->GetURLRequestContext();
|
||||||
if (network_delegate)
|
AtomNetworkDelegate* network_delegate =
|
||||||
network_delegate->SetDevToolsNetworkEmulationClientId(client_id);
|
static_cast<AtomNetworkDelegate*>(context->network_delegate());
|
||||||
|
network_delegate->SetDevToolsNetworkEmulationClientId(client_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyGlobalHandle(v8::Isolate* isolate,
|
||||||
|
const v8::Global<v8::Value>& global_handle) {
|
||||||
|
v8::Locker locker(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();
|
||||||
|
void* ptr = object->GetAlignedPointerFromInternalField(0);
|
||||||
|
if (!ptr)
|
||||||
|
return;
|
||||||
|
delete static_cast<mate::WrappableBase*>(ptr);
|
||||||
|
object->SetAlignedPointerInInternalField(0, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -457,8 +476,8 @@ Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
|||||||
: devtools_network_emulation_client_id_(base::GenerateGUID()),
|
: devtools_network_emulation_client_id_(base::GenerateGUID()),
|
||||||
browser_context_(browser_context) {
|
browser_context_(browser_context) {
|
||||||
// Observe DownloadManager to get download notifications.
|
// Observe DownloadManager to get download notifications.
|
||||||
content::BrowserContext::GetDownloadManager(browser_context)->
|
content::BrowserContext::GetDownloadManager(browser_context)
|
||||||
AddObserver(this);
|
->AddObserver(this);
|
||||||
|
|
||||||
new SessionPreferences(browser_context);
|
new SessionPreferences(browser_context);
|
||||||
|
|
||||||
@@ -467,22 +486,27 @@ Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Session::~Session() {
|
Session::~Session() {
|
||||||
content::BrowserContext::GetDownloadManager(browser_context())->
|
content::BrowserContext::GetDownloadManager(browser_context())
|
||||||
RemoveObserver(this);
|
->RemoveObserver(this);
|
||||||
|
DestroyGlobalHandle(isolate(), cookies_);
|
||||||
|
DestroyGlobalHandle(isolate(), web_request_);
|
||||||
|
DestroyGlobalHandle(isolate(), protocol_);
|
||||||
g_sessions.erase(weak_map_id());
|
g_sessions.erase(weak_map_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::OnDownloadCreated(content::DownloadManager* manager,
|
void Session::OnDownloadCreated(content::DownloadManager* manager,
|
||||||
content::DownloadItem* item) {
|
download::DownloadItem* item) {
|
||||||
if (item->IsSavePackageDownload())
|
if (item->IsSavePackageDownload())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
v8::Locker locker(isolate());
|
v8::Locker locker(isolate());
|
||||||
v8::HandleScope handle_scope(isolate());
|
v8::HandleScope handle_scope(isolate());
|
||||||
auto handle = DownloadItem::Create(isolate(), item);
|
auto handle = DownloadItem::Create(isolate(), item);
|
||||||
if (item->GetState() == content::DownloadItem::INTERRUPTED)
|
if (item->GetState() == download::DownloadItem::INTERRUPTED)
|
||||||
handle->SetSavePath(item->GetTargetFilePath());
|
handle->SetSavePath(item->GetTargetFilePath());
|
||||||
bool prevent_default = Emit("will-download", handle, item->GetWebContents());
|
content::WebContents* web_contents =
|
||||||
|
content::DownloadItemUtils::GetWebContents(item);
|
||||||
|
bool prevent_default = Emit("will-download", handle, web_contents);
|
||||||
if (prevent_default) {
|
if (prevent_default) {
|
||||||
item->Cancel(true);
|
item->Cancel(true);
|
||||||
item->Remove();
|
item->Remove();
|
||||||
@@ -493,13 +517,13 @@ void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
|
|||||||
new ResolveProxyHelper(browser_context(), url, callback);
|
new ResolveProxyHelper(browser_context(), url, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Session::CacheAction action>
|
template <Session::CacheAction action>
|
||||||
void Session::DoCacheAction(const net::CompletionCallback& callback) {
|
void Session::DoCacheAction(const net::CompletionCallback& callback) {
|
||||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
BrowserThread::PostTask(
|
||||||
base::Bind(&DoCacheActionInIO,
|
BrowserThread::IO, FROM_HERE,
|
||||||
make_scoped_refptr(browser_context_->GetRequestContext()),
|
base::BindOnce(&DoCacheActionInIO,
|
||||||
action,
|
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||||
callback));
|
action, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::ClearStorageData(mate::Arguments* args) {
|
void Session::ClearStorageData(mate::Arguments* args) {
|
||||||
@@ -509,7 +533,7 @@ void Session::ClearStorageData(mate::Arguments* args) {
|
|||||||
args->GetNext(&options);
|
args->GetNext(&options);
|
||||||
args->GetNext(&callback);
|
args->GetNext(&callback);
|
||||||
|
|
||||||
auto storage_partition =
|
auto* storage_partition =
|
||||||
content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
|
content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
|
||||||
if (options.storage_types & StoragePartition::REMOVE_DATA_MASK_COOKIES) {
|
if (options.storage_types & StoragePartition::REMOVE_DATA_MASK_COOKIES) {
|
||||||
// Reset media device id salt when cookies are cleared.
|
// Reset media device id salt when cookies are cleared.
|
||||||
@@ -518,66 +542,62 @@ void Session::ClearStorageData(mate::Arguments* args) {
|
|||||||
}
|
}
|
||||||
storage_partition->ClearData(
|
storage_partition->ClearData(
|
||||||
options.storage_types, options.quota_types, options.origin,
|
options.storage_types, options.quota_types, options.origin,
|
||||||
content::StoragePartition::OriginMatcherFunction(),
|
content::StoragePartition::OriginMatcherFunction(), base::Time(),
|
||||||
base::Time(), base::Time::Max(),
|
base::Time::Max(), base::Bind(&OnClearStorageDataDone, callback));
|
||||||
base::Bind(&OnClearStorageDataDone, callback));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::FlushStorageData() {
|
void Session::FlushStorageData() {
|
||||||
auto storage_partition =
|
auto* storage_partition =
|
||||||
content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
|
content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
|
||||||
storage_partition->Flush();
|
storage_partition->Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::SetProxy(const net::ProxyConfig& config,
|
void Session::SetProxy(const net::ProxyConfig& config,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
auto getter = browser_context_->GetRequestContext();
|
auto* getter = browser_context_->GetRequestContext();
|
||||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
BrowserThread::PostTask(
|
||||||
base::Bind(&SetProxyInIO, base::Unretained(getter), config, callback));
|
BrowserThread::IO, FROM_HERE,
|
||||||
|
base::BindOnce(&SetProxyInIO, base::RetainedRef(getter), config,
|
||||||
|
callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::SetDownloadPath(const base::FilePath& path) {
|
void Session::SetDownloadPath(const base::FilePath& path) {
|
||||||
browser_context_->prefs()->SetFilePath(
|
browser_context_->prefs()->SetFilePath(prefs::kDownloadDefaultDirectory,
|
||||||
prefs::kDownloadDefaultDirectory, path);
|
path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::EnableNetworkEmulation(const mate::Dictionary& options) {
|
void Session::EnableNetworkEmulation(const mate::Dictionary& options) {
|
||||||
std::unique_ptr<brightray::DevToolsNetworkConditions> conditions;
|
std::unique_ptr<network::NetworkConditions> conditions;
|
||||||
bool offline = false;
|
bool offline = false;
|
||||||
double latency = 0.0, download_throughput = 0.0, upload_throughput = 0.0;
|
double latency = 0.0, download_throughput = 0.0, upload_throughput = 0.0;
|
||||||
if (options.Get("offline", &offline) && offline) {
|
if (options.Get("offline", &offline) && offline) {
|
||||||
conditions.reset(new brightray::DevToolsNetworkConditions(offline));
|
conditions.reset(new network::NetworkConditions(offline));
|
||||||
} else {
|
} else {
|
||||||
options.Get("latency", &latency);
|
options.Get("latency", &latency);
|
||||||
options.Get("downloadThroughput", &download_throughput);
|
options.Get("downloadThroughput", &download_throughput);
|
||||||
options.Get("uploadThroughput", &upload_throughput);
|
options.Get("uploadThroughput", &upload_throughput);
|
||||||
conditions.reset(
|
conditions.reset(new network::NetworkConditions(
|
||||||
new brightray::DevToolsNetworkConditions(false,
|
false, latency, download_throughput, upload_throughput));
|
||||||
latency,
|
|
||||||
download_throughput,
|
|
||||||
upload_throughput));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
browser_context_->network_controller_handle()->SetNetworkState(
|
network::ThrottlingController::SetConditions(
|
||||||
devtools_network_emulation_client_id_, std::move(conditions));
|
devtools_network_emulation_client_id_, std::move(conditions));
|
||||||
BrowserThread::PostTask(
|
BrowserThread::PostTask(
|
||||||
BrowserThread::IO, FROM_HERE,
|
BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(
|
base::BindOnce(&SetDevToolsNetworkEmulationClientIdInIO,
|
||||||
&SetDevToolsNetworkEmulationClientIdInIO,
|
base::RetainedRef(browser_context_->GetRequestContext()),
|
||||||
base::RetainedRef(browser_context_->url_request_context_getter()),
|
devtools_network_emulation_client_id_));
|
||||||
devtools_network_emulation_client_id_));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::DisableNetworkEmulation() {
|
void Session::DisableNetworkEmulation() {
|
||||||
std::unique_ptr<brightray::DevToolsNetworkConditions> conditions;
|
auto conditions = std::make_unique<network::NetworkConditions>();
|
||||||
browser_context_->network_controller_handle()->SetNetworkState(
|
network::ThrottlingController::SetConditions(
|
||||||
devtools_network_emulation_client_id_, std::move(conditions));
|
devtools_network_emulation_client_id_, std::move(conditions));
|
||||||
BrowserThread::PostTask(
|
BrowserThread::PostTask(
|
||||||
BrowserThread::IO, FROM_HERE,
|
BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(
|
base::BindOnce(&SetDevToolsNetworkEmulationClientIdInIO,
|
||||||
&SetDevToolsNetworkEmulationClientIdInIO,
|
base::RetainedRef(browser_context_->GetRequestContext()),
|
||||||
base::RetainedRef(browser_context_->url_request_context_getter()),
|
std::string()));
|
||||||
std::string()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
|
void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
|
||||||
@@ -588,10 +608,11 @@ void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
BrowserThread::PostTask(
|
||||||
base::Bind(&SetCertVerifyProcInIO,
|
BrowserThread::IO, FROM_HERE,
|
||||||
make_scoped_refptr(browser_context_->GetRequestContext()),
|
base::BindOnce(&SetCertVerifyProcInIO,
|
||||||
proc));
|
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||||
|
proc));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
||||||
@@ -601,7 +622,7 @@ void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
|||||||
args->ThrowError("Must pass null or function");
|
args->ThrowError("Must pass null or function");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto permission_manager = static_cast<AtomPermissionManager*>(
|
auto* permission_manager = static_cast<AtomPermissionManager*>(
|
||||||
browser_context()->GetPermissionManager());
|
browser_context()->GetPermissionManager());
|
||||||
permission_manager->SetPermissionRequestHandler(handler);
|
permission_manager->SetPermissionRequestHandler(handler);
|
||||||
}
|
}
|
||||||
@@ -610,10 +631,11 @@ void Session::ClearHostResolverCache(mate::Arguments* args) {
|
|||||||
base::Closure callback;
|
base::Closure callback;
|
||||||
args->GetNext(&callback);
|
args->GetNext(&callback);
|
||||||
|
|
||||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
BrowserThread::PostTask(
|
||||||
base::Bind(&ClearHostResolverCacheInIO,
|
BrowserThread::IO, FROM_HERE,
|
||||||
make_scoped_refptr(browser_context_->GetRequestContext()),
|
base::BindOnce(&ClearHostResolverCacheInIO,
|
||||||
callback));
|
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||||
|
callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::ClearAuthCache(mate::Arguments* args) {
|
void Session::ClearAuthCache(mate::Arguments* args) {
|
||||||
@@ -627,16 +649,17 @@ void Session::ClearAuthCache(mate::Arguments* args) {
|
|||||||
|
|
||||||
BrowserThread::PostTask(
|
BrowserThread::PostTask(
|
||||||
BrowserThread::IO, FROM_HERE,
|
BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(&ClearAuthCacheInIO,
|
base::BindOnce(&ClearAuthCacheInIO,
|
||||||
make_scoped_refptr(browser_context_->GetRequestContext()),
|
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||||
options, callback));
|
options, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::AllowNTLMCredentialsForDomains(const std::string& domains) {
|
void Session::AllowNTLMCredentialsForDomains(const std::string& domains) {
|
||||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
BrowserThread::PostTask(
|
||||||
base::Bind(&AllowNTLMCredentialsForDomainsInIO,
|
BrowserThread::IO, FROM_HERE,
|
||||||
make_scoped_refptr(browser_context_->GetRequestContext()),
|
base::BindOnce(&AllowNTLMCredentialsForDomainsInIO,
|
||||||
domains));
|
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||||
|
domains));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::SetUserAgent(const std::string& user_agent,
|
void Session::SetUserAgent(const std::string& user_agent,
|
||||||
@@ -650,26 +673,23 @@ void Session::SetUserAgent(const std::string& user_agent,
|
|||||||
browser_context_->GetRequestContext());
|
browser_context_->GetRequestContext());
|
||||||
getter->GetNetworkTaskRunner()->PostTask(
|
getter->GetNetworkTaskRunner()->PostTask(
|
||||||
FROM_HERE,
|
FROM_HERE,
|
||||||
base::Bind(&SetUserAgentInIO, getter, accept_lang, user_agent));
|
base::BindOnce(&SetUserAgentInIO, getter, accept_lang, user_agent));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Session::GetUserAgent() {
|
std::string Session::GetUserAgent() {
|
||||||
return browser_context_->GetUserAgent();
|
return browser_context_->GetUserAgent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::GetBlobData(
|
void Session::GetBlobData(const std::string& uuid,
|
||||||
const std::string& uuid,
|
const AtomBlobReader::CompletionCallback& callback) {
|
||||||
const AtomBlobReader::CompletionCallback& callback) {
|
|
||||||
if (callback.is_null())
|
if (callback.is_null())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
AtomBlobReader* blob_reader =
|
AtomBlobReader* blob_reader = browser_context()->GetBlobReader();
|
||||||
browser_context()->GetBlobReader();
|
BrowserThread::PostTask(
|
||||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(&AtomBlobReader::StartReading,
|
base::BindOnce(&AtomBlobReader::StartReading,
|
||||||
base::Unretained(blob_reader),
|
base::Unretained(blob_reader), uuid, callback));
|
||||||
uuid,
|
|
||||||
callback));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::CreateInterruptedDownload(const mate::Dictionary& options) {
|
void Session::CreateInterruptedDownload(const mate::Dictionary& options) {
|
||||||
@@ -696,7 +716,7 @@ void Session::CreateInterruptedDownload(const mate::Dictionary& options) {
|
|||||||
isolate(), "Must pass an offset value less than length.")));
|
isolate(), "Must pass an offset value less than length.")));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto download_manager =
|
auto* download_manager =
|
||||||
content::BrowserContext::GetDownloadManager(browser_context());
|
content::BrowserContext::GetDownloadManager(browser_context());
|
||||||
download_manager->GetDelegate()->GetNextId(base::Bind(
|
download_manager->GetDelegate()->GetNextId(base::Bind(
|
||||||
&DownloadIdCallback, download_manager, path, url_chain, mime_type, offset,
|
&DownloadIdCallback, download_manager, path, url_chain, mime_type, offset,
|
||||||
@@ -741,14 +761,14 @@ v8::Local<v8::Value> Session::WebRequest(v8::Isolate* isolate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
mate::Handle<Session> Session::CreateFrom(
|
mate::Handle<Session> Session::CreateFrom(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate, AtomBrowserContext* browser_context) {
|
AtomBrowserContext* browser_context) {
|
||||||
auto existing = TrackableObject::FromWrappedClass(isolate, browser_context);
|
auto* existing = TrackableObject::FromWrappedClass(isolate, browser_context);
|
||||||
if (existing)
|
if (existing)
|
||||||
return mate::CreateHandle(isolate, static_cast<Session*>(existing));
|
return mate::CreateHandle(isolate, static_cast<Session*>(existing));
|
||||||
|
|
||||||
auto handle = mate::CreateHandle(
|
auto handle =
|
||||||
isolate, new Session(isolate, browser_context));
|
mate::CreateHandle(isolate, new Session(isolate, browser_context));
|
||||||
|
|
||||||
// The Sessions should never be garbage collected, since the common pattern is
|
// The Sessions should never be garbage collected, since the common pattern is
|
||||||
// to use partition strings, instead of using the Session object directly.
|
// to use partition strings, instead of using the Session object directly.
|
||||||
@@ -760,7 +780,8 @@ mate::Handle<Session> Session::CreateFrom(
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
mate::Handle<Session> Session::FromPartition(
|
mate::Handle<Session> Session::FromPartition(
|
||||||
v8::Isolate* isolate, const std::string& partition,
|
v8::Isolate* isolate,
|
||||||
|
const std::string& partition,
|
||||||
const base::DictionaryValue& options) {
|
const base::DictionaryValue& options) {
|
||||||
scoped_refptr<AtomBrowserContext> browser_context;
|
scoped_refptr<AtomBrowserContext> browser_context;
|
||||||
if (partition.empty()) {
|
if (partition.empty()) {
|
||||||
@@ -790,7 +811,7 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
|||||||
.SetMethod("setDownloadPath", &Session::SetDownloadPath)
|
.SetMethod("setDownloadPath", &Session::SetDownloadPath)
|
||||||
.SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation)
|
.SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation)
|
||||||
.SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation)
|
.SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation)
|
||||||
.SetMethod("_setCertificateVerifyProc", &Session::SetCertVerifyProc)
|
.SetMethod("setCertificateVerifyProc", &Session::SetCertVerifyProc)
|
||||||
.SetMethod("setPermissionRequestHandler",
|
.SetMethod("setPermissionRequestHandler",
|
||||||
&Session::SetPermissionRequestHandler)
|
&Session::SetPermissionRequestHandler)
|
||||||
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
|
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
|
||||||
@@ -817,8 +838,8 @@ namespace {
|
|||||||
|
|
||||||
using atom::api::Session;
|
using atom::api::Session;
|
||||||
|
|
||||||
v8::Local<v8::Value> FromPartition(
|
v8::Local<v8::Value> FromPartition(const std::string& partition,
|
||||||
const std::string& partition, mate::Arguments* args) {
|
mate::Arguments* args) {
|
||||||
if (!atom::Browser::Get()->is_ready()) {
|
if (!atom::Browser::Get()->is_ready()) {
|
||||||
args->ThrowError("Session can only be received when app is ready");
|
args->ThrowError("Session can only be received when app is ready");
|
||||||
return v8::Null(args->isolate());
|
return v8::Null(args->isolate());
|
||||||
@@ -828,8 +849,10 @@ v8::Local<v8::Value> FromPartition(
|
|||||||
return Session::FromPartition(args->isolate(), partition, options).ToV8();
|
return Session::FromPartition(args->isolate(), partition, options).ToV8();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.Set("Session", Session::GetConstructor(isolate)->GetFunction());
|
dict.Set("Session", Session::GetConstructor(isolate)->GetFunction());
|
||||||
@@ -839,4 +862,4 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_session, Initialize)
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_session, Initialize)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class FilePath;
|
|||||||
namespace mate {
|
namespace mate {
|
||||||
class Arguments;
|
class Arguments;
|
||||||
class Dictionary;
|
class Dictionary;
|
||||||
}
|
} // namespace mate
|
||||||
|
|
||||||
namespace net {
|
namespace net {
|
||||||
class ProxyConfig;
|
class ProxyConfig;
|
||||||
@@ -36,8 +36,8 @@ class AtomBrowserContext;
|
|||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class Session: public mate::TrackableObject<Session>,
|
class Session : public mate::TrackableObject<Session>,
|
||||||
public content::DownloadManager::Observer {
|
public content::DownloadManager::Observer {
|
||||||
public:
|
public:
|
||||||
using ResolveProxyCallback = base::Callback<void(std::string)>;
|
using ResolveProxyCallback = base::Callback<void(std::string)>;
|
||||||
|
|
||||||
@@ -47,12 +47,13 @@ class Session: public mate::TrackableObject<Session>,
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Gets or creates Session from the |browser_context|.
|
// Gets or creates Session from the |browser_context|.
|
||||||
static mate::Handle<Session> CreateFrom(
|
static mate::Handle<Session> CreateFrom(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
AtomBrowserContext* browser_context);
|
||||||
|
|
||||||
// Gets the Session of |partition|.
|
// Gets the Session of |partition|.
|
||||||
static mate::Handle<Session> FromPartition(
|
static mate::Handle<Session> FromPartition(
|
||||||
v8::Isolate* isolate, const std::string& partition,
|
v8::Isolate* isolate,
|
||||||
|
const std::string& partition,
|
||||||
const base::DictionaryValue& options = base::DictionaryValue());
|
const base::DictionaryValue& options = base::DictionaryValue());
|
||||||
|
|
||||||
AtomBrowserContext* browser_context() const { return browser_context_.get(); }
|
AtomBrowserContext* browser_context() const { return browser_context_.get(); }
|
||||||
@@ -63,7 +64,7 @@ class Session: public mate::TrackableObject<Session>,
|
|||||||
|
|
||||||
// Methods.
|
// Methods.
|
||||||
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
|
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
|
||||||
template<CacheAction action>
|
template <CacheAction action>
|
||||||
void DoCacheAction(const net::CompletionCallback& callback);
|
void DoCacheAction(const net::CompletionCallback& callback);
|
||||||
void ClearStorageData(mate::Arguments* args);
|
void ClearStorageData(mate::Arguments* args);
|
||||||
void FlushStorageData();
|
void FlushStorageData();
|
||||||
@@ -90,11 +91,11 @@ class Session: public mate::TrackableObject<Session>,
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
Session(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
Session(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||||
~Session();
|
~Session() override;
|
||||||
|
|
||||||
// content::DownloadManager::Observer:
|
// content::DownloadManager::Observer:
|
||||||
void OnDownloadCreated(content::DownloadManager* manager,
|
void OnDownloadCreated(content::DownloadManager* manager,
|
||||||
content::DownloadItem* item) override;
|
download::DownloadItem* item) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Cached object.
|
// Cached object.
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ mate::Handle<SystemPreferences> SystemPreferences::Create(
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
void SystemPreferences::BuildPrototype(
|
void SystemPreferences::BuildPrototype(
|
||||||
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
|
v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
prototype->SetClassName(mate::StringToV8(isolate, "SystemPreferences"));
|
prototype->SetClassName(mate::StringToV8(isolate, "SystemPreferences"));
|
||||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
@@ -53,18 +54,23 @@ void SystemPreferences::BuildPrototype(
|
|||||||
.SetMethod("isAeroGlassEnabled", &SystemPreferences::IsAeroGlassEnabled)
|
.SetMethod("isAeroGlassEnabled", &SystemPreferences::IsAeroGlassEnabled)
|
||||||
.SetMethod("getColor", &SystemPreferences::GetColor)
|
.SetMethod("getColor", &SystemPreferences::GetColor)
|
||||||
#elif defined(OS_MACOSX)
|
#elif defined(OS_MACOSX)
|
||||||
.SetMethod("postNotification",
|
.SetMethod("postNotification", &SystemPreferences::PostNotification)
|
||||||
&SystemPreferences::PostNotification)
|
|
||||||
.SetMethod("postLocalNotification",
|
|
||||||
&SystemPreferences::PostLocalNotification)
|
|
||||||
.SetMethod("subscribeNotification",
|
.SetMethod("subscribeNotification",
|
||||||
&SystemPreferences::SubscribeNotification)
|
&SystemPreferences::SubscribeNotification)
|
||||||
.SetMethod("unsubscribeNotification",
|
.SetMethod("unsubscribeNotification",
|
||||||
&SystemPreferences::UnsubscribeNotification)
|
&SystemPreferences::UnsubscribeNotification)
|
||||||
|
.SetMethod("postLocalNotification",
|
||||||
|
&SystemPreferences::PostLocalNotification)
|
||||||
.SetMethod("subscribeLocalNotification",
|
.SetMethod("subscribeLocalNotification",
|
||||||
&SystemPreferences::SubscribeLocalNotification)
|
&SystemPreferences::SubscribeLocalNotification)
|
||||||
.SetMethod("unsubscribeLocalNotification",
|
.SetMethod("unsubscribeLocalNotification",
|
||||||
&SystemPreferences::UnsubscribeLocalNotification)
|
&SystemPreferences::UnsubscribeLocalNotification)
|
||||||
|
.SetMethod("postWorkspaceNotification",
|
||||||
|
&SystemPreferences::PostWorkspaceNotification)
|
||||||
|
.SetMethod("subscribeWorkspaceNotification",
|
||||||
|
&SystemPreferences::SubscribeWorkspaceNotification)
|
||||||
|
.SetMethod("unsubscribeWorkspaceNotification",
|
||||||
|
&SystemPreferences::UnsubscribeWorkspaceNotification)
|
||||||
.SetMethod("registerDefaults", &SystemPreferences::RegisterDefaults)
|
.SetMethod("registerDefaults", &SystemPreferences::RegisterDefaults)
|
||||||
.SetMethod("getUserDefault", &SystemPreferences::GetUserDefault)
|
.SetMethod("getUserDefault", &SystemPreferences::GetUserDefault)
|
||||||
.SetMethod("setUserDefault", &SystemPreferences::SetUserDefault)
|
.SetMethod("setUserDefault", &SystemPreferences::SetUserDefault)
|
||||||
@@ -85,8 +91,10 @@ namespace {
|
|||||||
|
|
||||||
using atom::api::SystemPreferences;
|
using atom::api::SystemPreferences;
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Value> unused,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.Set("systemPreferences", SystemPreferences::Create(isolate));
|
dict.Set("systemPreferences", SystemPreferences::Create(isolate));
|
||||||
@@ -96,4 +104,4 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_system_preferences, Initialize);
|
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_system_preferences, Initialize);
|
||||||
|
|||||||
@@ -26,12 +26,21 @@ namespace atom {
|
|||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
enum NotificationCenterKind {
|
||||||
|
kNSDistributedNotificationCenter = 0,
|
||||||
|
kNSNotificationCenter,
|
||||||
|
kNSWorkspaceNotificationCenter,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
, public BrowserObserver
|
,
|
||||||
, public gfx::SysColorChangeListener
|
public BrowserObserver,
|
||||||
|
public gfx::SysColorChangeListener
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static mate::Handle<SystemPreferences> Create(v8::Isolate* isolate);
|
static mate::Handle<SystemPreferences> Create(v8::Isolate* isolate);
|
||||||
|
|
||||||
@@ -41,10 +50,10 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
|||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
bool IsAeroGlassEnabled();
|
bool IsAeroGlassEnabled();
|
||||||
|
|
||||||
typedef HRESULT (STDAPICALLTYPE *DwmGetColorizationColor)(DWORD *, BOOL *);
|
typedef HRESULT(STDAPICALLTYPE* DwmGetColorizationColor)(DWORD*, BOOL*);
|
||||||
DwmGetColorizationColor dwmGetColorizationColor =
|
DwmGetColorizationColor dwmGetColorizationColor =
|
||||||
(DwmGetColorizationColor) GetProcAddress(LoadLibraryW(L"dwmapi.dll"),
|
(DwmGetColorizationColor)GetProcAddress(LoadLibraryW(L"dwmapi.dll"),
|
||||||
"DwmGetColorizationColor");
|
"DwmGetColorizationColor");
|
||||||
|
|
||||||
std::string GetAccentColor();
|
std::string GetAccentColor();
|
||||||
std::string GetColor(const std::string& color, mate::Arguments* args);
|
std::string GetColor(const std::string& color, mate::Arguments* args);
|
||||||
@@ -58,19 +67,24 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
|||||||
void OnFinishLaunching(const base::DictionaryValue& launch_info) override;
|
void OnFinishLaunching(const base::DictionaryValue& launch_info) override;
|
||||||
|
|
||||||
#elif defined(OS_MACOSX)
|
#elif defined(OS_MACOSX)
|
||||||
using NotificationCallback = base::Callback<
|
using NotificationCallback =
|
||||||
void(const std::string&, const base::DictionaryValue&)>;
|
base::Callback<void(const std::string&, const base::DictionaryValue&)>;
|
||||||
|
|
||||||
void PostNotification(const std::string& name,
|
void PostNotification(const std::string& name,
|
||||||
const base::DictionaryValue& user_info);
|
const base::DictionaryValue& user_info);
|
||||||
void PostLocalNotification(const std::string& name,
|
|
||||||
const base::DictionaryValue& user_info);
|
|
||||||
int SubscribeNotification(const std::string& name,
|
int SubscribeNotification(const std::string& name,
|
||||||
const NotificationCallback& callback);
|
const NotificationCallback& callback);
|
||||||
void UnsubscribeNotification(int id);
|
void UnsubscribeNotification(int id);
|
||||||
|
void PostLocalNotification(const std::string& name,
|
||||||
|
const base::DictionaryValue& user_info);
|
||||||
int SubscribeLocalNotification(const std::string& name,
|
int SubscribeLocalNotification(const std::string& name,
|
||||||
const NotificationCallback& callback);
|
const NotificationCallback& callback);
|
||||||
void UnsubscribeLocalNotification(int request_id);
|
void UnsubscribeLocalNotification(int request_id);
|
||||||
|
void PostWorkspaceNotification(const std::string& name,
|
||||||
|
const base::DictionaryValue& user_info);
|
||||||
|
int SubscribeWorkspaceNotification(const std::string& name,
|
||||||
|
const NotificationCallback& callback);
|
||||||
|
void UnsubscribeWorkspaceNotification(int request_id);
|
||||||
v8::Local<v8::Value> GetUserDefault(const std::string& name,
|
v8::Local<v8::Value> GetUserDefault(const std::string& name,
|
||||||
const std::string& type);
|
const std::string& type);
|
||||||
void RegisterDefaults(mate::Arguments* args);
|
void RegisterDefaults(mate::Arguments* args);
|
||||||
@@ -90,21 +104,25 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
|||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
void DoPostNotification(const std::string& name,
|
void DoPostNotification(const std::string& name,
|
||||||
const base::DictionaryValue& user_info,
|
const base::DictionaryValue& user_info,
|
||||||
bool is_local);
|
NotificationCenterKind kind);
|
||||||
int DoSubscribeNotification(const std::string& name,
|
int DoSubscribeNotification(const std::string& name,
|
||||||
const NotificationCallback& callback,
|
const NotificationCallback& callback,
|
||||||
bool is_local);
|
NotificationCenterKind kind);
|
||||||
void DoUnsubscribeNotification(int request_id, bool is_local);
|
void DoUnsubscribeNotification(int request_id, NotificationCenterKind kind);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
// Static callback invoked when a message comes in to our messaging window.
|
// Static callback invoked when a message comes in to our messaging window.
|
||||||
static LRESULT CALLBACK
|
static LRESULT CALLBACK WndProcStatic(HWND hwnd,
|
||||||
WndProcStatic(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
|
UINT message,
|
||||||
|
WPARAM wparam,
|
||||||
|
LPARAM lparam);
|
||||||
|
|
||||||
LRESULT CALLBACK
|
LRESULT CALLBACK WndProc(HWND hwnd,
|
||||||
WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
|
UINT message,
|
||||||
|
WPARAM wparam,
|
||||||
|
LPARAM lparam);
|
||||||
|
|
||||||
// The window class of |window_|.
|
// The window class of |window_|.
|
||||||
ATOM atom_;
|
ATOM atom_;
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
#include "atom/browser/mac/dict_util.h"
|
#include "atom/browser/mac/dict_util.h"
|
||||||
#include "atom/common/native_mate_converters/value_converter.h"
|
|
||||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||||
|
#include "atom/common/native_mate_converters/value_converter.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
#include "net/base/mac/url_conversions.h"
|
#include "net/base/mac/url_conversions.h"
|
||||||
@@ -28,94 +28,151 @@ std::map<int, id> g_id_map;
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void SystemPreferences::PostNotification(const std::string& name,
|
void SystemPreferences::PostNotification(
|
||||||
|
const std::string& name,
|
||||||
const base::DictionaryValue& user_info) {
|
const base::DictionaryValue& user_info) {
|
||||||
DoPostNotification(name, user_info, false);
|
DoPostNotification(name, user_info, kNSDistributedNotificationCenter);
|
||||||
}
|
|
||||||
|
|
||||||
void SystemPreferences::PostLocalNotification(const std::string& name,
|
|
||||||
const base::DictionaryValue& user_info) {
|
|
||||||
DoPostNotification(name, user_info, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SystemPreferences::DoPostNotification(const std::string& name,
|
|
||||||
const base::DictionaryValue& user_info, bool is_local) {
|
|
||||||
NSNotificationCenter* center = is_local ?
|
|
||||||
[NSNotificationCenter defaultCenter] :
|
|
||||||
[NSDistributedNotificationCenter defaultCenter];
|
|
||||||
[center
|
|
||||||
postNotificationName:base::SysUTF8ToNSString(name)
|
|
||||||
object:nil
|
|
||||||
userInfo:DictionaryValueToNSDictionary(user_info)
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SystemPreferences::SubscribeNotification(
|
int SystemPreferences::SubscribeNotification(
|
||||||
const std::string& name, const NotificationCallback& callback) {
|
const std::string& name,
|
||||||
return DoSubscribeNotification(name, callback, false);
|
const NotificationCallback& callback) {
|
||||||
|
return DoSubscribeNotification(name, callback,
|
||||||
|
kNSDistributedNotificationCenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemPreferences::UnsubscribeNotification(int request_id) {
|
void SystemPreferences::UnsubscribeNotification(int request_id) {
|
||||||
DoUnsubscribeNotification(request_id, false);
|
DoUnsubscribeNotification(request_id, kNSDistributedNotificationCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemPreferences::PostLocalNotification(
|
||||||
|
const std::string& name,
|
||||||
|
const base::DictionaryValue& user_info) {
|
||||||
|
DoPostNotification(name, user_info, kNSNotificationCenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SystemPreferences::SubscribeLocalNotification(
|
int SystemPreferences::SubscribeLocalNotification(
|
||||||
const std::string& name, const NotificationCallback& callback) {
|
const std::string& name,
|
||||||
return DoSubscribeNotification(name, callback, true);
|
const NotificationCallback& callback) {
|
||||||
|
return DoSubscribeNotification(name, callback, kNSNotificationCenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemPreferences::UnsubscribeLocalNotification(int request_id) {
|
void SystemPreferences::UnsubscribeLocalNotification(int request_id) {
|
||||||
DoUnsubscribeNotification(request_id, true);
|
DoUnsubscribeNotification(request_id, kNSNotificationCenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SystemPreferences::DoSubscribeNotification(const std::string& name,
|
void SystemPreferences::PostWorkspaceNotification(
|
||||||
const NotificationCallback& callback, bool is_local) {
|
const std::string& name,
|
||||||
|
const base::DictionaryValue& user_info) {
|
||||||
|
DoPostNotification(name, user_info, kNSWorkspaceNotificationCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SystemPreferences::SubscribeWorkspaceNotification(
|
||||||
|
const std::string& name,
|
||||||
|
const NotificationCallback& callback) {
|
||||||
|
return DoSubscribeNotification(name, callback,
|
||||||
|
kNSWorkspaceNotificationCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
NotificationCenterKind kind) {
|
||||||
int request_id = g_next_id++;
|
int request_id = g_next_id++;
|
||||||
__block NotificationCallback copied_callback = callback;
|
__block NotificationCallback copied_callback = callback;
|
||||||
NSNotificationCenter* center = is_local ?
|
NSNotificationCenter* center;
|
||||||
[NSNotificationCenter defaultCenter] :
|
switch (kind) {
|
||||||
[NSDistributedNotificationCenter defaultCenter];
|
case kNSDistributedNotificationCenter:
|
||||||
|
center = [NSDistributedNotificationCenter defaultCenter];
|
||||||
|
break;
|
||||||
|
case kNSNotificationCenter:
|
||||||
|
center = [NSNotificationCenter defaultCenter];
|
||||||
|
break;
|
||||||
|
case kNSWorkspaceNotificationCenter:
|
||||||
|
center = [[NSWorkspace sharedWorkspace] notificationCenter];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
g_id_map[request_id] = [center
|
g_id_map[request_id] = [center
|
||||||
addObserverForName:base::SysUTF8ToNSString(name)
|
addObserverForName:base::SysUTF8ToNSString(name)
|
||||||
object:nil
|
object:nil
|
||||||
queue:nil
|
queue:nil
|
||||||
usingBlock:^(NSNotification* notification) {
|
usingBlock:^(NSNotification* notification) {
|
||||||
std::unique_ptr<base::DictionaryValue> user_info =
|
std::unique_ptr<base::DictionaryValue> user_info =
|
||||||
NSDictionaryToDictionaryValue(notification.userInfo);
|
NSDictionaryToDictionaryValue(notification.userInfo);
|
||||||
if (user_info) {
|
if (user_info) {
|
||||||
copied_callback.Run(
|
copied_callback.Run(
|
||||||
base::SysNSStringToUTF8(notification.name),
|
base::SysNSStringToUTF8(notification.name), *user_info);
|
||||||
*user_info);
|
} else {
|
||||||
} else {
|
copied_callback.Run(
|
||||||
copied_callback.Run(
|
base::SysNSStringToUTF8(notification.name),
|
||||||
base::SysNSStringToUTF8(notification.name),
|
base::DictionaryValue());
|
||||||
base::DictionaryValue());
|
}
|
||||||
}
|
}];
|
||||||
}
|
|
||||||
];
|
|
||||||
return request_id;
|
return request_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemPreferences::DoUnsubscribeNotification(int request_id, bool is_local) {
|
void SystemPreferences::DoUnsubscribeNotification(int request_id,
|
||||||
|
NotificationCenterKind kind) {
|
||||||
auto iter = g_id_map.find(request_id);
|
auto iter = g_id_map.find(request_id);
|
||||||
if (iter != g_id_map.end()) {
|
if (iter != g_id_map.end()) {
|
||||||
id observer = iter->second;
|
id observer = iter->second;
|
||||||
NSNotificationCenter* center = is_local ?
|
NSNotificationCenter* center;
|
||||||
[NSNotificationCenter defaultCenter] :
|
switch (kind) {
|
||||||
[NSDistributedNotificationCenter defaultCenter];
|
case kNSDistributedNotificationCenter:
|
||||||
|
center = [NSDistributedNotificationCenter defaultCenter];
|
||||||
|
break;
|
||||||
|
case kNSNotificationCenter:
|
||||||
|
center = [NSNotificationCenter defaultCenter];
|
||||||
|
break;
|
||||||
|
case kNSWorkspaceNotificationCenter:
|
||||||
|
center = [[NSWorkspace sharedWorkspace] notificationCenter];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
[center removeObserver:observer];
|
[center removeObserver:observer];
|
||||||
g_id_map.erase(iter);
|
g_id_map.erase(iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Local<v8::Value> SystemPreferences::GetUserDefault(
|
v8::Local<v8::Value> SystemPreferences::GetUserDefault(
|
||||||
const std::string& name, const std::string& type) {
|
const std::string& name,
|
||||||
|
const std::string& type) {
|
||||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||||
NSString* key = base::SysUTF8ToNSString(name);
|
NSString* key = base::SysUTF8ToNSString(name);
|
||||||
if (type == "string") {
|
if (type == "string") {
|
||||||
return mate::StringToV8(isolate(),
|
return mate::StringToV8(
|
||||||
base::SysNSStringToUTF8([defaults stringForKey:key]));
|
isolate(), base::SysNSStringToUTF8([defaults stringForKey:key]));
|
||||||
} else if (type == "boolean") {
|
} else if (type == "boolean") {
|
||||||
return v8::Boolean::New(isolate(), [defaults boolForKey:key]);
|
return v8::Boolean::New(isolate(), [defaults boolForKey:key]);
|
||||||
} else if (type == "float") {
|
} else if (type == "float") {
|
||||||
@@ -126,7 +183,7 @@ v8::Local<v8::Value> SystemPreferences::GetUserDefault(
|
|||||||
return v8::Number::New(isolate(), [defaults doubleForKey:key]);
|
return v8::Number::New(isolate(), [defaults doubleForKey:key]);
|
||||||
} else if (type == "url") {
|
} else if (type == "url") {
|
||||||
return mate::ConvertToV8(isolate(),
|
return mate::ConvertToV8(isolate(),
|
||||||
net::GURLWithNSURL([defaults URLForKey:key]));
|
net::GURLWithNSURL([defaults URLForKey:key]));
|
||||||
} else if (type == "array") {
|
} else if (type == "array") {
|
||||||
std::unique_ptr<base::ListValue> list =
|
std::unique_ptr<base::ListValue> list =
|
||||||
NSArrayToListValue([defaults arrayForKey:key]);
|
NSArrayToListValue([defaults arrayForKey:key]);
|
||||||
@@ -147,7 +204,7 @@ v8::Local<v8::Value> SystemPreferences::GetUserDefault(
|
|||||||
void SystemPreferences::RegisterDefaults(mate::Arguments* args) {
|
void SystemPreferences::RegisterDefaults(mate::Arguments* args) {
|
||||||
base::DictionaryValue value;
|
base::DictionaryValue value;
|
||||||
|
|
||||||
if(!args->GetNext(&value)) {
|
if (!args->GetNext(&value)) {
|
||||||
args->ThrowError("Invalid userDefault data provided");
|
args->ThrowError("Invalid userDefault data provided");
|
||||||
} else {
|
} else {
|
||||||
@try {
|
@try {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user