mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
1185 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1dd98171f4 | ||
|
|
994cc62031 | ||
|
|
cd444e82f9 | ||
|
|
9d924bb6d7 | ||
|
|
995a20a125 | ||
|
|
677a317274 | ||
|
|
1ba07a9d6d | ||
|
|
a4f94b89b4 | ||
|
|
5e2f36387f | ||
|
|
4a41311409 | ||
|
|
6ac0151e65 | ||
|
|
fe0ec67623 | ||
|
|
19fd841c30 | ||
|
|
566b0676bc | ||
|
|
daea448b61 | ||
|
|
7929daa48c | ||
|
|
f3af1dbd54 | ||
|
|
1c9fe8d23e | ||
|
|
52888c97b5 | ||
|
|
5010150c8c | ||
|
|
0d4f1abdf9 | ||
|
|
b866b34ac8 | ||
|
|
fca91db133 | ||
|
|
c489d6d4b3 | ||
|
|
1b9bced8c0 | ||
|
|
f68d0f324f | ||
|
|
de27b34891 | ||
|
|
1d61f987cb | ||
|
|
fd5f120434 | ||
|
|
09de0c2766 | ||
|
|
ac6e4aff5e | ||
|
|
13b4c8bb06 | ||
|
|
7aaf974362 | ||
|
|
8f7a04f9c3 | ||
|
|
62cad610e0 | ||
|
|
4c531e909b | ||
|
|
b52b6e12c4 | ||
|
|
48b161f210 | ||
|
|
06da5d543c | ||
|
|
5267d734bb | ||
|
|
3db2daf790 | ||
|
|
9d02292dec | ||
|
|
77eb0e8e3f | ||
|
|
6f3d0e1782 | ||
|
|
6c8ffcf7a0 | ||
|
|
363ab2075c | ||
|
|
c9b314d43c | ||
|
|
0e63050916 | ||
|
|
8821cae34f | ||
|
|
f16f48aa7c | ||
|
|
e1d9229507 | ||
|
|
588420ecd2 | ||
|
|
d56c36b4a7 | ||
|
|
d983eb42e6 | ||
|
|
f52cd31d0d | ||
|
|
f266b979af | ||
|
|
8b9d189671 | ||
|
|
3182485e68 | ||
|
|
a93c9462ed | ||
|
|
b33c04d041 | ||
|
|
d26480b74e | ||
|
|
ea2807c890 | ||
|
|
0059e7bcf9 | ||
|
|
9e26e5c121 | ||
|
|
67d9ae27c3 | ||
|
|
adfd99f5f0 | ||
|
|
9196a9f334 | ||
|
|
7d93642f42 | ||
|
|
7c34d8333c | ||
|
|
d5f3e5d59a | ||
|
|
8ac93e02c6 | ||
|
|
4193fb1742 | ||
|
|
844f9e989b | ||
|
|
d6dffc570c | ||
|
|
4a075866de | ||
|
|
cc7395eea8 | ||
|
|
b09c81202a | ||
|
|
4754e4aabb | ||
|
|
fef2f789cd | ||
|
|
1a27ecdad4 | ||
|
|
2bade868bb | ||
|
|
836e2e4e91 | ||
|
|
a2b6731bf2 | ||
|
|
983d611e96 | ||
|
|
0bd3e28a05 | ||
|
|
480f0fbfd7 | ||
|
|
590c2bcf23 | ||
|
|
8fd9957453 | ||
|
|
e488320d37 | ||
|
|
195e0e64d0 | ||
|
|
17528a4dfd | ||
|
|
53d0db0a28 | ||
|
|
d6ab81c1da | ||
|
|
3ee9eef308 | ||
|
|
9cbcd228f3 | ||
|
|
e1bf0ea2b4 | ||
|
|
5c8ecd8a97 | ||
|
|
2b7c3735bd | ||
|
|
f8c1db160e | ||
|
|
e609a5bee2 | ||
|
|
eaacbc86c7 | ||
|
|
4702d8b640 | ||
|
|
359123458d | ||
|
|
d8c05ecc0d | ||
|
|
f441ba2694 | ||
|
|
5d906c0e4e | ||
|
|
a361d50b95 | ||
|
|
18b2094198 | ||
|
|
1032287511 | ||
|
|
d3beaa0b16 | ||
|
|
046cb0df8d | ||
|
|
97d903bca3 | ||
|
|
0456be1535 | ||
|
|
161bd89a24 | ||
|
|
5f9976c46a | ||
|
|
872c6ea763 | ||
|
|
e995befcd0 | ||
|
|
d49302858b | ||
|
|
d3e0c08255 | ||
|
|
06e3e65c1b | ||
|
|
962ce6c44c | ||
|
|
e05f795d1d | ||
|
|
906948218f | ||
|
|
deddf98533 | ||
|
|
d7fdb16078 | ||
|
|
d2a567d6ab | ||
|
|
3d0b98c9ca | ||
|
|
68cf267b1d | ||
|
|
240c346d02 | ||
|
|
97250b53e8 | ||
|
|
49cca0978d | ||
|
|
87c10b3ac2 | ||
|
|
5f6c468f0f | ||
|
|
dc9b3fcef7 | ||
|
|
d6cb84f8a3 | ||
|
|
998ce73ad9 | ||
|
|
8a061b7183 | ||
|
|
118afab67b | ||
|
|
7fd3149031 | ||
|
|
242508e22f | ||
|
|
5368da18ad | ||
|
|
467ccabb7e | ||
|
|
397d0e34ee | ||
|
|
27da0f3338 | ||
|
|
c7f5210b50 | ||
|
|
7bd11c14f6 | ||
|
|
cee31ff67a | ||
|
|
9266f9abfc | ||
|
|
f95c46d987 | ||
|
|
866260a2a6 | ||
|
|
bfb75df49c | ||
|
|
b301c473cd | ||
|
|
3f3871b1be | ||
|
|
2043356fa3 | ||
|
|
13cfc2d2a0 | ||
|
|
8d0c5c30b8 | ||
|
|
0b4b79d0a4 | ||
|
|
7db2601ea8 | ||
|
|
77b074fbad | ||
|
|
dc86ec8ddd | ||
|
|
189380d4ea | ||
|
|
bfb4867e10 | ||
|
|
1623622073 | ||
|
|
ae2eec3efa | ||
|
|
b51be9b83f | ||
|
|
60bc2acd6c | ||
|
|
cd7bc0e50c | ||
|
|
75362450cd | ||
|
|
191b054ff0 | ||
|
|
f4538daa0a | ||
|
|
a7ac7ba4c1 | ||
|
|
7e09b1664a | ||
|
|
ee9e28dfdf | ||
|
|
fb6f5320e7 | ||
|
|
7ce87c470a | ||
|
|
90f52169af | ||
|
|
0140015500 | ||
|
|
c1399f9bdc | ||
|
|
3fedea4b9e | ||
|
|
13bfb099a2 | ||
|
|
f53aabaef5 | ||
|
|
ecbb088ea6 | ||
|
|
f5442a4888 | ||
|
|
57f082055a | ||
|
|
e53bfad018 | ||
|
|
0d3d097ce8 | ||
|
|
2317b56ac4 | ||
|
|
16c870191f | ||
|
|
54c654530e | ||
|
|
6217d497ed | ||
|
|
84cce6c2c1 | ||
|
|
40c531737d | ||
|
|
88f3c34412 | ||
|
|
fd9c9c3be7 | ||
|
|
236810a923 | ||
|
|
88dc73ec3f | ||
|
|
195a4bb3c1 | ||
|
|
c540721bd3 | ||
|
|
c11d18fe06 | ||
|
|
8ed3659bb8 | ||
|
|
ba7a32b16e | ||
|
|
800ab50b56 | ||
|
|
f43b9665c1 | ||
|
|
14906eb6c8 | ||
|
|
c53e47265d | ||
|
|
5986a302d1 | ||
|
|
f5acc8b599 | ||
|
|
e5af03547f | ||
|
|
861a79dd6a | ||
|
|
5fe270a78f | ||
|
|
b1275420a3 | ||
|
|
fb161d5f1f | ||
|
|
6ac24f592c | ||
|
|
88d158f2c1 | ||
|
|
e5036c0988 | ||
|
|
0b5efcbc75 | ||
|
|
0785c3bd15 | ||
|
|
5dc88aa543 | ||
|
|
5ec2e8d7e5 | ||
|
|
3214fdd73f | ||
|
|
d3e359ab2d | ||
|
|
c740438032 | ||
|
|
7459581d13 | ||
|
|
03052e81c1 | ||
|
|
1bac1a9028 | ||
|
|
de08473ea3 | ||
|
|
2d46f6f66f | ||
|
|
2287ad6d37 | ||
|
|
2234307d41 | ||
|
|
652913f8d6 | ||
|
|
19cba3ff85 | ||
|
|
6f0057532a | ||
|
|
908084c0fd | ||
|
|
d83c36e0fd | ||
|
|
22a3765394 | ||
|
|
61e775c055 | ||
|
|
bebf8eabca | ||
|
|
847d9580b7 | ||
|
|
faf896db67 | ||
|
|
10f144069d | ||
|
|
29b799de73 | ||
|
|
525d456f7c | ||
|
|
f1142cf2b5 | ||
|
|
08779eb6d9 | ||
|
|
2d7b5c53b1 | ||
|
|
8dc8f8f485 | ||
|
|
4a409b870e | ||
|
|
bb5b30b8a0 | ||
|
|
906ae043f9 | ||
|
|
0ad03d9ff7 | ||
|
|
3aaff23f78 | ||
|
|
e77582baee | ||
|
|
2497c73009 | ||
|
|
73223fe5c3 | ||
|
|
9c0f298064 | ||
|
|
525e3ee9c6 | ||
|
|
9ccb495f60 | ||
|
|
35d9e37220 | ||
|
|
e8c4fb6903 | ||
|
|
a9652052c4 | ||
|
|
a52dbf0784 | ||
|
|
900001e547 | ||
|
|
37ccd34a88 | ||
|
|
f93fa53aea | ||
|
|
0253aec0cd | ||
|
|
ce7c1023d5 | ||
|
|
02d72c81af | ||
|
|
22863b9f31 | ||
|
|
48e62ac0b5 | ||
|
|
732936713a | ||
|
|
f418ac5b5d | ||
|
|
d889bdef49 | ||
|
|
c04353a845 | ||
|
|
ff91aeb5d4 | ||
|
|
8a2aebd03f | ||
|
|
82f3bb26ce | ||
|
|
2da39d31aa | ||
|
|
5fda9bc6ae | ||
|
|
93e9cf4ac1 | ||
|
|
dc7928021d | ||
|
|
b78fe04f8f | ||
|
|
8d4ed037a2 | ||
|
|
57b0f288cb | ||
|
|
ceea7adf98 | ||
|
|
751ebe7377 | ||
|
|
c59f38c370 | ||
|
|
9a72afc963 | ||
|
|
b9b6e8aa68 | ||
|
|
b32bc8cf3e | ||
|
|
01dcee6449 | ||
|
|
83e3d059b4 | ||
|
|
eef9d9beaf | ||
|
|
f86bd75f82 | ||
|
|
9a35d54ecf | ||
|
|
989dfe01e1 | ||
|
|
b81742f335 | ||
|
|
5a702425eb | ||
|
|
f6d4af8882 | ||
|
|
2d19d8108b | ||
|
|
c29b844a97 | ||
|
|
64718888dd | ||
|
|
064af6ecb2 | ||
|
|
959f7a1911 | ||
|
|
ff3104b44b | ||
|
|
12d40cd310 | ||
|
|
759a46f3d6 | ||
|
|
6578c4f0b3 | ||
|
|
b2d83fd8a8 | ||
|
|
a32f50ef64 | ||
|
|
1b2b7fc4ce | ||
|
|
49ac160ff7 | ||
|
|
a077355d70 | ||
|
|
ffa5abe99b | ||
|
|
9200e32b0e | ||
|
|
04d59991b0 | ||
|
|
c708ae8eb5 | ||
|
|
ea93553225 | ||
|
|
e6c0b1fe0c | ||
|
|
79c1ad85f9 | ||
|
|
7f2a46cdd5 | ||
|
|
2cd41b2f84 | ||
|
|
0f52a6da39 | ||
|
|
71704fc5d8 | ||
|
|
e5890728dc | ||
|
|
08d2320ad6 | ||
|
|
95c9e48822 | ||
|
|
8bb097e0a4 | ||
|
|
01c483e0dd | ||
|
|
4cdba29fbd | ||
|
|
ed70a11ff8 | ||
|
|
8dd5f58161 | ||
|
|
1d6f05c9bb | ||
|
|
d0b39bc4fe | ||
|
|
dec971a889 | ||
|
|
0dad2581ef | ||
|
|
b54af73782 | ||
|
|
6dae07b76f | ||
|
|
ebc7f5cba0 | ||
|
|
c4d34eb465 | ||
|
|
5146befa46 | ||
|
|
885aeec442 | ||
|
|
f1b184ef78 | ||
|
|
139a4f984a | ||
|
|
6e0112bf9f | ||
|
|
552102b88d | ||
|
|
4d7296e1db | ||
|
|
61bf3ae1ee | ||
|
|
5787bb0226 | ||
|
|
8e48fde5ac | ||
|
|
3cc2dd216f | ||
|
|
cd3d154cc3 | ||
|
|
6bad16377d | ||
|
|
3014e61792 | ||
|
|
12e62746b3 | ||
|
|
61ec3acde9 | ||
|
|
8e7a5adc60 | ||
|
|
4dc431043f | ||
|
|
566bb1f708 | ||
|
|
ab3122ef2a | ||
|
|
c40fb67890 | ||
|
|
797b0ddb9a | ||
|
|
e139012f9a | ||
|
|
60d7dd991d | ||
|
|
897d376978 | ||
|
|
ad4450ec88 | ||
|
|
fe5dc5d28e | ||
|
|
af0afecb45 | ||
|
|
6b79f53416 | ||
|
|
ac905e7080 | ||
|
|
70dac71639 | ||
|
|
4841e37502 | ||
|
|
c682ccd9d0 | ||
|
|
b358dff689 | ||
|
|
e24ce97731 | ||
|
|
1dcbd352cc | ||
|
|
85f700f458 | ||
|
|
3fcb4be303 | ||
|
|
9c71c9fa6a | ||
|
|
0f2ae385ed | ||
|
|
1ff33b7c81 | ||
|
|
19d5d3b7d1 | ||
|
|
91220f2a98 | ||
|
|
f3e633eb2c | ||
|
|
6708e2a302 | ||
|
|
b6fd4fed38 | ||
|
|
02e8e929e1 | ||
|
|
b05fa2ed5b | ||
|
|
e46a50512d | ||
|
|
8f4b6afa64 | ||
|
|
e6f4dd0f85 | ||
|
|
767c235708 | ||
|
|
bc8689889d | ||
|
|
bb32039fde | ||
|
|
53ac79cb19 | ||
|
|
081c8e1f28 | ||
|
|
6861d645ad | ||
|
|
ef459c7676 | ||
|
|
28f1aef7b4 | ||
|
|
fd432ddbc9 | ||
|
|
446da677b5 | ||
|
|
7685380105 | ||
|
|
56cd57872c | ||
|
|
f2d8eadf4e | ||
|
|
14661819c2 | ||
|
|
609f5dcaaf | ||
|
|
4d6b95aa52 | ||
|
|
0eefb282ca | ||
|
|
722a07de86 | ||
|
|
30b60516fe | ||
|
|
814ae7b4a4 | ||
|
|
d627ead273 | ||
|
|
16d4c436cb | ||
|
|
7ad86a12b4 | ||
|
|
58473f41ab | ||
|
|
4cb620c195 | ||
|
|
bea232f53a | ||
|
|
ef801d5543 | ||
|
|
1e140fb32c | ||
|
|
2ce4237083 | ||
|
|
dafa14fe42 | ||
|
|
bf91410a22 | ||
|
|
d988cae16d | ||
|
|
a6cf7a1095 | ||
|
|
6f0471f6cb | ||
|
|
0342db9328 | ||
|
|
dae68be2ce | ||
|
|
0cf50b1c0b | ||
|
|
7cca287b60 | ||
|
|
476aea5a3f | ||
|
|
f84b5a7642 | ||
|
|
9a56974c83 | ||
|
|
0e8636cb2a | ||
|
|
f58b3f853e | ||
|
|
c18880bd77 | ||
|
|
7b83d920fa | ||
|
|
df397dab30 | ||
|
|
4ce26dfa68 | ||
|
|
16bfc19547 | ||
|
|
a4405dad45 | ||
|
|
aa516ae01a | ||
|
|
69c4c7e3be | ||
|
|
45b3bd3a22 | ||
|
|
edfb1b5d0e | ||
|
|
969a30fc3b | ||
|
|
636570306a | ||
|
|
2c31d7c1e8 | ||
|
|
c9c4ba39ab | ||
|
|
2f9fee0c8a | ||
|
|
60bd60e1ed | ||
|
|
8e1d2479ac | ||
|
|
7268f434b2 | ||
|
|
3f2a25d07c | ||
|
|
f10ab71f60 | ||
|
|
4b42fe1b24 | ||
|
|
0901a70166 | ||
|
|
b2fb95f857 | ||
|
|
55babea2bb | ||
|
|
3271492c86 | ||
|
|
afe0296e0f | ||
|
|
5a9f28e034 | ||
|
|
178496afe5 | ||
|
|
2b079588bb | ||
|
|
a6f2d401fa | ||
|
|
6fba72a40c | ||
|
|
fe73688975 | ||
|
|
ef561fb919 | ||
|
|
9483cd351a | ||
|
|
28d12166fd | ||
|
|
7074789011 | ||
|
|
5e73b0372d | ||
|
|
540076e9d5 | ||
|
|
8957ba5222 | ||
|
|
4c1a0d29b0 | ||
|
|
7b207aa1b6 | ||
|
|
9fcafc6f9e | ||
|
|
8be2239a45 | ||
|
|
d63d570327 | ||
|
|
12764a66ed | ||
|
|
42768bcc2b | ||
|
|
81eb3e3428 | ||
|
|
0fffbea79d | ||
|
|
ebd8d30f25 | ||
|
|
a5a2e20449 | ||
|
|
03d25ce6c0 | ||
|
|
f84a973d69 | ||
|
|
2606f8020a | ||
|
|
e9c9e22a9e | ||
|
|
513b07b3b3 | ||
|
|
b15c07e1a8 | ||
|
|
0e7de568a2 | ||
|
|
f984536523 | ||
|
|
67a768fc77 | ||
|
|
49eed1ebb9 | ||
|
|
0567f09d6d | ||
|
|
90cc10944a | ||
|
|
2295f3a832 | ||
|
|
b53480e15c | ||
|
|
dbe36748d4 | ||
|
|
be32039cf9 | ||
|
|
543211b53a | ||
|
|
fecd9ee4a0 | ||
|
|
e39d5a9eb9 | ||
|
|
ac3a704abc | ||
|
|
34b4ebd9f3 | ||
|
|
098d72b741 | ||
|
|
26e4ce30bb | ||
|
|
7cbe6bc8bd | ||
|
|
bd70d9008f | ||
|
|
ad09196433 | ||
|
|
cc24bea813 | ||
|
|
459a65d296 | ||
|
|
64abae0b3c | ||
|
|
26c0ad1c2f | ||
|
|
a83b891a95 | ||
|
|
51f095e5c3 | ||
|
|
a60bb9031a | ||
|
|
f1edd88e56 | ||
|
|
c48598a5bc | ||
|
|
6cb8f278a2 | ||
|
|
91911d2d32 | ||
|
|
abb60ecd2e | ||
|
|
586e5e2ba5 | ||
|
|
b2e77b2e6b | ||
|
|
21ae288ee7 | ||
|
|
05493502ea | ||
|
|
33aecb9978 | ||
|
|
a554f9e683 | ||
|
|
6fda14ce88 | ||
|
|
f426c9c951 | ||
|
|
bde412dd69 | ||
|
|
03ce8a195a | ||
|
|
47f7f7b02e | ||
|
|
d91cd424fe | ||
|
|
5766f4703a | ||
|
|
f65f8918c9 | ||
|
|
33370b18b3 | ||
|
|
dae63ec4f1 | ||
|
|
214eb0430c | ||
|
|
2a55d93501 | ||
|
|
b68a25835f | ||
|
|
3dcf69eab3 | ||
|
|
8aa88067ca | ||
|
|
6756f8c7af | ||
|
|
cea1b49db0 | ||
|
|
195940292d | ||
|
|
88805ec7e2 | ||
|
|
fe3c78ad84 | ||
|
|
47a2a3a13f | ||
|
|
b693ced765 | ||
|
|
9f99ba3b73 | ||
|
|
3a9a1d35d7 | ||
|
|
c20acb0361 | ||
|
|
6df4bb176d | ||
|
|
92606579d3 | ||
|
|
1bbc6211ca | ||
|
|
0c9c1229e3 | ||
|
|
95476a81ae | ||
|
|
2f71d6afe0 | ||
|
|
e9514bf35d | ||
|
|
edb73fb734 | ||
|
|
cb45c94db9 | ||
|
|
66853344c0 | ||
|
|
83af5de572 | ||
|
|
f7d4ff90ea | ||
|
|
4001f10e2d | ||
|
|
c2833274bf | ||
|
|
9f82620bb0 | ||
|
|
b0dc7ff841 | ||
|
|
80bece5640 | ||
|
|
5995e3f400 | ||
|
|
3e4ecd6d6e | ||
|
|
6979ea7fda | ||
|
|
068909dc03 | ||
|
|
dd337640f5 | ||
|
|
c6edab0950 | ||
|
|
7e9d790070 | ||
|
|
54aa458ba4 | ||
|
|
09b036f07b | ||
|
|
340b7220f1 | ||
|
|
1bac04c69d | ||
|
|
850bc2d443 | ||
|
|
d64e3784f4 | ||
|
|
68192785e7 | ||
|
|
d9db23185c | ||
|
|
122652a368 | ||
|
|
77573281b5 | ||
|
|
4e6b148eaa | ||
|
|
df2141d9e6 | ||
|
|
6dbd2ce243 | ||
|
|
bfae925b0f | ||
|
|
46208b5b3e | ||
|
|
0fa92923da | ||
|
|
4435cdc576 | ||
|
|
302a6e42bd | ||
|
|
f3c3042deb | ||
|
|
7b8a05f01f | ||
|
|
32c93f713a | ||
|
|
4080442f80 | ||
|
|
b1c0e7e2ab | ||
|
|
21af03d71a | ||
|
|
cdb4444caa | ||
|
|
76a954077d | ||
|
|
4f21a50d23 | ||
|
|
d9778413e1 | ||
|
|
06cf0406fe | ||
|
|
570dc7ca9b | ||
|
|
f081c77422 | ||
|
|
f3a9d3eed7 | ||
|
|
315cd9d2c8 | ||
|
|
db91adc2e8 | ||
|
|
a0c14eed04 | ||
|
|
63d0704490 | ||
|
|
64db17dde7 | ||
|
|
d02125bde5 | ||
|
|
62d00163a8 | ||
|
|
b5d2e51100 | ||
|
|
11653aa9c8 | ||
|
|
067e9c1a85 | ||
|
|
a421c66f3f | ||
|
|
9557226223 | ||
|
|
ddd8eae661 | ||
|
|
d72a0e452f | ||
|
|
13f8599ba1 | ||
|
|
60b9ff3948 | ||
|
|
9fe3dbcfe0 | ||
|
|
272592415d | ||
|
|
993695af07 | ||
|
|
60d2cb8a84 | ||
|
|
2ae52d0ff4 | ||
|
|
a8f08e1fab | ||
|
|
096b948570 | ||
|
|
c7f338a5ef | ||
|
|
c7754e712d | ||
|
|
2f06a2af81 | ||
|
|
e1516d4244 | ||
|
|
778d18a510 | ||
|
|
dfd1a46956 | ||
|
|
28381757d5 | ||
|
|
799fd13c50 | ||
|
|
2c8261b429 | ||
|
|
0527b17e42 | ||
|
|
ee190ca62a | ||
|
|
a4de40ec89 | ||
|
|
08e18d46ea | ||
|
|
6205dfa25f | ||
|
|
a14014941b | ||
|
|
ba9fa95653 | ||
|
|
66f4701d93 | ||
|
|
b6f8dcea20 | ||
|
|
7fa4b7c8b5 | ||
|
|
b862cee6ec | ||
|
|
741f8091b4 | ||
|
|
cbc2a869e3 | ||
|
|
c72bb6df33 | ||
|
|
4f4277e25e | ||
|
|
0282180b9c | ||
|
|
08dbd35ced | ||
|
|
552609db73 | ||
|
|
57115a447c | ||
|
|
d125483c13 | ||
|
|
da727a3c1b | ||
|
|
c04d43ca13 | ||
|
|
394ffa88dd | ||
|
|
c0f63eed4e | ||
|
|
bb2cab2858 | ||
|
|
b45f683655 | ||
|
|
8e7bf1051d | ||
|
|
e4bd592e0e | ||
|
|
67f672541c | ||
|
|
c92e622ce0 | ||
|
|
2a2a8d3263 | ||
|
|
b30143c67d | ||
|
|
df97be30e5 | ||
|
|
1c75baa8b3 | ||
|
|
0900762507 | ||
|
|
30d37fcba4 | ||
|
|
ec832f418a | ||
|
|
a836ee4ea7 | ||
|
|
b5c1db9ad9 | ||
|
|
ca756c3c24 | ||
|
|
aa29dc0c8a | ||
|
|
720fbc1003 | ||
|
|
dc8fc7c079 | ||
|
|
823c4f91a8 | ||
|
|
809135f657 | ||
|
|
47ec7dcaa0 | ||
|
|
3fdcbcef03 | ||
|
|
965c3f605e | ||
|
|
680652d01c | ||
|
|
ff1b7d18f6 | ||
|
|
d3e879cd7f | ||
|
|
d7a391dc61 | ||
|
|
d3bff7fffc | ||
|
|
a3e8591a41 | ||
|
|
794d120754 | ||
|
|
bdde5fd7ad | ||
|
|
57bdbd8185 | ||
|
|
16b54e1502 | ||
|
|
7468118df5 | ||
|
|
942971b01a | ||
|
|
652110707e | ||
|
|
b80272dbb4 | ||
|
|
5b7637687c | ||
|
|
b2a3aabc90 | ||
|
|
18f5fcde60 | ||
|
|
eb9e0e5534 | ||
|
|
8ca1a6961c | ||
|
|
37e500dc10 | ||
|
|
873e9c44db | ||
|
|
5e9fe1c6eb | ||
|
|
02c8c58c0b | ||
|
|
8f04dd1b9c | ||
|
|
838cf0ffdc | ||
|
|
58dfad4d01 | ||
|
|
34ee29871b | ||
|
|
fd6747483a | ||
|
|
bd406ab046 | ||
|
|
2d8286515d | ||
|
|
414245f4d8 | ||
|
|
8f89cd2d59 | ||
|
|
ddf962c6ea | ||
|
|
591f8fed88 | ||
|
|
fcad4ee186 | ||
|
|
916114dd28 | ||
|
|
ace235b2fe | ||
|
|
c3200ba7f6 | ||
|
|
1c87acbb75 | ||
|
|
5c75fbe369 | ||
|
|
64a84dee3b | ||
|
|
3a9bbe30ac | ||
|
|
2c0494dcef | ||
|
|
919be67cd2 | ||
|
|
2ddac9352f | ||
|
|
5a9b86dd05 | ||
|
|
1240c83e40 | ||
|
|
142300aeb9 | ||
|
|
eeccd90455 | ||
|
|
a8032e8fef | ||
|
|
b8e04f4947 | ||
|
|
12483486c0 | ||
|
|
34319abf4a | ||
|
|
e81cec4058 | ||
|
|
fcf04377d7 | ||
|
|
0bf1e56156 | ||
|
|
c8e77f47ab | ||
|
|
d512421084 | ||
|
|
1976c271ec | ||
|
|
65c37fe64b | ||
|
|
c87c49f4c8 | ||
|
|
8d08c3241d | ||
|
|
16de30dd04 | ||
|
|
522d592832 | ||
|
|
2414096560 | ||
|
|
cb947873c4 | ||
|
|
44bc24174c | ||
|
|
9574f79d0f | ||
|
|
132ac20ccf | ||
|
|
7d788cfa7a | ||
|
|
aefb672393 | ||
|
|
059ca01767 | ||
|
|
38f0088844 | ||
|
|
07346ae858 | ||
|
|
4dd2716865 | ||
|
|
1985e1b8e0 | ||
|
|
075da45b74 | ||
|
|
7d96f3d720 | ||
|
|
a5b93211e6 | ||
|
|
7b56085a0a | ||
|
|
4708477f5a | ||
|
|
95a53fc832 | ||
|
|
b8e64ac40e | ||
|
|
b84a178ceb | ||
|
|
64d37065bd | ||
|
|
7501a02b34 | ||
|
|
54545a8a6e | ||
|
|
11ba1832d1 | ||
|
|
9e85cb4c11 | ||
|
|
7d4e0629d6 | ||
|
|
ae0d007c5e | ||
|
|
b9ad09db91 | ||
|
|
47cc390e41 | ||
|
|
7787dee638 | ||
|
|
cb2343c69e | ||
|
|
31eb793fb0 | ||
|
|
3c6e933231 | ||
|
|
8f0e594007 | ||
|
|
43c44da50b | ||
|
|
07a4c52919 | ||
|
|
c3ac92b500 | ||
|
|
07572965df | ||
|
|
65c612a66d | ||
|
|
0a39449694 | ||
|
|
92882c358a | ||
|
|
49d25693ee | ||
|
|
3780d9f033 | ||
|
|
de51f2c1ba | ||
|
|
99a9aa085e | ||
|
|
1379e4f2dc | ||
|
|
313883b1fc | ||
|
|
2fbe06a2a5 | ||
|
|
c9a3fc4317 | ||
|
|
17446f4284 | ||
|
|
bb70defcb8 | ||
|
|
5efa075aca | ||
|
|
d6b4c2a842 | ||
|
|
41e771d011 | ||
|
|
337d105104 | ||
|
|
d3fb123920 | ||
|
|
a07612c1ed | ||
|
|
a2f7458e07 | ||
|
|
5659ee5c0b | ||
|
|
056aaa2a62 | ||
|
|
107d759ea2 | ||
|
|
796f6614f7 | ||
|
|
726d0d6b60 | ||
|
|
a048bddaa5 | ||
|
|
c1f64b3f85 | ||
|
|
3c44dfa210 | ||
|
|
1fe97ddf2e | ||
|
|
0a80618263 | ||
|
|
fca3a5f853 | ||
|
|
1a842bf9d5 | ||
|
|
50f51899de | ||
|
|
15b042b5f6 | ||
|
|
c1b1348735 | ||
|
|
732697a8a2 | ||
|
|
066092abb6 | ||
|
|
37119768a0 | ||
|
|
3fb39ad3ef | ||
|
|
00ff209fe7 | ||
|
|
46365f4076 | ||
|
|
5ff97317fe | ||
|
|
d169ebf737 | ||
|
|
2f6796bd7f | ||
|
|
d156846036 | ||
|
|
d703a87317 | ||
|
|
4fc35a4587 | ||
|
|
f403950503 | ||
|
|
f20950702d | ||
|
|
1a3ede6ca5 | ||
|
|
4041d52864 | ||
|
|
10860e4ec5 | ||
|
|
687a512b11 | ||
|
|
e95224deab | ||
|
|
a74b9607b6 | ||
|
|
0fad8fdc4b | ||
|
|
7e87973d60 | ||
|
|
d3308cf8c3 | ||
|
|
348a0e958b | ||
|
|
4d8d4d5f2a | ||
|
|
193c6d6e93 | ||
|
|
49b82decd8 | ||
|
|
8d8d5878a3 | ||
|
|
79ba8feaf8 | ||
|
|
577480421d | ||
|
|
59991f2fd8 | ||
|
|
a79c63581d | ||
|
|
cf2a17cf88 | ||
|
|
82856eb099 | ||
|
|
7d3f8cb222 | ||
|
|
efb0fc2ea5 | ||
|
|
aae83cbce8 | ||
|
|
adb112e970 | ||
|
|
bcb4ba6f99 | ||
|
|
cb47dfa90e | ||
|
|
71b67534a8 | ||
|
|
3ee366257c | ||
|
|
d171cfe8d0 | ||
|
|
548febfa4c | ||
|
|
e0ee60f290 | ||
|
|
91457fe739 | ||
|
|
f9644463a9 | ||
|
|
80f66031cb | ||
|
|
fb299c7fcb | ||
|
|
55b8e9aa44 | ||
|
|
b4885b9a37 | ||
|
|
6e7aa6d299 | ||
|
|
c474ad0913 | ||
|
|
5dfc64120f | ||
|
|
b48788af43 | ||
|
|
dd283ff8d7 | ||
|
|
7796dbb7ce | ||
|
|
c562b24df8 | ||
|
|
884c9cc2f5 | ||
|
|
f12f87d6f0 | ||
|
|
fa27120429 | ||
|
|
c2bcf8cbde | ||
|
|
b553981644 | ||
|
|
fc84c952f2 | ||
|
|
102f7e8e33 | ||
|
|
5ffa30a563 | ||
|
|
492a7d0ffe | ||
|
|
6e9c27fdaa | ||
|
|
fdb138f79c | ||
|
|
d62d8bbf0a | ||
|
|
39a20ea4fb | ||
|
|
442ccbe204 | ||
|
|
a9ea8b92f0 | ||
|
|
eb82f7cea9 | ||
|
|
165009681b | ||
|
|
a6f19c4292 | ||
|
|
769ba02b2a | ||
|
|
491bf30a15 | ||
|
|
f94661547c | ||
|
|
4a724e91e0 | ||
|
|
e5aa712bf3 | ||
|
|
9828875ebc | ||
|
|
8c3ff97ba4 | ||
|
|
8bc95fe279 | ||
|
|
a66565fd3f | ||
|
|
19a172f2f5 | ||
|
|
1980d85f3e | ||
|
|
cb470cb94b | ||
|
|
70ca49e36a | ||
|
|
7bfe80f835 | ||
|
|
527ff66115 | ||
|
|
3695e38719 | ||
|
|
7734f6af62 | ||
|
|
909ed54bef | ||
|
|
230ed78dd6 | ||
|
|
ef2a28ca86 | ||
|
|
55b12c184b | ||
|
|
eafe9c245b | ||
|
|
fd12e1f506 | ||
|
|
4890734f66 | ||
|
|
e5164d2255 | ||
|
|
dbe1c1d4e4 | ||
|
|
9e66df23d0 | ||
|
|
d7b1792503 | ||
|
|
2713580d09 | ||
|
|
463e077c3a | ||
|
|
777704e659 | ||
|
|
afdad927b7 | ||
|
|
3c96d7b726 | ||
|
|
ee9128268e | ||
|
|
ce95747a25 | ||
|
|
c036986cc4 | ||
|
|
ef08138a8d | ||
|
|
2853356b10 | ||
|
|
b92e86301a | ||
|
|
ac419038c6 | ||
|
|
400efa1b7d | ||
|
|
b2ad0a05d7 | ||
|
|
5221154653 | ||
|
|
464dad3135 | ||
|
|
ff7bb1e6cb | ||
|
|
4b9b630e80 | ||
|
|
b35f4c1805 | ||
|
|
247b3f3605 | ||
|
|
576b54320a | ||
|
|
6f7a98d7c9 | ||
|
|
39d2b95a33 | ||
|
|
b9ead472a5 | ||
|
|
4ebb01f8c9 | ||
|
|
f36851fcff | ||
|
|
0416e65b8b | ||
|
|
e14c91771b | ||
|
|
7e366dd5c8 | ||
|
|
e0fe478ae7 | ||
|
|
7016fbe258 | ||
|
|
7353fb4296 | ||
|
|
7023528042 | ||
|
|
1eddaecef8 | ||
|
|
389b2b5cdd | ||
|
|
f87e417f7f | ||
|
|
9e2dd13f9a | ||
|
|
ccbbf35696 | ||
|
|
ae5a6e61c5 | ||
|
|
f033f259b4 | ||
|
|
daa09ea9e7 | ||
|
|
6e46753499 | ||
|
|
293ca4ef55 | ||
|
|
07fc0880fb | ||
|
|
303290bfb4 | ||
|
|
e23faceba0 | ||
|
|
d4a14bc215 | ||
|
|
996ad10344 | ||
|
|
546ad643e4 | ||
|
|
a648528f43 | ||
|
|
346ef9df0c | ||
|
|
f7e5c65802 | ||
|
|
cfd2cdb9c4 | ||
|
|
72878d0de6 | ||
|
|
be5e787edf | ||
|
|
c220753c60 | ||
|
|
0e3737423b | ||
|
|
c307478d5d | ||
|
|
afb82fcc1f | ||
|
|
252121ac70 | ||
|
|
9efd29d059 | ||
|
|
d5e8bb7f12 | ||
|
|
7c58f7fb02 | ||
|
|
aadc0bee25 | ||
|
|
0d11b755db | ||
|
|
afbc914f8b | ||
|
|
47a61e9f27 | ||
|
|
6425ef4261 | ||
|
|
b5afad9da7 | ||
|
|
1a18151eff | ||
|
|
0fd0887407 | ||
|
|
71f8ba6f7a | ||
|
|
e156faea5c | ||
|
|
6f845373a7 | ||
|
|
98b4353ef8 | ||
|
|
42e7ee2b4a | ||
|
|
4e2f1311e0 | ||
|
|
2c3cacdc08 | ||
|
|
e6698102c9 | ||
|
|
cfdfdc8ccc | ||
|
|
fd0f9519f1 | ||
|
|
14fb3c4598 | ||
|
|
c5f70c8d99 | ||
|
|
5e4696f4a7 | ||
|
|
9db733a4ff | ||
|
|
c4b6cf4a8e | ||
|
|
f47fa25e39 | ||
|
|
68510cbe49 | ||
|
|
3a55f0d1f7 | ||
|
|
09635ae50e | ||
|
|
67d189474c | ||
|
|
2fb92076b6 | ||
|
|
7404b848a2 | ||
|
|
f35f362272 | ||
|
|
06b556c34c | ||
|
|
bd9b0b8ed3 | ||
|
|
3855a774ab | ||
|
|
67fa250020 | ||
|
|
c845ea8372 | ||
|
|
80f7c82f93 | ||
|
|
f61010df96 | ||
|
|
ca7b492b97 | ||
|
|
ee181294b3 | ||
|
|
4d4f479721 | ||
|
|
4794385fac | ||
|
|
f25c3d33b6 | ||
|
|
6e31e51292 | ||
|
|
dd23b09569 | ||
|
|
8bcede8019 | ||
|
|
4ac08870d0 | ||
|
|
ad67070f23 | ||
|
|
839ab07fd4 | ||
|
|
c4a2329665 | ||
|
|
edbb2b4a26 | ||
|
|
7dbf07edfc | ||
|
|
ff2d005058 | ||
|
|
1231360b2f | ||
|
|
664f59a8eb | ||
|
|
534fa7073e | ||
|
|
116aa2f483 | ||
|
|
48cea8aa35 | ||
|
|
ab685ac335 | ||
|
|
73201e419d | ||
|
|
4ebd24d128 | ||
|
|
a4d2dd9b4d | ||
|
|
e401335ebb | ||
|
|
e5886dda9b | ||
|
|
896ea7b79d | ||
|
|
70f9cb098f | ||
|
|
d83cb53997 | ||
|
|
f23729acdb | ||
|
|
2ffe891cc8 | ||
|
|
5a3552f577 | ||
|
|
75f0942057 | ||
|
|
247a63efe3 | ||
|
|
c4128e6b4b | ||
|
|
a3f30ca822 | ||
|
|
19931397ac | ||
|
|
09710d6c47 | ||
|
|
832ac97088 | ||
|
|
8685f8e6c8 | ||
|
|
e49eae4047 | ||
|
|
0066833887 | ||
|
|
4a1e060832 | ||
|
|
8feb0f0440 | ||
|
|
8ce1ca4590 | ||
|
|
8839cc51c2 | ||
|
|
f7a82987f4 | ||
|
|
ff3e29041e | ||
|
|
d2567b0381 | ||
|
|
5fccbfc7c6 | ||
|
|
8482109dea | ||
|
|
0bd45c7d75 | ||
|
|
7f78781800 | ||
|
|
8939c6ac12 | ||
|
|
c0f13103a4 | ||
|
|
951bd745aa | ||
|
|
6041c7edf9 | ||
|
|
2d32956903 | ||
|
|
4127b524d5 | ||
|
|
43746727aa | ||
|
|
4f4dc2f4d8 | ||
|
|
baa566adae | ||
|
|
8fac75f4ee | ||
|
|
8cf4574198 | ||
|
|
b4f1a63f64 | ||
|
|
8cff36967e | ||
|
|
cbfe8b9228 | ||
|
|
52d09e9600 | ||
|
|
a52285596e | ||
|
|
e08b48ab48 | ||
|
|
663e42070f | ||
|
|
43cb48295b | ||
|
|
4abed1f83f | ||
|
|
dd1cfdd31c | ||
|
|
f84c41f684 | ||
|
|
116d61185a | ||
|
|
9f6541228d | ||
|
|
a89e79a7ed | ||
|
|
d73dc0958b | ||
|
|
70baf86ce2 | ||
|
|
a53c7529c1 | ||
|
|
8889c29866 | ||
|
|
99d6afb3a1 | ||
|
|
827730144b | ||
|
|
e05804848f | ||
|
|
6aa452cda4 | ||
|
|
7668c1ea0b | ||
|
|
03319a5426 | ||
|
|
344dda4029 | ||
|
|
e9ba5abe03 | ||
|
|
87395cdef8 | ||
|
|
737ffd8d7c | ||
|
|
c31882749d | ||
|
|
90d815ce6c | ||
|
|
3e7501579f | ||
|
|
a14380ed01 | ||
|
|
2acfb8ad82 | ||
|
|
15397bf879 | ||
|
|
1b6e01ce6d | ||
|
|
dfd13cf4ca | ||
|
|
1e8e8f18b4 | ||
|
|
5c9b19b508 | ||
|
|
67db92d500 | ||
|
|
38d99950f8 | ||
|
|
cbd37ad3b9 | ||
|
|
912ec1437b | ||
|
|
242be31440 | ||
|
|
48f1eb4584 | ||
|
|
939d69df6e | ||
|
|
f8b9a66ead | ||
|
|
081ab17e13 | ||
|
|
75ec7a057a | ||
|
|
01980dea11 | ||
|
|
5acfa8611a | ||
|
|
e94da877c2 | ||
|
|
148014f99a | ||
|
|
fa197ad583 | ||
|
|
6503f32ef9 | ||
|
|
da47b569e8 | ||
|
|
0d8994d81d | ||
|
|
c3f343e6c4 | ||
|
|
25931d16ab | ||
|
|
7bcb99f823 | ||
|
|
3eac767e72 | ||
|
|
12f218c747 | ||
|
|
492269a0fd | ||
|
|
141f909b68 | ||
|
|
e50ba35871 | ||
|
|
98be7b6299 | ||
|
|
dbb8a6bf52 | ||
|
|
ce855c5685 | ||
|
|
b105bf59c1 | ||
|
|
c2c91b6477 | ||
|
|
3c007d1333 | ||
|
|
665d3166ed | ||
|
|
3ee4790dab | ||
|
|
ae701977c6 | ||
|
|
f59752bf4f | ||
|
|
d344c1e408 | ||
|
|
e3e6cd6fd8 | ||
|
|
cdc7b8d15e | ||
|
|
cc4da371ff | ||
|
|
fd53a4b24d | ||
|
|
f8f3fba433 | ||
|
|
06a8db8a66 | ||
|
|
63d9174822 | ||
|
|
248ac5c37b | ||
|
|
7233c83874 | ||
|
|
5dea4b9b1c | ||
|
|
262abc43f8 | ||
|
|
b3da5370c0 | ||
|
|
d96836e608 | ||
|
|
29609b6e5d | ||
|
|
3e04884a57 | ||
|
|
fe248ac03f |
8
.gitmodules
vendored
8
.gitmodules
vendored
@@ -1,21 +1,21 @@
|
||||
[submodule "vendor/brightray"]
|
||||
path = vendor/brightray
|
||||
url = https://github.com/atom/brightray.git
|
||||
url = https://github.com/electron/brightray.git
|
||||
[submodule "vendor/node"]
|
||||
path = vendor/node
|
||||
url = https://github.com/atom/node.git
|
||||
url = https://github.com/electron/node.git
|
||||
[submodule "vendor/depot_tools"]
|
||||
path = vendor/depot_tools
|
||||
url = https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
[submodule "vendor/breakpad"]
|
||||
path = vendor/breakpad
|
||||
url = https://github.com/atom/chromium-breakpad.git
|
||||
url = https://github.com/electron/chromium-breakpad.git
|
||||
[submodule "vendor/native_mate"]
|
||||
path = vendor/native_mate
|
||||
url = https://github.com/zcbenz/native-mate.git
|
||||
[submodule "vendor/crashpad"]
|
||||
path = vendor/crashpad
|
||||
url = https://github.com/atom/crashpad.git
|
||||
url = https://github.com/electron/crashpad.git
|
||||
[submodule "vendor/requests"]
|
||||
path = vendor/requests
|
||||
url = https://github.com/kennethreitz/requests
|
||||
|
||||
1
.node-version
Normal file
1
.node-version
Normal file
@@ -0,0 +1 @@
|
||||
v5.10.0
|
||||
@@ -19,8 +19,7 @@ matrix:
|
||||
- os: linux
|
||||
env: TARGET_ARCH=ia32
|
||||
allow_failures:
|
||||
- env: TARGET_ARCH=arm
|
||||
- env: TARGET_ARCH=ia32
|
||||
- os: osx
|
||||
|
||||
script: './script/cibuild'
|
||||
|
||||
|
||||
@@ -1,24 +1,46 @@
|
||||
# Contributor Code of Conduct
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
||||
## Our Pledge
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
- The use of sexualized language or imagery
|
||||
- Personal attacks
|
||||
- Trolling or insulting/derogatory comments
|
||||
- Public or private harassment
|
||||
- Publishing other's private information, such as physical or electronic addresses, without explicit permission
|
||||
- Other unethical or unprofessional conduct
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a project maintainer at [atom@github.com](mailto:atom@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
## Enforcement
|
||||
|
||||
This Code of Conduct is adapted from the Contributor Covenant, version 1.3.0, available from http://contributor-covenant.org/version/1/3/0/
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Electron에 기여하기
|
||||
|
||||
:+1::tada: 먼저, 이 프로젝트에 기여해주셔서 감사합니다! :tada::+1:
|
||||
:+1::tada: 먼저, 기여에 관심을 가져주셔서 감사합니다! :tada::+1:
|
||||
|
||||
이 프로젝트는 기여자 규약 [행동강령](CODE_OF_CONDUCT.md)을 준수합니다. 따라서 이
|
||||
이 프로젝트는 기여자 규약인 [행동강령](CODE_OF_CONDUCT.md)을 준수합니다. 따라서 이
|
||||
프로젝트의 개발에 참여하려면 이 규약을 지켜야 합니다. 받아들일 수 없는 행위를 발견했을
|
||||
경우 atom@github.com로 보고 하십시오.
|
||||
경우 atom@github.com로 보고하세요.
|
||||
|
||||
다음 항목들은 Electron에 기여하는 가이드라인을 제시합니다.
|
||||
참고로 이 항목들은 그저 가이드라인에 불과하며 규칙이 아닙니다. 따라서 스스로의 적절한
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
## 이슈 제출
|
||||
|
||||
* [여기](https://github.com/atom/electron/issues/new)에서 새로운 이슈를 만들 수
|
||||
* [여기](https://github.com/electron/electron/issues/new)에서 새로운 이슈를 만들 수
|
||||
있습니다. 하지만 이슈를 작성하기 전에 아래의 항목들을 숙지하고 가능한한 이슈 보고에
|
||||
대해 최대한 많은 정보와 자세한 설명을 포함해야 합니다. 가능하다면 다음 항목을 포함해야
|
||||
합니다:
|
||||
@@ -23,18 +23,18 @@
|
||||
* 추가로 다음 사항을 준수하면 이슈를 해결하는데 큰 도움이 됩니다:
|
||||
* 스크린샷 또는 GIF 애니메이션 이미지들
|
||||
* 터미널에 출력된 에러의 내용 또는 개발자 도구, 알림창에 뜬 내용
|
||||
* [Cursory search](https://github.com/atom/electron/issues?utf8=✓&q=is%3Aissue+)를
|
||||
* [Cursory search](https://github.com/electron/electron/issues?utf8=✓&q=is%3Aissue+)를
|
||||
통해 이미 비슷한 내용의 이슈가 등록되어있는지 확인
|
||||
|
||||
## Pull Request 하기
|
||||
|
||||
* 가능한한 스크린샷과 GIF 애니메이션 이미지를 pull request에 추가
|
||||
* CoffeeScript, JavaScript, C++과 Python등
|
||||
[참조문서에 정의된 코딩스타일](/docs-translations/ko-KR/development/coding-style.md)을
|
||||
* JavaScript, C++과 Python등
|
||||
[참조 문서에 정의된 코딩스타일](/docs-translations/ko-KR/development/coding-style.md)을
|
||||
준수
|
||||
* [문서 스타일 가이드](/docs-translations/ko-KR/styleguide.md)에 따라 문서를
|
||||
[Markdown](https://daringfireball.net/projects/markdown) 형식으로 작성.
|
||||
* 짧은, 현재 시제 커밋 메시지 사용. [커밋 메시지 스타일 가이드](#Git-커밋-메시지)를
|
||||
* 짧은, 현재 시제 커밋 메시지 사용. [커밋 메시지 스타일 가이드](#git-커밋-메시지)를
|
||||
참고하세요
|
||||
|
||||
## 스타일 가이드
|
||||
@@ -58,7 +58,7 @@
|
||||
### Git 커밋 메시지
|
||||
|
||||
* 현재 시제 사용 ("Added feature" 대신 "Add feature" 사용)
|
||||
* 필수적 분위기(imperative mood) 사용 ("Moves cursor to..." 대신 "Move cursor to..." 사용)
|
||||
* 명령법(imperative mood) 사용 ("Moves cursor to..." 대신 "Move cursor to..." 사용)
|
||||
* 첫 줄은 72자에 맞추거나 그 보다 적게 제한
|
||||
* 자유롭게 필요에 따라 이슈나 PR링크를 참조
|
||||
* 단순한 문서 변경일 경우 `[ci skip]`을 커밋 메시지에 추가
|
||||
|
||||
@@ -12,7 +12,7 @@ propose changes to this document in a pull request.
|
||||
|
||||
## Submitting Issues
|
||||
|
||||
* You can create an issue [here](https://github.com/atom/electron/issues/new),
|
||||
* You can create an issue [here](https://github.com/electron/electron/issues/new),
|
||||
but before doing that please read the notes below and include as many details as
|
||||
possible with your report. If you can, please include:
|
||||
* The version of Electron you are using
|
||||
@@ -22,13 +22,13 @@ possible with your report. If you can, please include:
|
||||
* Other things that will help resolve your issue:
|
||||
* Screenshots and animated GIFs
|
||||
* Error output that appears in your terminal, dev tools or as an alert
|
||||
* Perform a [cursory search](https://github.com/atom/electron/issues?utf8=✓&q=is%3Aissue+)
|
||||
* Perform a [cursory search](https://github.com/electron/electron/issues?utf8=✓&q=is%3Aissue+)
|
||||
to see if a similar issue has already been submitted
|
||||
|
||||
## Submitting Pull Requests
|
||||
|
||||
* Include screenshots and animated GIFs in your pull request whenever possible.
|
||||
* Follow the CoffeeScript, JavaScript, C++ and Python [coding style defined in docs](/docs/development/coding-style.md).
|
||||
* Follow the JavaScript, C++, and Python [coding style defined in docs](/docs/development/coding-style.md).
|
||||
* Write documentation in [Markdown](https://daringfireball.net/projects/markdown).
|
||||
See the [Documentation Styleguide](/docs/styleguide.md).
|
||||
* Use short, present tense commit messages. See [Commit Message Styleguide](#git-commit-messages).
|
||||
|
||||
47
README-ko.md
47
README-ko.md
@@ -1,12 +1,13 @@
|
||||
[](http://electron.atom.io/)
|
||||
|
||||
[](https://travis-ci.org/atom/electron)
|
||||
[](https://david-dm.org/atom/electron#info=devDependencies)
|
||||
[](https://travis-ci.org/electron/electron)
|
||||
[](https://ci.appveyor.com/project/Atom/electron)
|
||||
[](https://david-dm.org/electron/electron#info=devDependencies)
|
||||
[](http://atom-slack.herokuapp.com/)
|
||||
|
||||
### [Electron](https://github.com/atom/electron/) 한국어 참조문서
|
||||
### [Electron](https://github.com/electron/electron/) 한국어 참조 문서
|
||||
|
||||
:zap: *프레임워크 이름이 Atom Shell에서 Electron으로 변경되었습니다* :zap:
|
||||
:zap: *이전까지 Atom Shell로 불렸지만, Electron으로 변경되었습니다* :zap:
|
||||
|
||||
Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여
|
||||
Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다.
|
||||
@@ -16,15 +17,15 @@ Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주
|
||||
Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서
|
||||
[@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요.
|
||||
|
||||
이 프로젝트는 기여자 규약 [행동강령](CODE_OF_CONDUCT.md)을 준수합니다. 따라서 이
|
||||
이 프로젝트는 기여자 규약인 [행동강령](CODE_OF_CONDUCT.md)을 준수합니다. 따라서 이
|
||||
프로젝트의 개발에 참여하려면 이 규약을 지켜야 합니다. 받아들일 수 없는 행위를 발견했을
|
||||
경우 atom@github.com로 보고 하십시오.
|
||||
경우 atom@github.com로 보고하세요.
|
||||
|
||||
## 다운로드
|
||||
|
||||
Linux, Windows, OS X 용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어
|
||||
있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 받아 볼
|
||||
수 있습니다.
|
||||
있습니다. [releases](https://github.com/electron/electron/releases) 페이지에서
|
||||
받아 볼 수 있습니다.
|
||||
|
||||
또한 [`npm`](https://docs.npmjs.com/)을 통해 미리 빌드된 Electron 바이너리를 설치할
|
||||
수도 있습니다:
|
||||
@@ -43,25 +44,26 @@ npm install electron-prebuilt --save-dev
|
||||
|
||||
## 참조 문서
|
||||
|
||||
[Docs](https://github.com/atom/electron/tree/master/docs/README.md)에 개발 지침과
|
||||
API 레퍼런스가 있습니다. Electron을 빌드 하는 방법과 프로젝트에 기여하는법 또한 문서에
|
||||
포함되어 있으니 참고하시기 바랍니다.
|
||||
[Docs](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/README.md)에
|
||||
개발 지침과 API 레퍼런스가 있습니다. Electron을 빌드 하는 방법과 프로젝트에 기여하는법
|
||||
또한 문서에 포함되어 있으니 참고하시기 바랍니다.
|
||||
|
||||
## 참조 문서 (번역)
|
||||
|
||||
- [브라질 포르투갈어](https://github.com/atom/electron/tree/master/docs-translations/pt-BR)
|
||||
- [한국어](https://github.com/atom/electron/tree/master/docs-translations/ko-KR)
|
||||
- [일본어](https://github.com/atom/electron/tree/master/docs-translations/jp)
|
||||
- [스페인어](https://github.com/atom/electron/tree/master/docs-translations/es)
|
||||
- [중국어 간체](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
||||
- [중국어 번체](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
||||
- [우크라이나어](https://github.com/atom/electron/tree/master/docs-translations/uk-UA)
|
||||
- [러시아어](https://github.com/atom/electron/tree/master/docs-translations/ru-RU)
|
||||
- [프랑스어](https://github.com/atom/electron/tree/master/docs-translations/fr-FR)
|
||||
- [브라질 포르투갈어](https://github.com/electron/electron/tree/master/docs-translations/pt-BR)
|
||||
- [한국어](https://github.com/electron/electron/tree/master/docs-translations/ko-KR)
|
||||
- [일본어](https://github.com/electron/electron/tree/master/docs-translations/jp)
|
||||
- [스페인어](https://github.com/electron/electron/tree/master/docs-translations/es)
|
||||
- [중국어 간체](https://github.com/electron/electron/tree/master/docs-translations/zh-CN)
|
||||
- [중국어 번체](https://github.com/electron/electron/tree/master/docs-translations/zh-TW)
|
||||
- [터키어](https://github.com/electron/electron/tree/master/docs-translations/tr-TR)
|
||||
- [우크라이나어](https://github.com/electron/electron/tree/master/docs-translations/uk-UA)
|
||||
- [러시아어](https://github.com/electron/electron/tree/master/docs-translations/ru-RU)
|
||||
- [프랑스어](https://github.com/electron/electron/tree/master/docs-translations/fr-FR)
|
||||
|
||||
## 시작하기
|
||||
|
||||
[`atom/electron-quick-start`](https://github.com/atom/electron-quick-start)
|
||||
[`electron/electron-quick-start`](https://github.com/electron/electron-quick-start)
|
||||
저장소를 클론하여 Electron을 간단히 접해볼 수 있습니다.
|
||||
|
||||
## 커뮤니티
|
||||
@@ -76,5 +78,4 @@ API 레퍼런스가 있습니다. Electron을 빌드 하는 방법과 프로젝
|
||||
- [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(일본)* 커뮤니티
|
||||
|
||||
[awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트에
|
||||
커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 한번 참고해 보시기
|
||||
바랍니다.
|
||||
커뮤니티가 운영중인 유용한 예시 어플리케이션과 도구, 리소스가 있으니 참고하기 바랍니다.
|
||||
|
||||
31
README.md
31
README.md
@@ -1,8 +1,8 @@
|
||||
[](http://electron.atom.io/)
|
||||
|
||||
[](https://travis-ci.org/atom/electron)
|
||||
[](https://ci.appveyor.com/project/Atom/electron)
|
||||
[](https://david-dm.org/atom/electron#info=devDependencies)
|
||||
[](https://travis-ci.org/electron/electron)
|
||||
[](https://ci.appveyor.com/project/Atom/electron)
|
||||
[](https://david-dm.org/electron/electron#info=devDependencies)
|
||||
[](http://atom-slack.herokuapp.com/)
|
||||
|
||||
:zap: *Formerly known as Atom Shell* :zap:
|
||||
@@ -22,7 +22,7 @@ behavior to atom@github.com.
|
||||
## Downloads
|
||||
|
||||
Prebuilt binaries and debug symbols of Electron for Linux, Windows and OS X can
|
||||
be found on the [releases](https://github.com/atom/electron/releases) page.
|
||||
be found on the [releases](https://github.com/electron/electron/releases) page.
|
||||
|
||||
You can also use [`npm`](https://docs.npmjs.com/) to install prebuilt electron
|
||||
binaries:
|
||||
@@ -42,24 +42,25 @@ npm install electron-prebuilt --save-dev
|
||||
## Documentation
|
||||
|
||||
Guides and the API reference are located in the
|
||||
[docs](https://github.com/atom/electron/tree/master/docs) directory. It also
|
||||
[docs](https://github.com/electron/electron/tree/master/docs) directory. It also
|
||||
contains documents describing how to build and contribute to Electron.
|
||||
|
||||
## Documentation Translations
|
||||
|
||||
- [Brazilian Portuguese](https://github.com/atom/electron/tree/master/docs-translations/pt-BR)
|
||||
- [Korean](https://github.com/atom/electron/tree/master/docs-translations/ko-KR)
|
||||
- [Japanese](https://github.com/atom/electron/tree/master/docs-translations/jp)
|
||||
- [Spanish](https://github.com/atom/electron/tree/master/docs-translations/es)
|
||||
- [Simplified Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
||||
- [Traditional Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
||||
- [Ukrainian](https://github.com/atom/electron/tree/master/docs-translations/uk-UA)
|
||||
- [Russian](https://github.com/atom/electron/tree/master/docs-translations/ru-RU)
|
||||
- [French](https://github.com/atom/electron/tree/master/docs-translations/fr-FR)
|
||||
- [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR)
|
||||
- [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR)
|
||||
- [Japanese](https://github.com/electron/electron/tree/master/docs-translations/jp)
|
||||
- [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es)
|
||||
- [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN)
|
||||
- [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW)
|
||||
- [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR)
|
||||
- [Ukrainian](https://github.com/electron/electron/tree/master/docs-translations/uk-UA)
|
||||
- [Russian](https://github.com/electron/electron/tree/master/docs-translations/ru-RU)
|
||||
- [French](https://github.com/electron/electron/tree/master/docs-translations/fr-FR)
|
||||
|
||||
## Quick Start
|
||||
|
||||
Clone and run the [`atom/electron-quick-start`](https://github.com/atom/electron-quick-start)
|
||||
Clone and run the [`electron/electron-quick-start`](https://github.com/electron/electron-quick-start)
|
||||
repository to see a minimal Electron app in action.
|
||||
|
||||
## Community
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
# http://www.appveyor.com/docs/appveyor-yml
|
||||
version: "{build}"
|
||||
|
||||
os: Visual Studio 2015
|
||||
|
||||
init:
|
||||
- git config --global core.autocrlf input
|
||||
|
||||
@@ -10,7 +12,7 @@ platform:
|
||||
- x64
|
||||
|
||||
install:
|
||||
- cmd: SET PATH=C:\Program Files (x86)\MSBuild\12.0\bin\;%PATH%
|
||||
- cmd: SET PATH=C:\Program Files (x86)\MSBuild\14.0\bin\;%PATH%
|
||||
- cmd: SET PATH=C:\python27;%PATH%
|
||||
- cmd: python script/cibuild
|
||||
|
||||
|
||||
@@ -89,11 +89,9 @@ content::PepperPluginInfo CreateWidevineCdmInfo(const base::FilePath& path,
|
||||
|
||||
// Add the supported codecs as if they came from the component manifest.
|
||||
std::vector<std::string> codecs;
|
||||
codecs.push_back(kCdmSupportedCodecVorbis);
|
||||
codecs.push_back(kCdmSupportedCodecVp8);
|
||||
codecs.push_back(kCdmSupportedCodecVp9);
|
||||
#if defined(USE_PROPRIETARY_CODECS)
|
||||
codecs.push_back(kCdmSupportedCodecAac);
|
||||
codecs.push_back(kCdmSupportedCodecAvc1);
|
||||
#endif // defined(USE_PROPRIETARY_CODECS)
|
||||
std::string codec_string = base::JoinString(
|
||||
@@ -126,7 +124,7 @@ void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
|
||||
void AddPepperFlashFromCommandLine(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto flash_path = command_line->GetSwitchValueNative(
|
||||
base::FilePath flash_path = command_line->GetSwitchValuePath(
|
||||
switches::kPpapiFlashPath);
|
||||
if (flash_path.empty())
|
||||
return;
|
||||
@@ -134,20 +132,19 @@ void AddPepperFlashFromCommandLine(
|
||||
auto flash_version = command_line->GetSwitchValueASCII(
|
||||
switches::kPpapiFlashVersion);
|
||||
|
||||
plugins->push_back(
|
||||
CreatePepperFlashInfo(base::FilePath(flash_path), flash_version));
|
||||
plugins->push_back(CreatePepperFlashInfo(flash_path, flash_version));
|
||||
}
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
void AddWidevineCdmFromCommandLine(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto widevine_cdm_path = command_line->GetSwitchValueNative(
|
||||
base::FilePath widevine_cdm_path = command_line->GetSwitchValuePath(
|
||||
switches::kWidevineCdmPath);
|
||||
if (widevine_cdm_path.empty())
|
||||
return;
|
||||
|
||||
if (!base::PathExists(base::FilePath(widevine_cdm_path)))
|
||||
if (!base::PathExists(widevine_cdm_path))
|
||||
return;
|
||||
|
||||
auto widevine_cdm_version = command_line->GetSwitchValueASCII(
|
||||
@@ -155,7 +152,7 @@ void AddWidevineCdmFromCommandLine(
|
||||
if (widevine_cdm_version.empty())
|
||||
return;
|
||||
|
||||
plugins->push_back(CreateWidevineCdmInfo(base::FilePath(widevine_cdm_path),
|
||||
plugins->push_back(CreateWidevineCdmInfo(widevine_cdm_path,
|
||||
widevine_cdm_version));
|
||||
}
|
||||
#endif
|
||||
@@ -182,14 +179,8 @@ base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
|
||||
|
||||
void AtomContentClient::AddAdditionalSchemes(
|
||||
std::vector<url::SchemeWithType>* standard_schemes,
|
||||
std::vector<url::SchemeWithType>* referrer_schemes,
|
||||
std::vector<std::string>* savable_schemes) {
|
||||
std::vector<std::string> schemes;
|
||||
ConvertStringWithSeparatorToVector(&schemes, ",",
|
||||
switches::kRegisterStandardSchemes);
|
||||
if (!schemes.empty()) {
|
||||
for (const std::string& scheme : schemes)
|
||||
standard_schemes->push_back({scheme.c_str(), url::SCHEME_WITHOUT_PORT});
|
||||
}
|
||||
standard_schemes->push_back({"chrome-extension", url::SCHEME_WITHOUT_PORT});
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ class AtomContentClient : public brightray::ContentClient {
|
||||
base::string16 GetLocalizedString(int message_id) const override;
|
||||
void AddAdditionalSchemes(
|
||||
std::vector<url::SchemeWithType>* standard_schemes,
|
||||
std::vector<url::SchemeWithType>* referrer_schemes,
|
||||
std::vector<std::string>* savable_schemes) override;
|
||||
void AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) override;
|
||||
|
||||
@@ -51,46 +51,6 @@ bool IsRunAsNode() {
|
||||
return IsEnvSet(kRunAsNode) || IsEnvSet(kOldRunAsNode);
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Win8.1 supports monitor-specific DPI scaling.
|
||||
bool SetProcessDpiAwarenessWrapper(PROCESS_DPI_AWARENESS value) {
|
||||
typedef HRESULT(WINAPI *SetProcessDpiAwarenessPtr)(PROCESS_DPI_AWARENESS);
|
||||
SetProcessDpiAwarenessPtr set_process_dpi_awareness_func =
|
||||
reinterpret_cast<SetProcessDpiAwarenessPtr>(
|
||||
GetProcAddress(GetModuleHandleA("user32.dll"),
|
||||
"SetProcessDpiAwarenessInternal"));
|
||||
if (set_process_dpi_awareness_func) {
|
||||
HRESULT hr = set_process_dpi_awareness_func(value);
|
||||
if (SUCCEEDED(hr)) {
|
||||
VLOG(1) << "SetProcessDpiAwareness succeeded.";
|
||||
return true;
|
||||
} else if (hr == E_ACCESSDENIED) {
|
||||
LOG(ERROR) << "Access denied error from SetProcessDpiAwareness. "
|
||||
"Function called twice, or manifest was used.";
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// This function works for Windows Vista through Win8. Win8.1 must use
|
||||
// SetProcessDpiAwareness[Wrapper].
|
||||
BOOL SetProcessDPIAwareWrapper() {
|
||||
typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID);
|
||||
SetProcessDPIAwarePtr set_process_dpi_aware_func =
|
||||
reinterpret_cast<SetProcessDPIAwarePtr>(
|
||||
GetProcAddress(GetModuleHandleA("user32.dll"),
|
||||
"SetProcessDPIAware"));
|
||||
return set_process_dpi_aware_func &&
|
||||
set_process_dpi_aware_func();
|
||||
}
|
||||
|
||||
void EnableHighDPISupport() {
|
||||
if (!SetProcessDpiAwarenessWrapper(PROCESS_SYSTEM_DPI_AWARE)) {
|
||||
SetProcessDPIAwareWrapper();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@@ -154,12 +114,6 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
content::InitializeSandboxInfo(&sandbox_info);
|
||||
atom::AtomMainDelegate delegate;
|
||||
|
||||
// We don't want to set DPI awareness on pre-Win7 because we don't support
|
||||
// DirectWrite there. GDI fonts are kerned very badly, so better to leave
|
||||
// DPI-unaware and at effective 1.0. See also ShouldUseDirectWrite().
|
||||
if (base::win::GetVersion() >= base::win::VERSION_WIN7)
|
||||
EnableHighDPISupport();
|
||||
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.instance = instance;
|
||||
params.sandbox_info = &sandbox_info;
|
||||
|
||||
@@ -83,6 +83,10 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
|
||||
chrome::RegisterPathProvider();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
SetUpBundleOverrides();
|
||||
#endif
|
||||
|
||||
return brightray::MainDelegate::BasicStartupComplete(exit_code);
|
||||
}
|
||||
|
||||
@@ -98,10 +102,6 @@ void AtomMainDelegate::PreSandboxStartup() {
|
||||
std::string process_type = command_line->GetSwitchValueASCII(
|
||||
switches::kProcessType);
|
||||
|
||||
if (process_type == switches::kUtilityProcess) {
|
||||
AtomContentUtilityClient::PreSandboxStartup();
|
||||
}
|
||||
|
||||
// Only append arguments for browser process.
|
||||
if (!IsBrowserProcess(command_line))
|
||||
return;
|
||||
|
||||
@@ -31,6 +31,10 @@ class AtomMainDelegate : public brightray::MainDelegate {
|
||||
#endif
|
||||
|
||||
private:
|
||||
#if defined(OS_MACOSX)
|
||||
void SetUpBundleOverrides();
|
||||
#endif
|
||||
|
||||
brightray::ContentClient content_client_;
|
||||
scoped_ptr<content::ContentBrowserClient> browser_client_;
|
||||
scoped_ptr<content::ContentRendererClient> renderer_client_;
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/mac/foundation_util.h"
|
||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
#include "brightray/common/mac/main_application_bundle.h"
|
||||
#include "content/public/common/content_paths.h"
|
||||
@@ -48,4 +51,15 @@ void AtomMainDelegate::OverrideChildProcessPath() {
|
||||
PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
|
||||
}
|
||||
|
||||
void AtomMainDelegate::SetUpBundleOverrides() {
|
||||
base::mac::ScopedNSAutoreleasePool pool;
|
||||
NSBundle* bundle = brightray::MainApplicationBundle();
|
||||
std::string base_bundle_id =
|
||||
base::SysNSStringToUTF8([bundle bundleIdentifier]);
|
||||
NSString* team_id = [bundle objectForInfoDictionaryKey:@"ElectronTeamID"];
|
||||
if (team_id)
|
||||
base_bundle_id = base::SysNSStringToUTF8(team_id) + "." + base_bundle_id;
|
||||
base::mac::SetBaseBundleID(base_bundle_id.c_str());
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -15,16 +15,19 @@
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/login_handler.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_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/net_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "brightray/browser/brightray_paths.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "content/public/browser/client_certificate_delegate.h"
|
||||
@@ -39,7 +42,6 @@
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
#endif
|
||||
|
||||
using atom::Browser;
|
||||
@@ -157,12 +159,46 @@ void PassLoginInformation(scoped_refptr<LoginHandler> login_handler,
|
||||
login_handler->CancelAuth();
|
||||
}
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
int ImportIntoCertStore(
|
||||
CertificateManagerModel* model,
|
||||
const base::DictionaryValue& options) {
|
||||
std::string file_data, cert_path;
|
||||
base::string16 password;
|
||||
net::CertificateList imported_certs;
|
||||
int rv = -1;
|
||||
options.GetString("certificate", &cert_path);
|
||||
options.GetString("password", &password);
|
||||
|
||||
if (!cert_path.empty()) {
|
||||
if (base::ReadFileToString(base::FilePath(cert_path), &file_data)) {
|
||||
auto module = model->cert_db()->GetPublicModule();
|
||||
rv = model->ImportFromPKCS12(module,
|
||||
file_data,
|
||||
password,
|
||||
true,
|
||||
&imported_certs);
|
||||
if (imported_certs.size() > 1) {
|
||||
auto it = imported_certs.begin();
|
||||
++it; // skip first which would be the client certificate.
|
||||
for (; it != imported_certs.end(); ++it)
|
||||
rv &= model->SetCertTrust(it->get(),
|
||||
net::CA_CERT,
|
||||
net::NSSCertDatabase::TRUSTED_SSL);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
App::App() {
|
||||
App::App(v8::Isolate* isolate) {
|
||||
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())->set_delegate(this);
|
||||
Browser::Get()->AddObserver(this);
|
||||
content::GpuDataManager::GetInstance()->AddObserver(this);
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
App::~App() {
|
||||
@@ -214,6 +250,15 @@ void App::OnFinishLaunching() {
|
||||
Emit("ready");
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void App::OnContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
*prevent_default = Emit("continue-activity", type, user_info);
|
||||
}
|
||||
#endif
|
||||
|
||||
void App::OnLogin(LoginHandler* login_handler) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
@@ -229,6 +274,23 @@ void App::OnLogin(LoginHandler* login_handler) {
|
||||
login_handler->CancelAuth();
|
||||
}
|
||||
|
||||
void App::OnCreateWindow(const GURL& target_url,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
int render_process_id,
|
||||
int render_frame_id) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
content::RenderFrameHost* rfh =
|
||||
content::RenderFrameHost::FromID(render_process_id, render_frame_id);
|
||||
content::WebContents* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(rfh);
|
||||
if (web_contents) {
|
||||
auto api_web_contents = WebContents::CreateFrom(isolate(), web_contents);
|
||||
api_web_contents->OnCreateWindow(target_url, frame_name, disposition);
|
||||
}
|
||||
}
|
||||
|
||||
void App::AllowCertificateError(
|
||||
content::WebContents* web_contents,
|
||||
int cert_error,
|
||||
@@ -279,12 +341,6 @@ void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) {
|
||||
Emit("gpu-process-crashed");
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void App::OnPlatformThemeChanged() {
|
||||
Emit("platform-theme-changed");
|
||||
}
|
||||
#endif
|
||||
|
||||
base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
|
||||
bool succeed = false;
|
||||
base::FilePath path;
|
||||
@@ -299,10 +355,15 @@ base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
|
||||
void App::SetPath(mate::Arguments* args,
|
||||
const std::string& name,
|
||||
const base::FilePath& path) {
|
||||
if (!path.IsAbsolute()) {
|
||||
args->ThrowError("path must be absolute");
|
||||
return;
|
||||
}
|
||||
|
||||
bool succeed = false;
|
||||
int key = GetPathConstant(name);
|
||||
if (key >= 0)
|
||||
succeed = PathService::Override(key, path);
|
||||
succeed = PathService::OverrideAndCreateIfNeeded(key, path, true, false);
|
||||
if (!succeed)
|
||||
args->ThrowError("Failed to set path");
|
||||
}
|
||||
@@ -314,22 +375,10 @@ void App::SetDesktopName(const std::string& desktop_name) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void App::AllowNTLMCredentialsForAllDomains(bool should_allow) {
|
||||
auto browser_context = static_cast<AtomBrowserContext*>(
|
||||
AtomBrowserMainParts::Get()->browser_context());
|
||||
browser_context->AllowNTLMCredentialsForAllDomains(should_allow);
|
||||
}
|
||||
|
||||
std::string App::GetLocale() {
|
||||
return l10n_util::GetApplicationLocale("");
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool App::IsAeroGlassEnabled() {
|
||||
return ui::win::IsAeroGlassEnabled();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool App::MakeSingleInstance(
|
||||
const ProcessSingleton::NotificationCallback& callback) {
|
||||
if (process_singleton_.get())
|
||||
@@ -352,10 +401,46 @@ bool App::MakeSingleInstance(
|
||||
}
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void App::ImportCertificate(
|
||||
const base::DictionaryValue& options,
|
||||
const net::CompletionCallback& callback) {
|
||||
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
|
||||
if (!certificate_manager_model_) {
|
||||
scoped_ptr<base::DictionaryValue> copy = options.CreateDeepCopy();
|
||||
CertificateManagerModel::Create(browser_context,
|
||||
base::Bind(&App::OnCertificateManagerModelCreated,
|
||||
base::Unretained(this),
|
||||
base::Passed(©),
|
||||
callback));
|
||||
return;
|
||||
}
|
||||
|
||||
int rv = ImportIntoCertStore(certificate_manager_model_.get(), options);
|
||||
callback.Run(rv);
|
||||
}
|
||||
|
||||
void App::OnCertificateManagerModelCreated(
|
||||
scoped_ptr<base::DictionaryValue> options,
|
||||
const net::CompletionCallback& callback,
|
||||
scoped_ptr<CertificateManagerModel> model) {
|
||||
certificate_manager_model_ = std::move(model);
|
||||
int rv = ImportIntoCertStore(certificate_manager_model_.get(),
|
||||
*(options.get()));
|
||||
callback.Run(rv);
|
||||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
mate::Handle<App> App::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new App(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void App::BuildPrototype(
|
||||
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
|
||||
auto browser = base::Unretained(Browser::Get());
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("quit", base::Bind(&Browser::Quit, browser))
|
||||
.SetMethod("exit", base::Bind(&Browser::Exit, browser))
|
||||
.SetMethod("focus", base::Bind(&Browser::Focus, browser))
|
||||
@@ -370,31 +455,34 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||
base::Bind(&Browser::ClearRecentDocuments, browser))
|
||||
.SetMethod("setAppUserModelId",
|
||||
base::Bind(&Browser::SetAppUserModelID, browser))
|
||||
.SetMethod("isDefaultProtocolClient",
|
||||
base::Bind(&Browser::IsDefaultProtocolClient, browser))
|
||||
.SetMethod("setAsDefaultProtocolClient",
|
||||
base::Bind(&Browser::SetAsDefaultProtocolClient, browser))
|
||||
.SetMethod("removeAsDefaultProtocolClient",
|
||||
base::Bind(&Browser::RemoveAsDefaultProtocolClient, browser))
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("hide", base::Bind(&Browser::Hide, browser))
|
||||
.SetMethod("show", base::Bind(&Browser::Show, browser))
|
||||
.SetMethod("isDarkMode",
|
||||
base::Bind(&Browser::IsDarkMode, browser))
|
||||
.SetMethod("setUserActivity",
|
||||
base::Bind(&Browser::SetUserActivity, browser))
|
||||
.SetMethod("getCurrentActivityType",
|
||||
base::Bind(&Browser::GetCurrentActivityType, browser))
|
||||
#endif
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("setUserTasks",
|
||||
base::Bind(&Browser::SetUserTasks, browser))
|
||||
.SetMethod("isAeroGlassEnabled", &App::IsAeroGlassEnabled)
|
||||
#endif
|
||||
.SetMethod("setPath", &App::SetPath)
|
||||
.SetMethod("getPath", &App::GetPath)
|
||||
.SetMethod("setDesktopName", &App::SetDesktopName)
|
||||
.SetMethod("allowNTLMCredentialsForAllDomains",
|
||||
&App::AllowNTLMCredentialsForAllDomains)
|
||||
.SetMethod("getLocale", &App::GetLocale)
|
||||
#if defined(USE_NSS_CERTS)
|
||||
.SetMethod("importCertificate", &App::ImportCertificate)
|
||||
#endif
|
||||
.SetMethod("makeSingleInstance", &App::MakeSingleInstance);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<App> App::Create(v8::Isolate* isolate) {
|
||||
return CreateHandle(isolate, new App);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
@@ -405,8 +493,8 @@ namespace {
|
||||
void AppendSwitch(const std::string& switch_string, mate::Arguments* args) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
if (switch_string == atom::switches::kPpapiFlashPath ||
|
||||
switch_string == atom::switches::kClientCertificate ||
|
||||
if (base::EndsWith(switch_string, "-path",
|
||||
base::CompareCase::INSENSITIVE_ASCII) ||
|
||||
switch_string == switches::kLogNetLog) {
|
||||
base::FilePath path;
|
||||
args->GetNext(&path);
|
||||
@@ -452,6 +540,8 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
dict.SetMethod("dockBounce", &DockBounce);
|
||||
dict.SetMethod("dockCancelBounce",
|
||||
base::Bind(&Browser::DockCancelBounce, browser));
|
||||
dict.SetMethod("dockDownloadFinished",
|
||||
base::Bind(&Browser::DockDownloadFinished, browser));
|
||||
dict.SetMethod("dockSetBadgeText",
|
||||
base::Bind(&Browser::DockSetBadgeText, browser));
|
||||
dict.SetMethod("dockGetBadgeText",
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
#include "chrome/browser/process_singleton.h"
|
||||
#include "content/public/browser/gpu_data_manager_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/base/completion_callback.h"
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
#include "chrome/browser/certificate_manager_model.h"
|
||||
#endif
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
@@ -28,15 +33,32 @@ namespace atom {
|
||||
namespace api {
|
||||
|
||||
class App : public AtomBrowserClient::Delegate,
|
||||
public mate::EventEmitter,
|
||||
public mate::EventEmitter<App>,
|
||||
public BrowserObserver,
|
||||
public content::GpuDataManagerObserver {
|
||||
public:
|
||||
static mate::Handle<App> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
// Called when window with disposition needs to be created.
|
||||
void OnCreateWindow(const GURL& target_url,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
int render_process_id,
|
||||
int render_frame_id);
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void OnCertificateManagerModelCreated(
|
||||
scoped_ptr<base::DictionaryValue> options,
|
||||
const net::CompletionCallback& callback,
|
||||
scoped_ptr<CertificateManagerModel> model);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
App();
|
||||
virtual ~App();
|
||||
explicit App(v8::Isolate* isolate);
|
||||
~App() override;
|
||||
|
||||
// BrowserObserver:
|
||||
void OnBeforeQuit(bool* prevent_default) override;
|
||||
@@ -49,6 +71,12 @@ class App : public AtomBrowserClient::Delegate,
|
||||
void OnWillFinishLaunching() override;
|
||||
void OnFinishLaunching() override;
|
||||
void OnLogin(LoginHandler* login_handler) override;
|
||||
#if defined(OS_MACOSX)
|
||||
void OnContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) override;
|
||||
#endif
|
||||
|
||||
// content::ContentBrowserClient:
|
||||
void AllowCertificateError(
|
||||
@@ -70,14 +98,6 @@ class App : public AtomBrowserClient::Delegate,
|
||||
// content::GpuDataManagerObserver:
|
||||
void OnGpuProcessCrashed(base::TerminationStatus exit_code) override;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void OnPlatformThemeChanged() override;
|
||||
#endif
|
||||
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
// Get/Set the pre-defined path in PathService.
|
||||
base::FilePath GetPath(mate::Arguments* args, const std::string& name);
|
||||
@@ -86,17 +106,21 @@ class App : public AtomBrowserClient::Delegate,
|
||||
const base::FilePath& path);
|
||||
|
||||
void SetDesktopName(const std::string& desktop_name);
|
||||
void AllowNTLMCredentialsForAllDomains(bool should_allow);
|
||||
bool MakeSingleInstance(
|
||||
const ProcessSingleton::NotificationCallback& callback);
|
||||
std::string GetLocale();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool IsAeroGlassEnabled();
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void ImportCertificate(const base::DictionaryValue& options,
|
||||
const net::CompletionCallback& callback);
|
||||
#endif
|
||||
|
||||
scoped_ptr<ProcessSingleton> process_singleton_;
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
scoped_ptr<CertificateManagerModel> certificate_manager_model_;
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(App);
|
||||
};
|
||||
|
||||
|
||||
@@ -34,8 +34,9 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
AutoUpdater::AutoUpdater() {
|
||||
AutoUpdater::AutoUpdater(v8::Isolate* isolate) {
|
||||
auto_updater::AutoUpdater::SetDelegate(this);
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
AutoUpdater::~AutoUpdater() {
|
||||
@@ -78,14 +79,6 @@ void AutoUpdater::OnWindowAllClosed() {
|
||||
QuitAndInstall();
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder AutoUpdater::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("setFeedURL", &auto_updater::AutoUpdater::SetFeedURL)
|
||||
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
|
||||
.SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall);
|
||||
}
|
||||
|
||||
void AutoUpdater::QuitAndInstall() {
|
||||
// If we don't have any window then quitAndInstall immediately.
|
||||
WindowList* window_list = WindowList::GetInstance();
|
||||
@@ -102,7 +95,16 @@ void AutoUpdater::QuitAndInstall() {
|
||||
|
||||
// static
|
||||
mate::Handle<AutoUpdater> AutoUpdater::Create(v8::Isolate* isolate) {
|
||||
return CreateHandle(isolate, new AutoUpdater);
|
||||
return mate::CreateHandle(isolate, new AutoUpdater(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void AutoUpdater::BuildPrototype(
|
||||
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("setFeedURL", &auto_updater::AutoUpdater::SetFeedURL)
|
||||
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
|
||||
.SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -16,15 +16,18 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class AutoUpdater : public mate::EventEmitter,
|
||||
class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
|
||||
public auto_updater::Delegate,
|
||||
public WindowListObserver {
|
||||
public:
|
||||
static mate::Handle<AutoUpdater> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
protected:
|
||||
AutoUpdater();
|
||||
virtual ~AutoUpdater();
|
||||
explicit AutoUpdater(v8::Isolate* isolate);
|
||||
~AutoUpdater() override;
|
||||
|
||||
// Delegate implementations.
|
||||
void OnError(const std::string& error) override;
|
||||
@@ -39,10 +42,6 @@ class AutoUpdater : public mate::EventEmitter,
|
||||
// WindowListObserver:
|
||||
void OnWindowAllClosed() override;
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
void QuitAndInstall();
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ struct Converter<net::CanonicalCookie> {
|
||||
dict.Set("secure", val.IsSecure());
|
||||
dict.Set("httpOnly", val.IsHttpOnly());
|
||||
dict.Set("session", !val.IsPersistent());
|
||||
if (!val.IsPersistent())
|
||||
if (val.IsPersistent())
|
||||
dict.Set("expirationDate", val.ExpiryDate().ToDoubleT());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
@@ -133,12 +133,12 @@ void GetCookiesOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
auto filtered_callback =
|
||||
base::Bind(FilterCookies, base::Passed(&filter), callback);
|
||||
|
||||
net::CookieMonster* monster = GetCookieStore(getter)->GetCookieMonster();
|
||||
// Empty url will match all url cookies.
|
||||
if (url.empty())
|
||||
monster->GetAllCookiesAsync(filtered_callback);
|
||||
GetCookieStore(getter)->GetAllCookiesAsync(filtered_callback);
|
||||
else
|
||||
monster->GetAllCookiesForURLAsync(GURL(url), filtered_callback);
|
||||
GetCookieStore(getter)->GetAllCookiesForURLAsync(GURL(url),
|
||||
filtered_callback);
|
||||
}
|
||||
|
||||
// Removes cookie with |url| and |name| in IO thread.
|
||||
@@ -162,7 +162,9 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
std::string url, name, value, domain, path;
|
||||
bool secure = false;
|
||||
bool http_only = false;
|
||||
double creation_date;
|
||||
double expiration_date;
|
||||
double last_access_date;
|
||||
details->GetString("url", &url);
|
||||
details->GetString("name", &name);
|
||||
details->GetString("value", &value);
|
||||
@@ -171,6 +173,13 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
details->GetBoolean("secure", &secure);
|
||||
details->GetBoolean("httpOnly", &http_only);
|
||||
|
||||
base::Time creation_time;
|
||||
if (details->GetDouble("creationDate", &creation_date)) {
|
||||
creation_time = (creation_date == 0) ?
|
||||
base::Time::UnixEpoch() :
|
||||
base::Time::FromDoubleT(creation_date);
|
||||
}
|
||||
|
||||
base::Time expiration_time;
|
||||
if (details->GetDouble("expirationDate", &expiration_date)) {
|
||||
expiration_time = (expiration_date == 0) ?
|
||||
@@ -178,16 +187,26 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
base::Time::FromDoubleT(expiration_date);
|
||||
}
|
||||
|
||||
GetCookieStore(getter)->GetCookieMonster()->SetCookieWithDetailsAsync(
|
||||
GURL(url), name, value, domain, path, expiration_time, secure, http_only,
|
||||
false, false, false, net::COOKIE_PRIORITY_DEFAULT,
|
||||
base::Time last_access_time;
|
||||
if (details->GetDouble("lastAccessDate", &last_access_date)) {
|
||||
last_access_time = (last_access_date == 0) ?
|
||||
base::Time::UnixEpoch() :
|
||||
base::Time::FromDoubleT(last_access_date);
|
||||
}
|
||||
|
||||
GetCookieStore(getter)->SetCookieWithDetailsAsync(
|
||||
GURL(url), name, value, domain, path, creation_time,
|
||||
expiration_time, last_access_time, secure, http_only,
|
||||
false, false, net::COOKIE_PRIORITY_DEFAULT,
|
||||
base::Bind(OnSetCookie, callback));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Cookies::Cookies(content::BrowserContext* browser_context)
|
||||
: request_context_getter_(browser_context->GetRequestContext()) {
|
||||
Cookies::Cookies(v8::Isolate* isolate,
|
||||
content::BrowserContext* browser_context)
|
||||
: request_context_getter_(browser_context->GetRequestContext()) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
Cookies::~Cookies() {
|
||||
@@ -223,7 +242,7 @@ void Cookies::Set(const base::DictionaryValue& details,
|
||||
mate::Handle<Cookies> Cookies::Create(
|
||||
v8::Isolate* isolate,
|
||||
content::BrowserContext* browser_context) {
|
||||
return mate::CreateHandle(isolate, new Cookies(browser_context));
|
||||
return mate::CreateHandle(isolate, new Cookies(isolate, browser_context));
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -46,8 +46,8 @@ class Cookies : public mate::TrackableObject<Cookies> {
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit Cookies(content::BrowserContext* browser_context);
|
||||
~Cookies();
|
||||
Cookies(v8::Isolate* isolate, content::BrowserContext* browser_context);
|
||||
~Cookies() override;
|
||||
|
||||
void Get(const base::DictionaryValue& filter, const GetCallback& callback);
|
||||
void Remove(const GURL& url, const std::string& name,
|
||||
|
||||
@@ -31,9 +31,10 @@ WrapDebuggerCallback g_wrap_debugger;
|
||||
|
||||
} // namespace
|
||||
|
||||
Debugger::Debugger(content::WebContents* web_contents)
|
||||
Debugger::Debugger(v8::Isolate* isolate, content::WebContents* web_contents)
|
||||
: web_contents_(web_contents),
|
||||
previous_request_id_(0) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
Debugger::~Debugger() {
|
||||
@@ -150,7 +151,8 @@ void Debugger::SendCommand(mate::Arguments* args) {
|
||||
mate::Handle<Debugger> Debugger::Create(
|
||||
v8::Isolate* isolate,
|
||||
content::WebContents* web_contents) {
|
||||
auto handle = mate::CreateHandle(isolate, new Debugger(web_contents));
|
||||
auto handle = mate::CreateHandle(
|
||||
isolate, new Debugger(isolate, web_contents));
|
||||
g_wrap_debugger.Run(handle.ToV8());
|
||||
return handle;
|
||||
}
|
||||
@@ -165,16 +167,8 @@ void Debugger::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("sendCommand", &Debugger::SendCommand);
|
||||
}
|
||||
|
||||
void ClearWrapDebugger() {
|
||||
g_wrap_debugger.Reset();
|
||||
}
|
||||
|
||||
void SetWrapDebugger(const WrapDebuggerCallback& callback) {
|
||||
g_wrap_debugger = callback;
|
||||
|
||||
// Cleanup the wrapper on exit.
|
||||
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
|
||||
base::Bind(ClearWrapDebugger));
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -42,8 +42,8 @@ class Debugger: public mate::TrackableObject<Debugger>,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit Debugger(content::WebContents* web_contents);
|
||||
~Debugger();
|
||||
Debugger(v8::Isolate* isolate, content::WebContents* web_contents);
|
||||
~Debugger() override;
|
||||
|
||||
// content::DevToolsAgentHostClient:
|
||||
void AgentHostClosed(content::DevToolsAgentHost* agent_host,
|
||||
|
||||
@@ -38,7 +38,8 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
DesktopCapturer::DesktopCapturer() {
|
||||
DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
DesktopCapturer::~DesktopCapturer() {
|
||||
@@ -88,19 +89,19 @@ void DesktopCapturer::OnSourceThumbnailChanged(int index) {
|
||||
|
||||
bool DesktopCapturer::OnRefreshFinished() {
|
||||
Emit("finished", media_list_->GetSources());
|
||||
media_list_.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder DesktopCapturer::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new DesktopCapturer);
|
||||
return mate::CreateHandle(isolate, new DesktopCapturer(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void DesktopCapturer::BuildPrototype(
|
||||
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -14,18 +14,21 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class DesktopCapturer: public mate::EventEmitter,
|
||||
class DesktopCapturer: public mate::EventEmitter<DesktopCapturer>,
|
||||
public DesktopMediaListObserver {
|
||||
public:
|
||||
static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
void StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
const gfx::Size& thumbnail_size);
|
||||
|
||||
protected:
|
||||
DesktopCapturer();
|
||||
~DesktopCapturer();
|
||||
explicit DesktopCapturer(v8::Isolate* isolate);
|
||||
~DesktopCapturer() override;
|
||||
|
||||
// DesktopMediaListObserver overrides.
|
||||
void OnSourceAdded(int index) override;
|
||||
@@ -36,10 +39,6 @@ class DesktopCapturer: public mate::EventEmitter,
|
||||
bool OnRefreshFinished() override;
|
||||
|
||||
private:
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
scoped_ptr<DesktopMediaList> media_list_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DesktopCapturer);
|
||||
|
||||
@@ -67,6 +67,7 @@ void ShowMessageBox(int type,
|
||||
}
|
||||
|
||||
void ShowOpenDialog(const std::string& title,
|
||||
const std::string& button_label,
|
||||
const base::FilePath& default_path,
|
||||
const file_dialog::Filters& filters,
|
||||
int properties,
|
||||
@@ -77,17 +78,18 @@ void ShowOpenDialog(const std::string& title,
|
||||
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(args->isolate(),
|
||||
peek,
|
||||
&callback)) {
|
||||
file_dialog::ShowOpenDialog(window, title, default_path, filters,
|
||||
properties, callback);
|
||||
file_dialog::ShowOpenDialog(window, title, button_label, default_path,
|
||||
filters, properties, callback);
|
||||
} else {
|
||||
std::vector<base::FilePath> paths;
|
||||
if (file_dialog::ShowOpenDialog(window, title, default_path, filters,
|
||||
properties, &paths))
|
||||
if (file_dialog::ShowOpenDialog(window, title, button_label, default_path,
|
||||
filters, properties, &paths))
|
||||
args->Return(paths);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowSaveDialog(const std::string& title,
|
||||
const std::string& button_label,
|
||||
const base::FilePath& default_path,
|
||||
const file_dialog::Filters& filters,
|
||||
atom::NativeWindow* window,
|
||||
@@ -97,11 +99,12 @@ void ShowSaveDialog(const std::string& title,
|
||||
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(args->isolate(),
|
||||
peek,
|
||||
&callback)) {
|
||||
file_dialog::ShowSaveDialog(window, title, default_path, filters, callback);
|
||||
file_dialog::ShowSaveDialog(window, title, button_label, default_path,
|
||||
filters, callback);
|
||||
} else {
|
||||
base::FilePath path;
|
||||
if (file_dialog::ShowSaveDialog(window, title, default_path, filters,
|
||||
&path))
|
||||
if (file_dialog::ShowSaveDialog(window, title, button_label, default_path,
|
||||
filters, &path))
|
||||
args->Return(path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,9 +57,11 @@ std::map<uint32_t, linked_ptr<v8::Global<v8::Value>>> g_download_item_objects;
|
||||
|
||||
} // namespace
|
||||
|
||||
DownloadItem::DownloadItem(content::DownloadItem* download_item)
|
||||
DownloadItem::DownloadItem(v8::Isolate* isolate,
|
||||
content::DownloadItem* download_item)
|
||||
: download_item_(download_item) {
|
||||
download_item_->AddObserver(this);
|
||||
Init(isolate);
|
||||
AttachAsUserData(download_item);
|
||||
}
|
||||
|
||||
@@ -173,7 +175,7 @@ mate::Handle<DownloadItem> DownloadItem::Create(
|
||||
if (existing)
|
||||
return mate::CreateHandle(isolate, static_cast<DownloadItem*>(existing));
|
||||
|
||||
auto handle = mate::CreateHandle(isolate, new DownloadItem(item));
|
||||
auto handle = mate::CreateHandle(isolate, new DownloadItem(isolate, item));
|
||||
g_wrap_download_item.Run(handle.ToV8());
|
||||
|
||||
// Reference this object in case it got garbage collected.
|
||||
@@ -182,16 +184,8 @@ mate::Handle<DownloadItem> DownloadItem::Create(
|
||||
return handle;
|
||||
}
|
||||
|
||||
void ClearWrapDownloadItem() {
|
||||
g_wrap_download_item.Reset();
|
||||
}
|
||||
|
||||
void SetWrapDownloadItem(const WrapDownloadItemCallback& callback) {
|
||||
g_wrap_download_item = callback;
|
||||
|
||||
// Cleanup the wrapper on exit.
|
||||
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
|
||||
base::Bind(ClearWrapDownloadItem));
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -23,7 +23,6 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
||||
static mate::Handle<DownloadItem> Create(v8::Isolate* isolate,
|
||||
content::DownloadItem* item);
|
||||
|
||||
// mate::TrackableObject:
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
@@ -41,7 +40,7 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
||||
base::FilePath GetSavePath() const;
|
||||
|
||||
protected:
|
||||
explicit DownloadItem(content::DownloadItem* download_item);
|
||||
DownloadItem(v8::Isolate* isolate, content::DownloadItem* download_item);
|
||||
~DownloadItem();
|
||||
|
||||
// Override content::DownloadItem::Observer methods
|
||||
|
||||
@@ -19,7 +19,8 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
GlobalShortcut::GlobalShortcut() {
|
||||
GlobalShortcut::GlobalShortcut(v8::Isolate* isolate) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
GlobalShortcut::~GlobalShortcut() {
|
||||
@@ -66,20 +67,21 @@ void GlobalShortcut::UnregisterAll() {
|
||||
GlobalShortcutListener::GetInstance()->UnregisterAccelerators(this);
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder GlobalShortcut::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
// static
|
||||
mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new GlobalShortcut(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void GlobalShortcut::BuildPrototype(
|
||||
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("register", &GlobalShortcut::Register)
|
||||
.SetMethod("isRegistered", &GlobalShortcut::IsRegistered)
|
||||
.SetMethod("unregister", &GlobalShortcut::Unregister)
|
||||
.SetMethod("unregisterAll", &GlobalShortcut::UnregisterAll);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
|
||||
return CreateHandle(isolate, new GlobalShortcut);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -23,13 +23,12 @@ class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
|
||||
public:
|
||||
static mate::Handle<GlobalShortcut> Create(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
GlobalShortcut();
|
||||
~GlobalShortcut() override;
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
protected:
|
||||
explicit GlobalShortcut(v8::Isolate* isolate);
|
||||
~GlobalShortcut() override;
|
||||
|
||||
private:
|
||||
typedef std::map<ui::Accelerator, base::Closure> AcceleratorCallbackMap;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
Menu::Menu()
|
||||
Menu::Menu(v8::Isolate* isolate)
|
||||
: model_(new AtomMenuModel(this)),
|
||||
parent_(NULL) {
|
||||
}
|
||||
@@ -28,7 +28,7 @@ Menu::~Menu() {
|
||||
}
|
||||
|
||||
void Menu::AfterInit(v8::Isolate* isolate) {
|
||||
mate::Dictionary wrappable(isolate, GetWrapper(isolate));
|
||||
mate::Dictionary wrappable(isolate, GetWrapper());
|
||||
mate::Dictionary delegate;
|
||||
if (!wrappable.Get("delegate", &delegate))
|
||||
return;
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace api {
|
||||
class Menu : public mate::TrackableObject<Menu>,
|
||||
public AtomMenuModel::Delegate {
|
||||
public:
|
||||
static mate::Wrappable* Create();
|
||||
static mate::WrappableBase* Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
@@ -36,7 +36,7 @@ class Menu : public mate::TrackableObject<Menu>,
|
||||
AtomMenuModel* model() const { return model_.get(); }
|
||||
|
||||
protected:
|
||||
Menu();
|
||||
explicit Menu(v8::Isolate* isolate);
|
||||
~Menu() override;
|
||||
|
||||
// mate::Wrappable:
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace api {
|
||||
|
||||
class MenuMac : public Menu {
|
||||
protected:
|
||||
MenuMac();
|
||||
explicit MenuMac(v8::Isolate* isolate);
|
||||
|
||||
void PopupAt(Window* window, int x, int y, int positioning_item = 0) override;
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "base/message_loop/message_loop.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/web_contents.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
@@ -15,21 +17,22 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
MenuMac::MenuMac() {
|
||||
MenuMac::MenuMac(v8::Isolate* isolate) : Menu(isolate) {
|
||||
}
|
||||
|
||||
void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
|
||||
NativeWindow* native_window = window->window();
|
||||
if (!native_window)
|
||||
return;
|
||||
content::WebContents* web_contents = native_window->web_contents();
|
||||
brightray::InspectableWebContents* web_contents =
|
||||
native_window->inspectable_web_contents();
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller(
|
||||
[[AtomMenuController alloc] initWithModel:model_.get()]);
|
||||
NSMenu* menu = [menu_controller menu];
|
||||
NSView* view = web_contents->GetContentNativeView();
|
||||
NSView* view = web_contents->GetView()->GetNativeView();
|
||||
|
||||
// Which menu item to show.
|
||||
NSMenuItem* item = nil;
|
||||
@@ -46,6 +49,20 @@ void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
|
||||
position = NSMakePoint(x, [view frame].size.height - y);
|
||||
}
|
||||
|
||||
// If no preferred item is specified, try to show all of the menu items.
|
||||
if (!positioning_item) {
|
||||
CGFloat windowBottom = CGRectGetMinY([view window].frame);
|
||||
CGFloat distaceFromBottom = windowBottom + position.y - [menu size].height;
|
||||
if (distaceFromBottom < 0)
|
||||
position.y = position.y - distaceFromBottom + 4;
|
||||
}
|
||||
|
||||
// Place the menu left of cursor if it is overflowing off right of screen.
|
||||
CGFloat windowLeft = CGRectGetMinX([view window].frame);
|
||||
CGFloat rightmostPoint = windowLeft + position.x + [menu size].width;
|
||||
if (rightmostPoint > [[NSScreen mainScreen] visibleFrame].size.width)
|
||||
position.x = position.x - [menu size].width;
|
||||
|
||||
// Show the menu.
|
||||
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
|
||||
}
|
||||
@@ -68,8 +85,8 @@ void Menu::SendActionToFirstResponder(const std::string& action) {
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Wrappable* Menu::Create() {
|
||||
return new MenuMac();
|
||||
mate::WrappableBase* Menu::Create(v8::Isolate* isolate) {
|
||||
return new MenuMac(isolate);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
MenuViews::MenuViews() {
|
||||
MenuViews::MenuViews(v8::Isolate* isolate) : Menu(isolate) {
|
||||
}
|
||||
|
||||
void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
|
||||
@@ -30,7 +30,7 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
|
||||
// (-1, -1) means showing on mouse location.
|
||||
gfx::Point location;
|
||||
if (x == -1 || y == -1) {
|
||||
location = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
|
||||
location = gfx::Screen::GetScreen()->GetCursorScreenPoint();
|
||||
} else {
|
||||
gfx::Point origin = view->GetViewBounds().origin();
|
||||
location = gfx::Point(origin.x() + x, origin.y() + y);
|
||||
@@ -49,8 +49,8 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Wrappable* Menu::Create() {
|
||||
return new MenuViews();
|
||||
mate::WrappableBase* Menu::Create(v8::Isolate* isolate) {
|
||||
return new MenuViews(isolate);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace api {
|
||||
|
||||
class MenuViews : public Menu {
|
||||
public:
|
||||
MenuViews();
|
||||
explicit MenuViews(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
void PopupAt(Window* window, int x, int y, int positioning_item = 0) override;
|
||||
|
||||
@@ -14,8 +14,9 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
PowerMonitor::PowerMonitor() {
|
||||
PowerMonitor::PowerMonitor(v8::Isolate* isolate) {
|
||||
base::PowerMonitor::Get()->AddObserver(this);
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
PowerMonitor::~PowerMonitor() {
|
||||
@@ -46,7 +47,13 @@ v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
return CreateHandle(isolate, new PowerMonitor).ToV8();
|
||||
return mate::CreateHandle(isolate, new PowerMonitor(isolate)).ToV8();
|
||||
}
|
||||
|
||||
// static
|
||||
void PowerMonitor::BuildPrototype(
|
||||
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -19,8 +19,11 @@ class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
|
||||
public:
|
||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
protected:
|
||||
PowerMonitor();
|
||||
explicit PowerMonitor(v8::Isolate* isolate);
|
||||
~PowerMonitor() override;
|
||||
|
||||
// base::PowerObserver implementations:
|
||||
|
||||
@@ -37,9 +37,10 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
PowerSaveBlocker::PowerSaveBlocker()
|
||||
PowerSaveBlocker::PowerSaveBlocker(v8::Isolate* isolate)
|
||||
: current_blocker_type_(
|
||||
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
|
||||
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
PowerSaveBlocker::~PowerSaveBlocker() {
|
||||
@@ -97,17 +98,18 @@ bool PowerSaveBlocker::IsStarted(int id) {
|
||||
return power_save_blocker_types_.find(id) != power_save_blocker_types_.end();
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder PowerSaveBlocker::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("start", &PowerSaveBlocker::Start)
|
||||
.SetMethod("stop", &PowerSaveBlocker::Stop)
|
||||
.SetMethod("isStarted", &PowerSaveBlocker::IsStarted);
|
||||
// static
|
||||
mate::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new PowerSaveBlocker(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) {
|
||||
return CreateHandle(isolate, new PowerSaveBlocker);
|
||||
void PowerSaveBlocker::BuildPrototype(
|
||||
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("start", &PowerSaveBlocker::Start)
|
||||
.SetMethod("stop", &PowerSaveBlocker::Stop)
|
||||
.SetMethod("isStarted", &PowerSaveBlocker::IsStarted);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -24,13 +24,12 @@ class PowerSaveBlocker : public mate::TrackableObject<PowerSaveBlocker> {
|
||||
public:
|
||||
static mate::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
PowerSaveBlocker();
|
||||
~PowerSaveBlocker() override;
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
protected:
|
||||
explicit PowerSaveBlocker(v8::Isolate* isolate);
|
||||
~PowerSaveBlocker() override;
|
||||
|
||||
private:
|
||||
void UpdatePowerSaveBlocker();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "url/url_util.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
@@ -22,42 +23,11 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
Protocol::Protocol(AtomBrowserContext* browser_context)
|
||||
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
: request_context_getter_(browser_context->GetRequestContext()),
|
||||
job_factory_(browser_context->job_factory()) {
|
||||
CHECK(job_factory_);
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes)
|
||||
.SetMethod("registerServiceWorkerSchemes",
|
||||
&Protocol::RegisterServiceWorkerSchemes)
|
||||
.SetMethod("registerStringProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestStringJob>)
|
||||
.SetMethod("registerBufferProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestBufferJob>)
|
||||
.SetMethod("registerFileProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestAsyncAsarJob>)
|
||||
.SetMethod("registerHttpProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
|
||||
.SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled)
|
||||
.SetMethod("interceptStringProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestStringJob>)
|
||||
.SetMethod("interceptBufferProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestBufferJob>)
|
||||
.SetMethod("interceptFileProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestAsyncAsarJob>)
|
||||
.SetMethod("interceptHttpProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
|
||||
}
|
||||
|
||||
void Protocol::RegisterStandardSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
atom::AtomBrowserClient::SetCustomSchemes(schemes);
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
void Protocol::RegisterServiceWorkerSchemes(
|
||||
@@ -150,7 +120,34 @@ std::string Protocol::ErrorCodeToString(ProtocolError error) {
|
||||
// static
|
||||
mate::Handle<Protocol> Protocol::Create(
|
||||
v8::Isolate* isolate, AtomBrowserContext* browser_context) {
|
||||
return mate::CreateHandle(isolate, new Protocol(browser_context));
|
||||
return mate::CreateHandle(isolate, new Protocol(isolate, browser_context));
|
||||
}
|
||||
|
||||
// static
|
||||
void Protocol::BuildPrototype(
|
||||
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("registerServiceWorkerSchemes",
|
||||
&Protocol::RegisterServiceWorkerSchemes)
|
||||
.SetMethod("registerStringProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestStringJob>)
|
||||
.SetMethod("registerBufferProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestBufferJob>)
|
||||
.SetMethod("registerFileProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestAsyncAsarJob>)
|
||||
.SetMethod("registerHttpProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
|
||||
.SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled)
|
||||
.SetMethod("interceptStringProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestStringJob>)
|
||||
.SetMethod("interceptBufferProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestBufferJob>)
|
||||
.SetMethod("interceptFileProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestAsyncAsarJob>)
|
||||
.SetMethod("interceptHttpProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
@@ -159,13 +156,24 @@ mate::Handle<Protocol> Protocol::Create(
|
||||
|
||||
namespace {
|
||||
|
||||
void RegisterStandardSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
for (const auto& scheme : schemes)
|
||||
url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT);
|
||||
}
|
||||
|
||||
mate::Handle<atom::api::Protocol> CreateProtocol(v8::Isolate* isolate) {
|
||||
auto browser_context = static_cast<atom::AtomBrowserContext*>(
|
||||
atom::AtomBrowserMainParts::Get()->browser_context());
|
||||
return atom::api::Protocol::Create(isolate, browser_context);
|
||||
}
|
||||
|
||||
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);
|
||||
auto browser_context = static_cast<atom::AtomBrowserContext*>(
|
||||
atom::AtomBrowserMainParts::Get()->browser_context());
|
||||
dict.Set("protocol", atom::api::Protocol::Create(isolate, browser_context));
|
||||
dict.SetMethod("createProtocolObject", base::Bind(&CreateProtocol, isolate));
|
||||
dict.SetMethod("registerStandardSchemes", &RegisterStandardSchemes);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -30,7 +30,7 @@ class AtomURLRequestJobFactory;
|
||||
|
||||
namespace api {
|
||||
|
||||
class Protocol : public mate::Wrappable {
|
||||
class Protocol : public mate::Wrappable<Protocol> {
|
||||
public:
|
||||
using Handler =
|
||||
base::Callback<void(const net::URLRequest*, v8::Local<v8::Value>)>;
|
||||
@@ -40,12 +40,11 @@ class Protocol : public mate::Wrappable {
|
||||
static mate::Handle<Protocol> Create(
|
||||
v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
|
||||
protected:
|
||||
explicit Protocol(AtomBrowserContext* browser_context);
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate);
|
||||
protected:
|
||||
Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
|
||||
private:
|
||||
// Possible errors.
|
||||
@@ -89,9 +88,6 @@ class Protocol : public mate::Wrappable {
|
||||
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
|
||||
};
|
||||
|
||||
// Register schemes to standard scheme list.
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes);
|
||||
|
||||
// Register schemes that can handle service worker.
|
||||
void RegisterServiceWorkerSchemes(const std::vector<std::string>& schemes);
|
||||
|
||||
|
||||
@@ -47,9 +47,10 @@ std::vector<std::string> MetricsToArray(uint32_t metrics) {
|
||||
|
||||
} // namespace
|
||||
|
||||
Screen::Screen(gfx::Screen* screen) : screen_(screen) {
|
||||
displays_ = screen_->GetAllDisplays();
|
||||
Screen::Screen(v8::Isolate* isolate, gfx::Screen* screen)
|
||||
: screen_(screen) {
|
||||
screen_->AddObserver(this);
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
Screen::~Screen() {
|
||||
@@ -65,7 +66,7 @@ gfx::Display Screen::GetPrimaryDisplay() {
|
||||
}
|
||||
|
||||
std::vector<gfx::Display> Screen::GetAllDisplays() {
|
||||
return displays_;
|
||||
return screen_->GetAllDisplays();
|
||||
}
|
||||
|
||||
gfx::Display Screen::GetDisplayNearestPoint(const gfx::Point& point) {
|
||||
@@ -77,39 +78,18 @@ gfx::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) {
|
||||
}
|
||||
|
||||
void Screen::OnDisplayAdded(const gfx::Display& new_display) {
|
||||
displays_.push_back(new_display);
|
||||
Emit("display-added", new_display);
|
||||
}
|
||||
|
||||
void Screen::OnDisplayRemoved(const gfx::Display& old_display) {
|
||||
auto iter = FindById(&displays_, old_display.id());
|
||||
if (iter == displays_.end())
|
||||
return;
|
||||
|
||||
displays_.erase(iter);
|
||||
Emit("display-removed", old_display);
|
||||
}
|
||||
|
||||
void Screen::OnDisplayMetricsChanged(const gfx::Display& display,
|
||||
uint32_t changed_metrics) {
|
||||
auto iter = FindById(&displays_, display.id());
|
||||
if (iter == displays_.end())
|
||||
return;
|
||||
|
||||
*iter = display;
|
||||
Emit("display-metrics-changed", display, MetricsToArray(changed_metrics));
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder Screen::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint)
|
||||
.SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
|
||||
.SetMethod("getAllDisplays", &Screen::GetAllDisplays)
|
||||
.SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint)
|
||||
.SetMethod("getDisplayMatching", &Screen::GetDisplayMatching);
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
@@ -119,14 +99,25 @@ v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
gfx::Screen* screen = gfx::Screen::GetNativeScreen();
|
||||
gfx::Screen* screen = gfx::Screen::GetScreen();
|
||||
if (!screen) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate, "Failed to get screen information")));
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
return mate::CreateHandle(isolate, new Screen(screen)).ToV8();
|
||||
return mate::CreateHandle(isolate, new Screen(isolate, screen)).ToV8();
|
||||
}
|
||||
|
||||
// static
|
||||
void Screen::BuildPrototype(
|
||||
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint)
|
||||
.SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
|
||||
.SetMethod("getAllDisplays", &Screen::GetAllDisplays)
|
||||
.SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint)
|
||||
.SetMethod("getDisplayMatching", &Screen::GetDisplayMatching);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -21,14 +21,17 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Screen : public mate::EventEmitter,
|
||||
class Screen : public mate::EventEmitter<Screen>,
|
||||
public gfx::DisplayObserver {
|
||||
public:
|
||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit Screen(gfx::Screen* screen);
|
||||
virtual ~Screen();
|
||||
Screen(v8::Isolate* isolate, gfx::Screen* screen);
|
||||
~Screen() override;
|
||||
|
||||
gfx::Point GetCursorScreenPoint();
|
||||
gfx::Display GetPrimaryDisplay();
|
||||
@@ -42,13 +45,8 @@ class Screen : public mate::EventEmitter,
|
||||
void OnDisplayMetricsChanged(const gfx::Display& display,
|
||||
uint32_t changed_metrics) override;
|
||||
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
gfx::Screen* screen_;
|
||||
std::vector<gfx::Display> displays_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Screen);
|
||||
};
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
|
||||
#include "atom/browser/api/atom_api_cookies.h"
|
||||
#include "atom/browser/api/atom_api_download_item.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/api/atom_api_web_request.h"
|
||||
#include "atom/browser/api/save_page_handler.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_permission_manager.h"
|
||||
@@ -23,12 +21,13 @@
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/prefs/pref_service.h"
|
||||
#include "base/guid.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/thread_task_runner_handle.h"
|
||||
#include "brightray/browser/net/devtools_network_conditions.h"
|
||||
#include "brightray/browser/net/devtools_network_controller.h"
|
||||
#include "brightray/browser/net/devtools_network_controller_handle.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
@@ -37,6 +36,8 @@
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/disk_cache/disk_cache.h"
|
||||
#include "net/dns/host_cache.h"
|
||||
#include "net/http/http_auth_handler_factory.h"
|
||||
#include "net/http/http_auth_preferences.h"
|
||||
#include "net/proxy/proxy_service.h"
|
||||
#include "net/proxy/proxy_config_service_fixed.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
@@ -285,15 +286,30 @@ void ClearHostResolverCacheInIO(
|
||||
}
|
||||
}
|
||||
|
||||
void AllowNTLMCredentialsForDomainsInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
const std::string& domains) {
|
||||
auto request_context = context_getter->GetURLRequestContext();
|
||||
auto auth_handler = request_context->http_auth_handler_factory();
|
||||
if (auth_handler) {
|
||||
auto auth_preferences = const_cast<net::HttpAuthPreferences*>(
|
||||
auth_handler->http_auth_preferences());
|
||||
if (auth_preferences)
|
||||
auth_preferences->set_server_whitelist(domains);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Session::Session(AtomBrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
AttachAsUserData(browser_context);
|
||||
|
||||
Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
: devtools_network_emulation_client_id_(base::GenerateGUID()),
|
||||
browser_context_(browser_context) {
|
||||
// Observe DownloadManger to get download notifications.
|
||||
content::BrowserContext::GetDownloadManager(browser_context)->
|
||||
AddObserver(this);
|
||||
|
||||
Init(isolate);
|
||||
AttachAsUserData(browser_context);
|
||||
}
|
||||
|
||||
Session::~Session() {
|
||||
@@ -303,13 +319,15 @@ Session::~Session() {
|
||||
|
||||
void Session::OnDownloadCreated(content::DownloadManager* manager,
|
||||
content::DownloadItem* item) {
|
||||
auto web_contents = item->GetWebContents();
|
||||
if (SavePageHandler::IsSavePageTypes(item->GetMimeType()))
|
||||
if (item->IsSavePackageDownload())
|
||||
return;
|
||||
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
bool prevent_default = Emit(
|
||||
"will-download",
|
||||
DownloadItem::Create(isolate(), item),
|
||||
api::WebContents::CreateFrom(isolate(), web_contents));
|
||||
item->GetWebContents());
|
||||
if (prevent_default) {
|
||||
item->Cancel(true);
|
||||
item->Remove();
|
||||
@@ -381,25 +399,19 @@ void Session::EnableNetworkEmulation(const mate::Dictionary& options) {
|
||||
download_throughput,
|
||||
upload_throughput));
|
||||
}
|
||||
auto controller = browser_context_->GetDevToolsNetworkController();
|
||||
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&brightray::DevToolsNetworkController::SetNetworkState,
|
||||
base::Unretained(controller),
|
||||
std::string(),
|
||||
base::Passed(&conditions)));
|
||||
browser_context_->network_controller_handle()->SetNetworkState(
|
||||
devtools_network_emulation_client_id_, std::move(conditions));
|
||||
browser_context_->network_delegate()->SetDevToolsNetworkEmulationClientId(
|
||||
devtools_network_emulation_client_id_);
|
||||
}
|
||||
|
||||
void Session::DisableNetworkEmulation() {
|
||||
scoped_ptr<brightray::DevToolsNetworkConditions> conditions(
|
||||
new brightray::DevToolsNetworkConditions(false));
|
||||
auto controller = browser_context_->GetDevToolsNetworkController();
|
||||
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&brightray::DevToolsNetworkController::SetNetworkState,
|
||||
base::Unretained(controller),
|
||||
std::string(),
|
||||
base::Passed(&conditions)));
|
||||
scoped_ptr<brightray::DevToolsNetworkConditions> conditions;
|
||||
browser_context_->network_controller_handle()->SetNetworkState(
|
||||
devtools_network_emulation_client_id_, std::move(conditions));
|
||||
browser_context_->network_delegate()->SetDevToolsNetworkEmulationClientId(
|
||||
std::string());
|
||||
}
|
||||
|
||||
void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
|
||||
@@ -435,6 +447,13 @@ void Session::ClearHostResolverCache(mate::Arguments* args) {
|
||||
callback));
|
||||
}
|
||||
|
||||
void Session::AllowNTLMCredentialsForDomains(const std::string& domains) {
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&AllowNTLMCredentialsForDomainsInIO,
|
||||
make_scoped_refptr(browser_context_->GetRequestContext()),
|
||||
domains));
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
|
||||
if (cookies_.IsEmpty()) {
|
||||
auto handle = atom::api::Cookies::Create(isolate, browser_context());
|
||||
@@ -458,7 +477,8 @@ mate::Handle<Session> Session::CreateFrom(
|
||||
if (existing)
|
||||
return mate::CreateHandle(isolate, static_cast<Session*>(existing));
|
||||
|
||||
auto handle = mate::CreateHandle(isolate, new Session(browser_context));
|
||||
auto handle = mate::CreateHandle(
|
||||
isolate, new Session(isolate, browser_context));
|
||||
g_wrap_session.Run(handle.ToV8());
|
||||
return handle;
|
||||
}
|
||||
@@ -489,20 +509,14 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setPermissionRequestHandler",
|
||||
&Session::SetPermissionRequestHandler)
|
||||
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
|
||||
.SetMethod("allowNTLMCredentialsForDomains",
|
||||
&Session::AllowNTLMCredentialsForDomains)
|
||||
.SetProperty("cookies", &Session::Cookies)
|
||||
.SetProperty("webRequest", &Session::WebRequest);
|
||||
}
|
||||
|
||||
void ClearWrapSession() {
|
||||
g_wrap_session.Reset();
|
||||
}
|
||||
|
||||
void SetWrapSession(const WrapSessionCallback& callback) {
|
||||
g_wrap_session = callback;
|
||||
|
||||
// Cleanup the wrapper on exit.
|
||||
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
|
||||
base::Bind(ClearWrapSession));
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -58,7 +58,7 @@ class Session: public mate::TrackableObject<Session>,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit Session(AtomBrowserContext* browser_context);
|
||||
Session(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
~Session();
|
||||
|
||||
// content::DownloadManager::Observer:
|
||||
@@ -79,6 +79,7 @@ class Session: public mate::TrackableObject<Session>,
|
||||
void SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args);
|
||||
void ClearHostResolverCache(mate::Arguments* args);
|
||||
void AllowNTLMCredentialsForDomains(const std::string& domains);
|
||||
v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
|
||||
|
||||
@@ -86,6 +87,9 @@ class Session: public mate::TrackableObject<Session>,
|
||||
v8::Global<v8::Value> cookies_;
|
||||
v8::Global<v8::Value> web_request_;
|
||||
|
||||
// The X-DevTools-Emulate-Network-Conditions-Client-Id.
|
||||
std::string devtools_network_emulation_client_id_;
|
||||
|
||||
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Session);
|
||||
|
||||
76
atom/browser/api/atom_api_system_preferences.cc
Normal file
76
atom/browser/api/atom_api_system_preferences.cc
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright (c) 2016 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_system_preferences.h"
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "ui/base/win/shell.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
SystemPreferences::SystemPreferences(v8::Isolate* isolate) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
SystemPreferences::~SystemPreferences() {
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool SystemPreferences::IsAeroGlassEnabled() {
|
||||
return ui::win::IsAeroGlassEnabled();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
bool SystemPreferences::IsDarkMode() {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
mate::Handle<SystemPreferences> SystemPreferences::Create(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new SystemPreferences(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void SystemPreferences::BuildPrototype(
|
||||
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("isAeroGlassEnabled", &SystemPreferences::IsAeroGlassEnabled)
|
||||
#elif defined(OS_MACOSX)
|
||||
.SetMethod("subscribeNotification",
|
||||
&SystemPreferences::SubscribeNotification)
|
||||
.SetMethod("unsubscribeNotification",
|
||||
&SystemPreferences::UnsubscribeNotification)
|
||||
.SetMethod("getUserDefault", &SystemPreferences::GetUserDefault)
|
||||
#endif
|
||||
.SetMethod("isDarkMode", &SystemPreferences::IsDarkMode);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
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("systemPreferences", atom::api::SystemPreferences::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_system_preferences, Initialize);
|
||||
57
atom/browser/api/atom_api_system_preferences.h
Normal file
57
atom/browser/api/atom_api_system_preferences.h
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2016 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_SYSTEM_PREFERENCES_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "base/callback.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class SystemPreferences : public mate::EventEmitter<SystemPreferences> {
|
||||
public:
|
||||
static mate::Handle<SystemPreferences> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
using NotificationCallback = base::Callback<
|
||||
void(const std::string&, const base::DictionaryValue&)>;
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool IsAeroGlassEnabled();
|
||||
#elif defined(OS_MACOSX)
|
||||
int SubscribeNotification(const std::string& name,
|
||||
const NotificationCallback& callback);
|
||||
void UnsubscribeNotification(int id);
|
||||
v8::Local<v8::Value> GetUserDefault(const std::string& name,
|
||||
const std::string& type);
|
||||
#endif
|
||||
bool IsDarkMode();
|
||||
|
||||
protected:
|
||||
explicit SystemPreferences(v8::Isolate* isolate);
|
||||
~SystemPreferences() override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(SystemPreferences);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_
|
||||
95
atom/browser/api/atom_api_system_preferences_mac.mm
Normal file
95
atom/browser/api/atom_api_system_preferences_mac.mm
Normal file
@@ -0,0 +1,95 @@
|
||||
// Copyright (c) 2016 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_system_preferences.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/values.h"
|
||||
#include "net/base/mac/url_conversions.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
int g_next_id = 0;
|
||||
|
||||
// The map to convert |id| to |int|.
|
||||
std::map<int, id> g_id_map;
|
||||
|
||||
} // namespace
|
||||
|
||||
int SystemPreferences::SubscribeNotification(
|
||||
const std::string& name, const NotificationCallback& callback) {
|
||||
int request_id = g_next_id++;
|
||||
__block NotificationCallback copied_callback = callback;
|
||||
g_id_map[request_id] = [[NSDistributedNotificationCenter defaultCenter]
|
||||
addObserverForName:base::SysUTF8ToNSString(name)
|
||||
object:nil
|
||||
queue:nil
|
||||
usingBlock:^(NSNotification* notification) {
|
||||
scoped_ptr<base::DictionaryValue> user_info =
|
||||
NSDictionaryToDictionaryValue(notification.userInfo);
|
||||
if (user_info) {
|
||||
copied_callback.Run(
|
||||
base::SysNSStringToUTF8(notification.name),
|
||||
*user_info);
|
||||
} else {
|
||||
copied_callback.Run(
|
||||
base::SysNSStringToUTF8(notification.name),
|
||||
base::DictionaryValue());
|
||||
}
|
||||
}
|
||||
];
|
||||
return request_id;
|
||||
}
|
||||
|
||||
void SystemPreferences::UnsubscribeNotification(int request_id) {
|
||||
auto iter = g_id_map.find(request_id);
|
||||
if (iter != g_id_map.end()) {
|
||||
id observer = iter->second;
|
||||
[[NSDistributedNotificationCenter defaultCenter] removeObserver:observer];
|
||||
g_id_map.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> SystemPreferences::GetUserDefault(
|
||||
const std::string& name, const std::string& type) {
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSString* key = base::SysUTF8ToNSString(name);
|
||||
if (type == "string") {
|
||||
return mate::StringToV8(
|
||||
isolate(), base::SysNSStringToUTF8([defaults stringForKey:key]));
|
||||
} else if (type == "boolean") {
|
||||
return v8::Boolean::New(isolate(), [defaults boolForKey:key]);
|
||||
} else if (type == "float") {
|
||||
return v8::Number::New(isolate(), [defaults floatForKey:key]);
|
||||
} else if (type == "integer") {
|
||||
return v8::Integer::New(isolate(), [defaults integerForKey:key]);
|
||||
} else if (type == "double") {
|
||||
return v8::Number::New(isolate(), [defaults doubleForKey:key]);
|
||||
} else if (type == "url") {
|
||||
return mate::ConvertToV8(
|
||||
isolate(), net::GURLWithNSURL([defaults URLForKey:key]));
|
||||
} else {
|
||||
return v8::Undefined(isolate());
|
||||
}
|
||||
}
|
||||
|
||||
bool SystemPreferences::IsDarkMode() {
|
||||
NSString* mode = [[NSUserDefaults standardUserDefaults]
|
||||
stringForKey:@"AppleInterfaceStyle"];
|
||||
return [mode isEqualToString:@"Dark"];
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/ui/tray_icon.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/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
@@ -22,9 +23,9 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
Tray::Tray(const gfx::Image& image)
|
||||
Tray::Tray(v8::Isolate* isolate, mate::Handle<NativeImage> image)
|
||||
: tray_icon_(TrayIcon::Create()) {
|
||||
tray_icon_->SetImage(image);
|
||||
SetImage(isolate, image);
|
||||
tray_icon_->AddObserver(this);
|
||||
}
|
||||
|
||||
@@ -32,13 +33,14 @@ Tray::~Tray() {
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) {
|
||||
mate::WrappableBase* Tray::New(v8::Isolate* isolate,
|
||||
mate::Handle<NativeImage> image) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate, "Cannot create Tray before app is ready")));
|
||||
return nullptr;
|
||||
}
|
||||
return new Tray(image);
|
||||
return new Tray(isolate, image);
|
||||
}
|
||||
|
||||
void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
@@ -94,29 +96,38 @@ void Tray::OnDragEnded() {
|
||||
Emit("drag-end");
|
||||
}
|
||||
|
||||
void Tray::SetImage(mate::Arguments* args, const gfx::Image& image) {
|
||||
tray_icon_->SetImage(image);
|
||||
void Tray::SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image) {
|
||||
#if defined(OS_WIN)
|
||||
tray_icon_->SetImage(image->GetHICON(GetSystemMetrics(SM_CXSMICON)));
|
||||
#else
|
||||
tray_icon_->SetImage(image->image());
|
||||
#endif
|
||||
}
|
||||
|
||||
void Tray::SetPressedImage(mate::Arguments* args, const gfx::Image& image) {
|
||||
tray_icon_->SetPressedImage(image);
|
||||
void Tray::SetPressedImage(v8::Isolate* isolate,
|
||||
mate::Handle<NativeImage> image) {
|
||||
#if defined(OS_WIN)
|
||||
tray_icon_->SetPressedImage(image->GetHICON(GetSystemMetrics(SM_CXSMICON)));
|
||||
#else
|
||||
tray_icon_->SetPressedImage(image->image());
|
||||
#endif
|
||||
}
|
||||
|
||||
void Tray::SetToolTip(mate::Arguments* args, const std::string& tool_tip) {
|
||||
void Tray::SetToolTip(const std::string& tool_tip) {
|
||||
tray_icon_->SetToolTip(tool_tip);
|
||||
}
|
||||
|
||||
void Tray::SetTitle(mate::Arguments* args, const std::string& title) {
|
||||
void Tray::SetTitle(const std::string& title) {
|
||||
tray_icon_->SetTitle(title);
|
||||
}
|
||||
|
||||
void Tray::SetHighlightMode(mate::Arguments* args, bool highlight) {
|
||||
void Tray::SetHighlightMode(bool highlight) {
|
||||
tray_icon_->SetHighlightMode(highlight);
|
||||
}
|
||||
|
||||
void Tray::DisplayBalloon(mate::Arguments* args,
|
||||
const mate::Dictionary& options) {
|
||||
gfx::Image icon;
|
||||
mate::Handle<NativeImage> icon;
|
||||
options.Get("icon", &icon);
|
||||
base::string16 title, content;
|
||||
if (!options.Get("title", &title) ||
|
||||
@@ -125,7 +136,14 @@ void Tray::DisplayBalloon(mate::Arguments* args,
|
||||
return;
|
||||
}
|
||||
|
||||
tray_icon_->DisplayBalloon(icon, title, content);
|
||||
#if defined(OS_WIN)
|
||||
tray_icon_->DisplayBalloon(
|
||||
icon.IsEmpty() ? NULL : icon->GetHICON(GetSystemMetrics(SM_CXSMICON)),
|
||||
title, content);
|
||||
#else
|
||||
tray_icon_->DisplayBalloon(
|
||||
icon.IsEmpty() ? gfx::Image() : icon->image(), title, content);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Tray::PopUpContextMenu(mate::Arguments* args) {
|
||||
@@ -136,7 +154,8 @@ void Tray::PopUpContextMenu(mate::Arguments* args) {
|
||||
tray_icon_->PopUpContextMenu(pos, menu.IsEmpty() ? nullptr : menu->model());
|
||||
}
|
||||
|
||||
void Tray::SetContextMenu(mate::Arguments* args, Menu* menu) {
|
||||
void Tray::SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu) {
|
||||
menu_.Reset(isolate, menu.ToV8());
|
||||
tray_icon_->SetContextMenu(menu->model());
|
||||
}
|
||||
|
||||
@@ -162,7 +181,7 @@ void Tray::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setHighlightMode", &Tray::SetHighlightMode)
|
||||
.SetMethod("displayBalloon", &Tray::DisplayBalloon)
|
||||
.SetMethod("popUpContextMenu", &Tray::PopUpContextMenu)
|
||||
.SetMethod("_setContextMenu", &Tray::SetContextMenu);
|
||||
.SetMethod("setContextMenu", &Tray::SetContextMenu);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/ui/tray_icon_observer.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace gfx {
|
||||
class Image;
|
||||
@@ -28,17 +29,19 @@ class TrayIcon;
|
||||
namespace api {
|
||||
|
||||
class Menu;
|
||||
class NativeImage;
|
||||
|
||||
class Tray : public mate::TrackableObject<Tray>,
|
||||
public TrayIconObserver {
|
||||
public:
|
||||
static mate::Wrappable* New(v8::Isolate* isolate, const gfx::Image& image);
|
||||
static mate::WrappableBase* New(
|
||||
v8::Isolate* isolate, mate::Handle<NativeImage> image);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit Tray(const gfx::Image& image);
|
||||
Tray(v8::Isolate* isolate, mate::Handle<NativeImage> image);
|
||||
~Tray() override;
|
||||
|
||||
// TrayIconObserver:
|
||||
@@ -54,18 +57,19 @@ class Tray : public mate::TrackableObject<Tray>,
|
||||
void OnDragExited() override;
|
||||
void OnDragEnded() override;
|
||||
|
||||
void SetImage(mate::Arguments* args, const gfx::Image& image);
|
||||
void SetPressedImage(mate::Arguments* args, const gfx::Image& image);
|
||||
void SetToolTip(mate::Arguments* args, const std::string& tool_tip);
|
||||
void SetTitle(mate::Arguments* args, const std::string& title);
|
||||
void SetHighlightMode(mate::Arguments* args, bool highlight);
|
||||
void SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image);
|
||||
void SetPressedImage(v8::Isolate* isolate, mate::Handle<NativeImage> image);
|
||||
void SetToolTip(const std::string& tool_tip);
|
||||
void SetTitle(const std::string& title);
|
||||
void SetHighlightMode(bool highlight);
|
||||
void DisplayBalloon(mate::Arguments* args, const mate::Dictionary& options);
|
||||
void PopUpContextMenu(mate::Arguments* args);
|
||||
void SetContextMenu(mate::Arguments* args, Menu* menu);
|
||||
void SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu);
|
||||
|
||||
private:
|
||||
v8::Local<v8::Object> ModifiersToObject(v8::Isolate* isolate, int modifiers);
|
||||
|
||||
v8::Global<v8::Object> menu_;
|
||||
scoped_ptr<TrayIcon> tray_icon_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Tray);
|
||||
|
||||
@@ -13,12 +13,16 @@
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_security_state_model_client.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/net/atom_network_delegate.h"
|
||||
#include "atom/browser/web_contents_permission_helper.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/browser/web_view_guest_delegate.h"
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/api/event_emitter_caller.h"
|
||||
#include "atom/common/color_util.h"
|
||||
#include "atom/common/mouse_util.h"
|
||||
#include "atom/common/native_mate_converters/blink_converter.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/content_converter.h"
|
||||
@@ -28,13 +32,14 @@
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/mouse_util.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||
#include "chrome/browser/printing/print_preview_message_handler.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/common/view_messages.h"
|
||||
#include "content/public/browser/favicon_status.h"
|
||||
#include "content/public/browser/native_web_keyboard_event.h"
|
||||
@@ -58,6 +63,7 @@
|
||||
#include "net/url_request/static_http_user_agent_settings.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "third_party/WebKit/public/web/WebInputEvent.h"
|
||||
#include "third_party/WebKit/public/web/WebFindOptions.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
@@ -139,7 +145,7 @@ struct Converter<net::HttpResponseHeaders*> {
|
||||
net::HttpResponseHeaders* headers) {
|
||||
base::DictionaryValue response_headers;
|
||||
if (headers) {
|
||||
void* iter = nullptr;
|
||||
size_t iter = 0;
|
||||
std::string key;
|
||||
std::string value;
|
||||
while (headers->EnumerateHeaderLines(&iter, &key, &value)) {
|
||||
@@ -210,17 +216,27 @@ content::ServiceWorkerContext* GetServiceWorkerContext(
|
||||
|
||||
} // namespace
|
||||
|
||||
WebContents::WebContents(content::WebContents* web_contents)
|
||||
WebContents::WebContents(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents)
|
||||
: content::WebContentsObserver(web_contents),
|
||||
type_(REMOTE) {
|
||||
AttachAsUserData(web_contents);
|
||||
embedder_(nullptr),
|
||||
type_(REMOTE),
|
||||
request_id_(0),
|
||||
background_throttling_(true) {
|
||||
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
|
||||
|
||||
Init(isolate);
|
||||
AttachAsUserData(web_contents);
|
||||
}
|
||||
|
||||
WebContents::WebContents(v8::Isolate* isolate,
|
||||
const mate::Dictionary& options)
|
||||
: embedder_(nullptr),
|
||||
request_id_(0) {
|
||||
request_id_(0),
|
||||
background_throttling_(true) {
|
||||
// Read options.
|
||||
options.Get("backgroundThrottling", &background_throttling_);
|
||||
|
||||
// Whether it is a guest WebContents.
|
||||
bool is_guest = false;
|
||||
options.Get("isGuest", &is_guest);
|
||||
@@ -258,8 +274,7 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
Observe(web_contents);
|
||||
AttachAsUserData(web_contents);
|
||||
InitWithWebContents(web_contents);
|
||||
InitWithWebContents(web_contents, session->browser_context());
|
||||
|
||||
managed_web_contents()->GetView()->SetDelegate(this);
|
||||
|
||||
@@ -268,6 +283,8 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
|
||||
// Intialize permission helper.
|
||||
WebContentsPermissionHelper::CreateForWebContents(web_contents);
|
||||
// Intialize security state client.
|
||||
AtomSecurityStateModelClient::CreateForWebContents(web_contents);
|
||||
|
||||
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
|
||||
|
||||
@@ -285,6 +302,9 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
if (owner_window)
|
||||
SetOwnerWindow(owner_window);
|
||||
}
|
||||
|
||||
Init(isolate);
|
||||
AttachAsUserData(web_contents);
|
||||
}
|
||||
|
||||
WebContents::~WebContents() {
|
||||
@@ -316,21 +336,13 @@ bool WebContents::AddMessageToConsole(content::WebContents* source,
|
||||
}
|
||||
}
|
||||
|
||||
bool WebContents::ShouldCreateWebContents(
|
||||
content::WebContents* web_contents,
|
||||
int32_t route_id,
|
||||
int32_t main_frame_route_id,
|
||||
int32_t main_frame_widget_route_id,
|
||||
WindowContainerType window_container_type,
|
||||
const std::string& frame_name,
|
||||
const GURL& target_url,
|
||||
const std::string& partition_id,
|
||||
content::SessionStorageNamespace* session_storage_namespace) {
|
||||
void WebContents::OnCreateWindow(const GURL& target_url,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition) {
|
||||
if (type_ == BROWSER_WINDOW)
|
||||
Emit("-new-window", target_url, frame_name, NEW_FOREGROUND_TAB);
|
||||
Emit("-new-window", target_url, frame_name, disposition);
|
||||
else
|
||||
Emit("new-window", target_url, frame_name, NEW_FOREGROUND_TAB);
|
||||
return false;
|
||||
Emit("new-window", target_url, frame_name, disposition);
|
||||
}
|
||||
|
||||
content::WebContents* WebContents::OpenURLFromTab(
|
||||
@@ -367,7 +379,7 @@ void WebContents::MoveContents(content::WebContents* source,
|
||||
|
||||
void WebContents::CloseContents(content::WebContents* source) {
|
||||
Emit("close");
|
||||
if (type_ == BROWSER_WINDOW)
|
||||
if (type_ == BROWSER_WINDOW && owner_window())
|
||||
owner_window()->CloseContents(source);
|
||||
}
|
||||
|
||||
@@ -382,14 +394,12 @@ bool WebContents::IsPopupOrPanel(const content::WebContents* source) const {
|
||||
void WebContents::HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen()) {
|
||||
// Escape exits tabbed fullscreen mode.
|
||||
ExitFullscreenModeForTab(source);
|
||||
} else if (type_ == BROWSER_WINDOW) {
|
||||
owner_window()->HandleKeyboardEvent(source, event);
|
||||
} else if (type_ == WEB_VIEW && guest_delegate_) {
|
||||
if (type_ == WEB_VIEW && embedder_) {
|
||||
// Send the unhandled keyboard events back to the embedder.
|
||||
guest_delegate_->HandleKeyboardEvent(source, event);
|
||||
embedder_->HandleKeyboardEvent(source, event);
|
||||
} else {
|
||||
// Go to the default keyboard handling.
|
||||
CommonWebContentsDelegate::HandleKeyboardEvent(source, event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,22 +428,24 @@ void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
|
||||
|
||||
void WebContents::RendererUnresponsive(content::WebContents* source) {
|
||||
Emit("unresponsive");
|
||||
if (type_ == BROWSER_WINDOW)
|
||||
if (type_ == BROWSER_WINDOW && owner_window())
|
||||
owner_window()->RendererUnresponsive(source);
|
||||
}
|
||||
|
||||
void WebContents::RendererResponsive(content::WebContents* source) {
|
||||
Emit("responsive");
|
||||
if (type_ == BROWSER_WINDOW)
|
||||
if (type_ == BROWSER_WINDOW && owner_window())
|
||||
owner_window()->RendererResponsive(source);
|
||||
}
|
||||
|
||||
bool WebContents::HandleContextMenu(const content::ContextMenuParams& params) {
|
||||
if (!params.custom_context.is_pepper_menu)
|
||||
return false;
|
||||
if (params.custom_context.is_pepper_menu) {
|
||||
Emit("pepper-context-menu", std::make_pair(params, web_contents()));
|
||||
web_contents()->NotifyContextMenuClosed(params.custom_context);
|
||||
} else {
|
||||
Emit("context-menu", std::make_pair(params, web_contents()));
|
||||
}
|
||||
|
||||
Emit("pepper-context-menu", std::make_pair(params, web_contents()));
|
||||
web_contents()->NotifyContextMenuClosed(params.custom_context);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -546,18 +558,21 @@ void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
|
||||
void WebContents::DidFailProvisionalLoad(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& url,
|
||||
int error_code,
|
||||
const base::string16& error_description,
|
||||
int code,
|
||||
const base::string16& description,
|
||||
bool was_ignored_by_handler) {
|
||||
Emit("did-fail-provisional-load", error_code, error_description, url);
|
||||
bool is_main_frame = !render_frame_host->GetParent();
|
||||
Emit("did-fail-provisional-load", code, description, url, is_main_frame);
|
||||
Emit("did-fail-load", code, description, url, is_main_frame);
|
||||
}
|
||||
|
||||
void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url,
|
||||
const GURL& url,
|
||||
int error_code,
|
||||
const base::string16& error_description,
|
||||
bool was_ignored_by_handler) {
|
||||
Emit("did-fail-load", error_code, error_description, validated_url);
|
||||
bool is_main_frame = !render_frame_host->GetParent();
|
||||
Emit("did-fail-load", error_code, error_description, url, is_main_frame);
|
||||
}
|
||||
|
||||
void WebContents::DidStartLoading() {
|
||||
@@ -577,7 +592,8 @@ void WebContents::DidGetResourceResponseStart(
|
||||
details.http_response_code,
|
||||
details.method,
|
||||
details.referrer,
|
||||
details.headers.get());
|
||||
details.headers.get(),
|
||||
ResourceTypeToString(details.resource_type));
|
||||
}
|
||||
|
||||
void WebContents::DidGetRedirectForResourceRequest(
|
||||
@@ -623,6 +639,10 @@ void WebContents::DidUpdateFaviconURL(
|
||||
Emit("page-favicon-updated", unique_urls);
|
||||
}
|
||||
|
||||
void WebContents::DevToolsReloadPage() {
|
||||
Emit("devtools-reload-page");
|
||||
}
|
||||
|
||||
void WebContents::DevToolsFocused() {
|
||||
Emit("devtools-focused");
|
||||
}
|
||||
@@ -713,7 +733,8 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
|
||||
Emit("did-fail-load",
|
||||
static_cast<int>(net::ERR_INVALID_URL),
|
||||
net::ErrorToShortString(net::ERR_INVALID_URL),
|
||||
url.possibly_invalid_spec());
|
||||
url.possibly_invalid_spec(),
|
||||
true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -736,6 +757,25 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
|
||||
params.should_clear_history_list = true;
|
||||
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
|
||||
web_contents()->GetController().LoadURLWithParams(params);
|
||||
|
||||
// Set the background color of RenderWidgetHostView.
|
||||
// We have to call it right after LoadURL because the RenderViewHost is only
|
||||
// created after loading a page.
|
||||
const auto view = web_contents()->GetRenderWidgetHostView();
|
||||
WebContentsPreferences* web_preferences =
|
||||
WebContentsPreferences::FromWebContents(web_contents());
|
||||
std::string color_name;
|
||||
if (web_preferences->web_preferences()->GetString(options::kBackgroundColor,
|
||||
&color_name)) {
|
||||
view->SetBackgroundColor(ParseHexColor(color_name));
|
||||
} else {
|
||||
view->SetBackgroundColor(SK_ColorTRANSPARENT);
|
||||
}
|
||||
|
||||
// For the same reason we can only disable hidden here.
|
||||
const auto host = static_cast<content::RenderWidgetHostImpl*>(
|
||||
view->GetRenderWidgetHost());
|
||||
host->disable_hidden_ = !background_throttling_;
|
||||
}
|
||||
|
||||
void WebContents::DownloadURL(const GURL& url) {
|
||||
@@ -759,6 +799,14 @@ bool WebContents::IsLoading() const {
|
||||
return web_contents()->IsLoading();
|
||||
}
|
||||
|
||||
bool WebContents::IsLoadingMainFrame() const {
|
||||
// Comparing site instances works because Electron always creates a new site
|
||||
// instance when navigating, regardless of origin. See AtomBrowserClient.
|
||||
return (web_contents()->GetLastCommittedURL().is_empty() ||
|
||||
web_contents()->GetSiteInstance() !=
|
||||
web_contents()->GetPendingSiteInstance()) && IsLoading();
|
||||
}
|
||||
|
||||
bool WebContents::IsWaitingForResponse() const {
|
||||
return web_contents()->IsWaitingForResponse();
|
||||
}
|
||||
@@ -815,14 +863,20 @@ void WebContents::OpenDevTools(mate::Arguments* args) {
|
||||
if (type_ == REMOTE)
|
||||
return;
|
||||
|
||||
bool detach = false;
|
||||
if (type_ == WEB_VIEW) {
|
||||
detach = true;
|
||||
std::string state;
|
||||
if (type_ == WEB_VIEW || !owner_window()) {
|
||||
state = "detach";
|
||||
} else if (args && args->Length() == 1) {
|
||||
bool detach = false;
|
||||
mate::Dictionary options;
|
||||
args->GetNext(&options) && options.Get("detach", &detach);
|
||||
if (args->GetNext(&options)) {
|
||||
options.Get("mode", &state);
|
||||
options.Get("detach", &detach);
|
||||
if (state.empty() && detach)
|
||||
state = "detach";
|
||||
}
|
||||
}
|
||||
managed_web_contents()->SetCanDock(!detach);
|
||||
managed_web_contents()->SetDockState(state);
|
||||
managed_web_contents()->ShowDevTools();
|
||||
}
|
||||
|
||||
@@ -1101,11 +1155,6 @@ void WebContents::SetSize(const SetSizeParams& params) {
|
||||
guest_delegate_->SetSize(params);
|
||||
}
|
||||
|
||||
void WebContents::SetAllowTransparency(bool allow) {
|
||||
if (guest_delegate_)
|
||||
guest_delegate_->SetAllowTransparency(allow);
|
||||
}
|
||||
|
||||
bool WebContents::IsGuest() const {
|
||||
return type_ == WEB_VIEW;
|
||||
}
|
||||
@@ -1123,6 +1172,10 @@ v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() {
|
||||
return v8::Null(isolate());
|
||||
}
|
||||
|
||||
int32_t WebContents::ID() const {
|
||||
return weak_map_id();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebContents::Session(v8::Isolate* isolate) {
|
||||
return v8::Local<v8::Value>::New(isolate, session_);
|
||||
}
|
||||
@@ -1160,6 +1213,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("_getURL", &WebContents::GetURL)
|
||||
.SetMethod("getTitle", &WebContents::GetTitle)
|
||||
.SetMethod("isLoading", &WebContents::IsLoading)
|
||||
.SetMethod("isLoadingMainFrame", &WebContents::IsLoadingMainFrame)
|
||||
.SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse)
|
||||
.SetMethod("_stop", &WebContents::Stop)
|
||||
.SetMethod("_goBack", &WebContents::GoBack)
|
||||
@@ -1203,7 +1257,6 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
&WebContents::BeginFrameSubscription)
|
||||
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
|
||||
.SetMethod("setSize", &WebContents::SetSize)
|
||||
.SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
|
||||
.SetMethod("isGuest", &WebContents::IsGuest)
|
||||
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
|
||||
.SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
|
||||
@@ -1215,6 +1268,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("_printToPDF", &WebContents::PrintToPDF)
|
||||
.SetMethod("addWorkSpace", &WebContents::AddWorkSpace)
|
||||
.SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
|
||||
.SetProperty("id", &WebContents::ID)
|
||||
.SetProperty("session", &WebContents::Session)
|
||||
.SetProperty("hostWebContents", &WebContents::HostWebContents)
|
||||
.SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents)
|
||||
@@ -1247,7 +1301,8 @@ mate::Handle<WebContents> WebContents::CreateFrom(
|
||||
return mate::CreateHandle(isolate, static_cast<WebContents*>(existing));
|
||||
|
||||
// Otherwise create a new WebContents wrapper object.
|
||||
auto handle = mate::CreateHandle(isolate, new WebContents(web_contents));
|
||||
auto handle = mate::CreateHandle(
|
||||
isolate, new WebContents(isolate, web_contents));
|
||||
g_wrap_web_contents.Run(handle.ToV8());
|
||||
return handle;
|
||||
}
|
||||
@@ -1260,16 +1315,8 @@ mate::Handle<WebContents> WebContents::Create(
|
||||
return handle;
|
||||
}
|
||||
|
||||
void ClearWrapWebContents() {
|
||||
g_wrap_web_contents.Reset();
|
||||
}
|
||||
|
||||
void SetWrapWebContents(const WrapWebContentsCallback& callback) {
|
||||
g_wrap_web_contents = callback;
|
||||
|
||||
// Cleanup the wrapper on exit.
|
||||
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
|
||||
base::Bind(ClearWrapWebContents));
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -55,6 +55,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
static mate::Handle<WebContents> Create(
|
||||
v8::Isolate* isolate, const mate::Dictionary& options);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
int GetID() const;
|
||||
bool Equal(const WebContents* web_contents) const;
|
||||
void LoadURL(const GURL& url, const mate::Dictionary& options);
|
||||
@@ -62,6 +65,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
GURL GetURL() const;
|
||||
base::string16 GetTitle() const;
|
||||
bool IsLoading() const;
|
||||
bool IsLoadingMainFrame() const;
|
||||
bool IsWaitingForResponse() const;
|
||||
void Stop();
|
||||
void ReloadIgnoringCache();
|
||||
@@ -131,7 +135,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
|
||||
// Methods for creating <webview>.
|
||||
void SetSize(const SetSizeParams& params);
|
||||
void SetAllowTransparency(bool allow);
|
||||
bool IsGuest() const;
|
||||
|
||||
// Callback triggered on permission response.
|
||||
@@ -139,6 +142,11 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
const GURL& origin,
|
||||
bool allowed);
|
||||
|
||||
// Create window with the given disposition.
|
||||
void OnCreateWindow(const GURL& target_url,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition);
|
||||
|
||||
// Returns the web preferences of current WebContents.
|
||||
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
|
||||
|
||||
@@ -146,17 +154,14 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
v8::Local<v8::Value> GetOwnerBrowserWindow();
|
||||
|
||||
// Properties.
|
||||
int32_t ID() const;
|
||||
v8::Local<v8::Value> Session(v8::Isolate* isolate);
|
||||
content::WebContents* HostWebContents();
|
||||
v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> Debugger(v8::Isolate* isolate);
|
||||
|
||||
// mate::TrackableObject:
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit WebContents(content::WebContents* web_contents);
|
||||
WebContents(v8::Isolate* isolate, content::WebContents* web_contents);
|
||||
WebContents(v8::Isolate* isolate, const mate::Dictionary& options);
|
||||
~WebContents();
|
||||
|
||||
@@ -166,16 +171,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
const base::string16& message,
|
||||
int32_t line_no,
|
||||
const base::string16& source_id) override;
|
||||
bool ShouldCreateWebContents(
|
||||
content::WebContents* web_contents,
|
||||
int32_t route_id,
|
||||
int32_t main_frame_route_id,
|
||||
int32_t main_frame_widget_route_id,
|
||||
WindowContainerType window_container_type,
|
||||
const std::string& frame_name,
|
||||
const GURL& target_url,
|
||||
const std::string& partition_id,
|
||||
content::SessionStorageNamespace* session_storage_namespace) override;
|
||||
content::WebContents* OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) override;
|
||||
@@ -257,6 +252,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void MediaStoppedPlaying(const MediaPlayerId& id) override;
|
||||
void DidChangeThemeColor(SkColor theme_color) override;
|
||||
|
||||
// brightray::InspectableWebContentsDelegate:
|
||||
void DevToolsReloadPage() override;
|
||||
|
||||
// brightray::InspectableWebContentsViewDelegate:
|
||||
void DevToolsFocused() override;
|
||||
void DevToolsOpened() override;
|
||||
@@ -302,6 +300,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// Request id used for findInPage request.
|
||||
uint32_t request_id_;
|
||||
|
||||
// Whether background throttling is disabled.
|
||||
bool background_throttling_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContents);
|
||||
};
|
||||
|
||||
|
||||
@@ -36,8 +36,10 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
WebRequest::WebRequest(AtomBrowserContext* browser_context)
|
||||
WebRequest::WebRequest(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
WebRequest::~WebRequest() {
|
||||
@@ -81,7 +83,7 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
|
||||
mate::Handle<WebRequest> WebRequest::Create(
|
||||
v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context) {
|
||||
return mate::CreateHandle(isolate, new WebRequest(browser_context));
|
||||
return mate::CreateHandle(isolate, new WebRequest(isolate, browser_context));
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -21,13 +21,12 @@ class WebRequest : public mate::TrackableObject<WebRequest> {
|
||||
static mate::Handle<WebRequest> Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context);
|
||||
|
||||
// mate::TrackableObject:
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit WebRequest(AtomBrowserContext* browser_context);
|
||||
~WebRequest();
|
||||
WebRequest(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
~WebRequest() override;
|
||||
|
||||
// C++ can not distinguish overloaded member function.
|
||||
template<AtomNetworkDelegate::SimpleEvent type>
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/native_mate_converters/content_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
@@ -12,22 +12,6 @@
|
||||
|
||||
using atom::WebContentsPreferences;
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<content::WebContents*> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
content::WebContents** out) {
|
||||
atom::api::WebContents* contents;
|
||||
if (!Converter<atom::api::WebContents*>::FromV8(isolate, val, &contents))
|
||||
return false;
|
||||
*out = contents->web_contents();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace {
|
||||
|
||||
atom::WebViewManager* GetWebViewManager(content::WebContents* web_contents) {
|
||||
|
||||
@@ -21,8 +21,11 @@
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "atom/browser/ui/win/taskbar_host.h"
|
||||
#endif
|
||||
|
||||
@@ -61,52 +64,6 @@ void OnCapturePageDone(
|
||||
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
|
||||
}
|
||||
|
||||
// Converts min-width to minWidth, returns false if no conversion is needed.
|
||||
bool TranslateOldKey(const std::string& key, std::string* new_key) {
|
||||
if (key.find('-') == std::string::npos)
|
||||
return false;
|
||||
new_key->reserve(key.size());
|
||||
bool next_upper_case = false;
|
||||
for (char c : key) {
|
||||
if (c == '-') {
|
||||
next_upper_case = true;
|
||||
} else if (next_upper_case) {
|
||||
new_key->push_back(base::ToUpperASCII(c));
|
||||
next_upper_case = false;
|
||||
} else {
|
||||
new_key->push_back(c);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Converts min-width to minWidth recursively in the dictionary.
|
||||
void TranslateOldOptions(v8::Isolate* isolate, v8::Local<v8::Object> options) {
|
||||
auto context = isolate->GetCurrentContext();
|
||||
auto maybe_keys = options->GetOwnPropertyNames(context);
|
||||
if (maybe_keys.IsEmpty())
|
||||
return;
|
||||
std::vector<std::string> keys;
|
||||
if (!mate::ConvertFromV8(isolate, maybe_keys.ToLocalChecked(), &keys))
|
||||
return;
|
||||
mate::Dictionary dict(isolate, options);
|
||||
for (const auto& key : keys) {
|
||||
v8::Local<v8::Value> value;
|
||||
if (!dict.Get(key, &value)) // Shouldn't happen, but guard it anyway.
|
||||
continue;
|
||||
// Go recursively.
|
||||
v8::Local<v8::Object> sub_options;
|
||||
if (mate::ConvertFromV8(isolate, value, &sub_options))
|
||||
TranslateOldOptions(isolate, sub_options);
|
||||
// Translate key.
|
||||
std::string new_key;
|
||||
if (TranslateOldKey(key, &new_key)) {
|
||||
dict.Set(new_key, value);
|
||||
dict.Delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Converts binary data to Buffer.
|
||||
v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
|
||||
auto buffer = node::Buffer::Copy(isolate, static_cast<char*>(val), size);
|
||||
@@ -120,21 +77,14 @@ v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
|
||||
|
||||
|
||||
Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
|
||||
// Be compatible with old style field names like min-width.
|
||||
TranslateOldOptions(isolate, options.GetHandle());
|
||||
|
||||
// Use options.webPreferences to create WebContents.
|
||||
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
|
||||
options.Get(options::kWebPreferences, &web_preferences);
|
||||
|
||||
// Be compatible with old options which are now in web_preferences.
|
||||
// Copy the backgroundColor to webContents.
|
||||
v8::Local<v8::Value> value;
|
||||
if (options.Get(options::kNodeIntegration, &value))
|
||||
web_preferences.Set(options::kNodeIntegration, value);
|
||||
if (options.Get(options::kPreloadScript, &value))
|
||||
web_preferences.Set(options::kPreloadScript, value);
|
||||
if (options.Get(options::kZoomFactor, &value))
|
||||
web_preferences.Set(options::kZoomFactor, value);
|
||||
if (options.Get(options::kBackgroundColor, &value))
|
||||
web_preferences.Set(options::kBackgroundColor, value);
|
||||
|
||||
// Creates the WebContents used by BrowserWindow.
|
||||
auto web_contents = WebContents::Create(isolate, web_preferences);
|
||||
@@ -142,7 +92,7 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
|
||||
api_web_contents_ = web_contents.get();
|
||||
|
||||
// Keep a copy of the options for later use.
|
||||
mate::Dictionary(isolate, web_contents->GetWrapper(isolate)).Set(
|
||||
mate::Dictionary(isolate, web_contents->GetWrapper()).Set(
|
||||
"browserWindowOptions", options);
|
||||
|
||||
// Creates BrowserWindow.
|
||||
@@ -152,6 +102,13 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
|
||||
window_->InitFromOptions(options);
|
||||
window_->AddObserver(this);
|
||||
AttachAsUserData(window_.get());
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
// Sets the window icon.
|
||||
mate::Handle<NativeImage> icon;
|
||||
if (options.Get(options::kIcon, &icon))
|
||||
SetIcon(icon);
|
||||
#endif
|
||||
}
|
||||
|
||||
Window::~Window() {
|
||||
@@ -243,6 +200,10 @@ void Window::OnWindowScrollTouchEnd() {
|
||||
Emit("scroll-touch-end");
|
||||
}
|
||||
|
||||
void Window::OnWindowSwipe(const std::string& direction) {
|
||||
Emit("swipe", direction);
|
||||
}
|
||||
|
||||
void Window::OnWindowEnterHtmlFullScreen() {
|
||||
Emit("enter-html-full-screen");
|
||||
}
|
||||
@@ -274,7 +235,7 @@ void Window::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {
|
||||
#endif
|
||||
|
||||
// static
|
||||
mate::Wrappable* Window::New(v8::Isolate* isolate, mate::Arguments* args) {
|
||||
mate::WrappableBase* Window::New(v8::Isolate* isolate, mate::Arguments* args) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate, "Cannot create BrowserWindow before app is ready")));
|
||||
@@ -420,6 +381,12 @@ std::vector<int> Window::GetMaximumSize() {
|
||||
return result;
|
||||
}
|
||||
|
||||
void Window::SetSheetOffset(double offsetY, mate::Arguments* args) {
|
||||
double offsetX = 0.0;
|
||||
args->GetNext(&offsetX);
|
||||
window_->SetSheetOffset(offsetX, offsetY);
|
||||
}
|
||||
|
||||
void Window::SetResizable(bool resizable) {
|
||||
window_->SetResizable(resizable);
|
||||
}
|
||||
@@ -662,6 +629,18 @@ void Window::ShowDefinitionForSelection() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
void Window::SetIcon(mate::Handle<NativeImage> icon) {
|
||||
#if defined(OS_WIN)
|
||||
static_cast<NativeWindowViews*>(window_.get())->SetIcon(
|
||||
icon->GetHICON(GetSystemMetrics(SM_CXSMICON)), icon->GetHICON(256));
|
||||
#elif defined(USE_X11)
|
||||
static_cast<NativeWindowViews*>(window_.get())->SetIcon(
|
||||
icon->image().AsImageSkia());
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void Window::SetAspectRatio(double aspect_ratio, mate::Arguments* args) {
|
||||
gfx::Size extra_size;
|
||||
args->GetNext(&extra_size);
|
||||
@@ -726,6 +705,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getMinimumSize", &Window::GetMinimumSize)
|
||||
.SetMethod("setMaximumSize", &Window::SetMaximumSize)
|
||||
.SetMethod("getMaximumSize", &Window::GetMaximumSize)
|
||||
.SetMethod("setSheetOffset", &Window::SetSheetOffset)
|
||||
.SetMethod("setResizable", &Window::SetResizable)
|
||||
.SetMethod("isResizable", &Window::IsResizable)
|
||||
.SetMethod("setMovable", &Window::SetMovable)
|
||||
@@ -782,6 +762,9 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("showDefinitionForSelection",
|
||||
&Window::ShowDefinitionForSelection)
|
||||
#endif
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
.SetMethod("setIcon", &Window::SetIcon)
|
||||
#endif
|
||||
.SetProperty("id", &Window::ID)
|
||||
.SetProperty("webContents", &Window::WebContents);
|
||||
@@ -792,7 +775,7 @@ v8::Local<v8::Value> Window::From(v8::Isolate* isolate,
|
||||
NativeWindow* native_window) {
|
||||
auto existing = TrackableObject::FromWrappedClass(isolate, native_window);
|
||||
if (existing)
|
||||
return existing->GetWrapper(isolate);
|
||||
return existing->GetWrapper();
|
||||
else
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/native_window_observer.h"
|
||||
#include "atom/common/api/atom_api_native_image.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
class GURL;
|
||||
@@ -38,7 +39,7 @@ class WebContents;
|
||||
class Window : public mate::TrackableObject<Window>,
|
||||
public NativeWindowObserver {
|
||||
public:
|
||||
static mate::Wrappable* New(v8::Isolate* isolate, mate::Arguments* args);
|
||||
static mate::WrappableBase* New(v8::Isolate* isolate, mate::Arguments* args);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
@@ -51,7 +52,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||
|
||||
protected:
|
||||
Window(v8::Isolate* isolate, const mate::Dictionary& options);
|
||||
virtual ~Window();
|
||||
~Window() override;
|
||||
|
||||
// NativeWindowObserver:
|
||||
void WillCloseWindow(bool* prevent_default) override;
|
||||
@@ -69,6 +70,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void OnWindowMoved() override;
|
||||
void OnWindowScrollTouchBegin() override;
|
||||
void OnWindowScrollTouchEnd() override;
|
||||
void OnWindowSwipe(const std::string& direction) override;
|
||||
void OnWindowEnterFullScreen() override;
|
||||
void OnWindowLeaveFullScreen() override;
|
||||
void OnWindowEnterHtmlFullScreen() override;
|
||||
@@ -109,6 +111,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||
std::vector<int> GetMinimumSize();
|
||||
void SetMaximumSize(int width, int height);
|
||||
std::vector<int> GetMaximumSize();
|
||||
void SetSheetOffset(double offsetY, mate::Arguments* args);
|
||||
void SetResizable(bool resizable);
|
||||
bool IsResizable();
|
||||
void SetMovable(bool movable);
|
||||
@@ -170,6 +173,10 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void ShowDefinitionForSelection();
|
||||
#endif
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
void SetIcon(mate::Handle<NativeImage> icon);
|
||||
#endif
|
||||
|
||||
void SetVisibleOnAllWorkspaces(bool visible);
|
||||
bool IsVisibleOnAllWorkspaces();
|
||||
|
||||
|
||||
@@ -11,31 +11,15 @@
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace {
|
||||
|
||||
v8::Persistent<v8::ObjectTemplate> template_;
|
||||
|
||||
} // namespace
|
||||
|
||||
Event::Event()
|
||||
Event::Event(v8::Isolate* isolate)
|
||||
: sender_(NULL),
|
||||
message_(NULL) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
Event::~Event() {
|
||||
}
|
||||
|
||||
ObjectTemplateBuilder Event::GetObjectTemplateBuilder(v8::Isolate* isolate) {
|
||||
if (template_.IsEmpty())
|
||||
template_.Reset(isolate, ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("preventDefault", &Event::PreventDefault)
|
||||
.SetMethod("sendReply", &Event::SendReply)
|
||||
.Build());
|
||||
|
||||
return ObjectTemplateBuilder(
|
||||
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
|
||||
}
|
||||
|
||||
void Event::SetSenderAndMessage(content::WebContents* sender,
|
||||
IPC::Message* message) {
|
||||
DCHECK(!sender_);
|
||||
@@ -52,7 +36,7 @@ void Event::WebContentsDestroyed() {
|
||||
}
|
||||
|
||||
void Event::PreventDefault(v8::Isolate* isolate) {
|
||||
GetWrapper(isolate)->Set(StringToV8(isolate, "defaultPrevented"),
|
||||
GetWrapper()->Set(StringToV8(isolate, "defaultPrevented"),
|
||||
v8::True(isolate));
|
||||
}
|
||||
|
||||
@@ -61,12 +45,23 @@ bool Event::SendReply(const base::string16& json) {
|
||||
return false;
|
||||
|
||||
AtomViewHostMsg_Message_Sync::WriteReplyParams(message_, json);
|
||||
return sender_->Send(message_);
|
||||
bool success = sender_->Send(message_);
|
||||
message_ = NULL;
|
||||
sender_ = NULL;
|
||||
return success;
|
||||
}
|
||||
|
||||
// static
|
||||
Handle<Event> Event::Create(v8::Isolate* isolate) {
|
||||
return CreateHandle(isolate, new Event);
|
||||
return mate::CreateHandle(isolate, new Event(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void Event::BuildPrototype(
|
||||
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("preventDefault", &Event::PreventDefault)
|
||||
.SetMethod("sendReply", &Event::SendReply);
|
||||
}
|
||||
|
||||
} // namespace mate
|
||||
|
||||
@@ -15,11 +15,14 @@ class Message;
|
||||
|
||||
namespace mate {
|
||||
|
||||
class Event : public Wrappable,
|
||||
class Event : public Wrappable<Event>,
|
||||
public content::WebContentsObserver {
|
||||
public:
|
||||
static Handle<Event> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
// Pass the sender and message to be replied.
|
||||
void SetSenderAndMessage(content::WebContents* sender, IPC::Message* message);
|
||||
|
||||
@@ -30,11 +33,8 @@ class Event : public Wrappable,
|
||||
bool SendReply(const base::string16& json);
|
||||
|
||||
protected:
|
||||
Event();
|
||||
virtual ~Event();
|
||||
|
||||
// Wrappable implementations:
|
||||
ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) override;
|
||||
explicit Event(v8::Isolate* isolate);
|
||||
~Event() override;
|
||||
|
||||
// content::WebContentsObserver implementations:
|
||||
void WebContentsDestroyed() override;
|
||||
|
||||
@@ -34,11 +34,13 @@ v8::Local<v8::Object> CreateEventObject(v8::Isolate* isolate) {
|
||||
|
||||
} // namespace
|
||||
|
||||
EventEmitter::EventEmitter() {
|
||||
}
|
||||
namespace internal {
|
||||
|
||||
v8::Local<v8::Object> EventEmitter::CreateJSEvent(
|
||||
v8::Isolate* isolate, content::WebContents* sender, IPC::Message* message) {
|
||||
v8::Local<v8::Object> CreateJSEvent(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message) {
|
||||
v8::Local<v8::Object> event;
|
||||
bool use_native_event = sender && message;
|
||||
|
||||
@@ -49,16 +51,20 @@ v8::Local<v8::Object> EventEmitter::CreateJSEvent(
|
||||
} else {
|
||||
event = CreateEventObject(isolate);
|
||||
}
|
||||
mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate));
|
||||
mate::Dictionary(isolate, event).Set("sender", object);
|
||||
return event;
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> EventEmitter::CreateCustomEvent(
|
||||
v8::Isolate* isolate, v8::Local<v8::Object> custom_event) {
|
||||
v8::Local<v8::Object> CreateCustomEvent(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
v8::Local<v8::Object> custom_event) {
|
||||
v8::Local<v8::Object> event = CreateEventObject(isolate);
|
||||
(void)event->SetPrototype(custom_event->CreationContext(), custom_event);
|
||||
mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate));
|
||||
mate::Dictionary(isolate, event).Set("sender", object);
|
||||
return event;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace mate
|
||||
|
||||
@@ -20,17 +20,38 @@ class Message;
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace internal {
|
||||
|
||||
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message);
|
||||
v8::Local<v8::Object> CreateCustomEvent(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
v8::Local<v8::Object> event);
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Provide helperers to emit event in JavaScript.
|
||||
class EventEmitter : public Wrappable {
|
||||
template<typename T>
|
||||
class EventEmitter : public Wrappable<T> {
|
||||
public:
|
||||
typedef std::vector<v8::Local<v8::Value>> ValueArray;
|
||||
|
||||
// Make the convinient methods visible:
|
||||
// https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members
|
||||
v8::Local<v8::Object> GetWrapper() { return Wrappable<T>::GetWrapper(); }
|
||||
v8::Isolate* isolate() const { return Wrappable<T>::isolate(); }
|
||||
|
||||
// this.emit(name, event, args...);
|
||||
template<typename... Args>
|
||||
bool EmitCustomEvent(const base::StringPiece& name,
|
||||
v8::Local<v8::Object> event,
|
||||
const Args&... args) {
|
||||
return EmitWithEvent(name, CreateCustomEvent(isolate(), event), args...);
|
||||
return EmitWithEvent(
|
||||
name,
|
||||
internal::CreateCustomEvent(isolate(), GetWrapper(), event), args...);
|
||||
}
|
||||
|
||||
// this.emit(name, new Event(), args...);
|
||||
@@ -47,12 +68,13 @@ class EventEmitter : public Wrappable {
|
||||
const Args&... args) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
v8::Local<v8::Object> event = CreateJSEvent(isolate(), sender, message);
|
||||
v8::Local<v8::Object> event = internal::CreateJSEvent(
|
||||
isolate(), GetWrapper(), sender, message);
|
||||
return EmitWithEvent(name, event, args...);
|
||||
}
|
||||
|
||||
protected:
|
||||
EventEmitter();
|
||||
EventEmitter() {}
|
||||
|
||||
private:
|
||||
// this.emit(name, event, args...);
|
||||
@@ -62,17 +84,11 @@ class EventEmitter : public Wrappable {
|
||||
const Args&... args) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
EmitEvent(isolate(), GetWrapper(isolate()), name, event, args...);
|
||||
EmitEvent(isolate(), GetWrapper(), name, event, args...);
|
||||
return event->Get(
|
||||
StringToV8(isolate(), "defaultPrevented"))->BooleanValue();
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message);
|
||||
v8::Local<v8::Object> CreateCustomEvent(
|
||||
v8::Isolate* isolate, v8::Local<v8::Object> event);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(EventEmitter);
|
||||
};
|
||||
|
||||
|
||||
@@ -73,11 +73,6 @@ void SavePageHandler::Destroy(content::DownloadItem* item) {
|
||||
delete this;
|
||||
}
|
||||
|
||||
// static
|
||||
bool SavePageHandler::IsSavePageTypes(const std::string& type) {
|
||||
return type == "multipart/related" || type == "text/html";
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -37,8 +37,6 @@ class SavePageHandler : public content::DownloadManager::Observer,
|
||||
bool Handle(const base::FilePath& full_path,
|
||||
const content::SavePageType& save_type);
|
||||
|
||||
static bool IsSavePageTypes(const std::string& type);
|
||||
|
||||
private:
|
||||
void Destroy(content::DownloadItem* item);
|
||||
|
||||
|
||||
@@ -37,15 +37,6 @@ TrackableObjectBase::~TrackableObjectBase() {
|
||||
cleanup_.Run();
|
||||
}
|
||||
|
||||
void TrackableObjectBase::AfterInit(v8::Isolate* isolate) {
|
||||
if (wrapped_)
|
||||
AttachAsUserData(wrapped_);
|
||||
}
|
||||
|
||||
void TrackableObjectBase::MarkDestroyed() {
|
||||
GetWrapper(isolate())->SetAlignedPointerInInternalField(0, nullptr);
|
||||
}
|
||||
|
||||
base::Closure TrackableObjectBase::GetDestroyClosure() {
|
||||
return base::Bind(&TrackableObjectBase::Destroy, weak_factory_.GetWeakPtr());
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/common/id_weak_map.h"
|
||||
#include "atom/common/key_weak_map.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
@@ -21,7 +21,7 @@ class SupportsUserData;
|
||||
namespace mate {
|
||||
|
||||
// Users should use TrackableObject instead.
|
||||
class TrackableObjectBase : public mate::EventEmitter {
|
||||
class TrackableObjectBase {
|
||||
public:
|
||||
TrackableObjectBase();
|
||||
|
||||
@@ -32,13 +32,7 @@ class TrackableObjectBase : public mate::EventEmitter {
|
||||
void AttachAsUserData(base::SupportsUserData* wrapped);
|
||||
|
||||
protected:
|
||||
~TrackableObjectBase() override;
|
||||
|
||||
// mate::Wrappable:
|
||||
void AfterInit(v8::Isolate* isolate) override;
|
||||
|
||||
// Mark the JS object as destroyed.
|
||||
void MarkDestroyed();
|
||||
virtual ~TrackableObjectBase();
|
||||
|
||||
// Returns a closure that can destroy the native class.
|
||||
base::Closure GetDestroyClosure();
|
||||
@@ -65,8 +59,14 @@ class TrackableObjectBase : public mate::EventEmitter {
|
||||
// All instances of TrackableObject will be kept in a weak map and can be got
|
||||
// from its ID.
|
||||
template<typename T>
|
||||
class TrackableObject : public TrackableObjectBase {
|
||||
class TrackableObject : public TrackableObjectBase,
|
||||
public mate::EventEmitter<T> {
|
||||
public:
|
||||
// Mark the JS object as destroyed.
|
||||
void MarkDestroyed() {
|
||||
Wrappable<T>::GetWrapper()->SetAlignedPointerInInternalField(0, nullptr);
|
||||
}
|
||||
|
||||
// Finds out the TrackableObject from its ID in weak map.
|
||||
static T* FromWeakMapID(v8::Isolate* isolate, int32_t id) {
|
||||
if (!weak_map_)
|
||||
@@ -106,50 +106,33 @@ class TrackableObject : public TrackableObjectBase {
|
||||
|
||||
protected:
|
||||
TrackableObject() {}
|
||||
|
||||
~TrackableObject() override {
|
||||
RemoveFromWeakMap();
|
||||
}
|
||||
|
||||
void AfterInit(v8::Isolate* isolate) override {
|
||||
if (!weak_map_) {
|
||||
weak_map_.reset(new atom::IDWeakMap);
|
||||
RegisterDestructionCallback(
|
||||
base::Bind(&TrackableObject<T>::ReleaseAllWeakReferences));
|
||||
weak_map_.reset(new atom::KeyWeakMap<int32_t>);
|
||||
}
|
||||
weak_map_id_ = weak_map_->Add(isolate, GetWrapper(isolate));
|
||||
TrackableObjectBase::AfterInit(isolate);
|
||||
weak_map_id_ = ++next_id_;
|
||||
weak_map_->Set(isolate, weak_map_id_, Wrappable<T>::GetWrapper());
|
||||
if (wrapped_)
|
||||
AttachAsUserData(wrapped_);
|
||||
}
|
||||
|
||||
private:
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override {
|
||||
if (template_.IsEmpty()) {
|
||||
auto templ = v8::ObjectTemplate::New(isolate);
|
||||
T::BuildPrototype(isolate, templ);
|
||||
template_.Reset(isolate, templ);
|
||||
}
|
||||
|
||||
return ObjectTemplateBuilder(
|
||||
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
|
||||
}
|
||||
|
||||
// Releases all weak references in weak map, called when app is terminating.
|
||||
static void ReleaseAllWeakReferences() {
|
||||
weak_map_.reset();
|
||||
}
|
||||
|
||||
static v8::Persistent<v8::ObjectTemplate> template_;
|
||||
static scoped_ptr<atom::IDWeakMap> weak_map_;
|
||||
static int32_t next_id_;
|
||||
static scoped_ptr<atom::KeyWeakMap<int32_t>> weak_map_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TrackableObject);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
v8::Persistent<v8::ObjectTemplate> TrackableObject<T>::template_;
|
||||
int32_t TrackableObject<T>::next_id_ = 0;
|
||||
|
||||
template<typename T>
|
||||
scoped_ptr<atom::IDWeakMap> TrackableObject<T>::weak_map_;
|
||||
scoped_ptr<atom::KeyWeakMap<int32_t>> TrackableObject<T>::weak_map_;
|
||||
|
||||
} // namespace mate
|
||||
|
||||
|
||||
@@ -32,18 +32,18 @@ AtomAccessTokenStore::~AtomAccessTokenStore() {
|
||||
}
|
||||
|
||||
void AtomAccessTokenStore::LoadAccessTokens(
|
||||
const LoadAccessTokensCallbackType& callback) {
|
||||
AccessTokenSet access_token_set;
|
||||
const LoadAccessTokensCallback& callback) {
|
||||
AccessTokenMap access_token_map;
|
||||
|
||||
// Equivelent to access_token_set[kGeolocationProviderURL].
|
||||
// Equivelent to access_token_map[kGeolocationProviderURL].
|
||||
// Somehow base::string16 is causing compilation errors when used in a pair
|
||||
// of std::map on Linux, this can work around it.
|
||||
std::pair<GURL, base::string16> token_pair;
|
||||
token_pair.first = GURL(kGeolocationProviderURL);
|
||||
access_token_set.insert(token_pair);
|
||||
access_token_map.insert(token_pair);
|
||||
|
||||
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
|
||||
callback.Run(access_token_set, browser_context->url_request_context_getter());
|
||||
callback.Run(access_token_map, browser_context->url_request_context_getter());
|
||||
}
|
||||
|
||||
void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url,
|
||||
|
||||
@@ -18,7 +18,7 @@ class AtomAccessTokenStore : public content::AccessTokenStore {
|
||||
|
||||
// content::AccessTokenStore:
|
||||
void LoadAccessTokens(
|
||||
const LoadAccessTokensCallbackType& callback) override;
|
||||
const LoadAccessTokensCallback& callback) override;
|
||||
void SaveAccessToken(const GURL& server_url,
|
||||
const base::string16& access_token) override;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
#include "atom/browser/api/atom_api_app.h"
|
||||
#include "atom/browser/atom_access_token_store.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
@@ -36,7 +37,6 @@
|
||||
#include "content/public/browser/site_instance.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/web_preferences.h"
|
||||
#include "net/cert/x509_certificate.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
@@ -49,31 +49,9 @@ namespace {
|
||||
// Next navigation should not restart renderer process.
|
||||
bool g_suppress_renderer_process_restart = false;
|
||||
|
||||
// Custom schemes to be registered to standard.
|
||||
std::string g_custom_schemes = "";
|
||||
// Custom schemes to be registered to handle service worker.
|
||||
std::string g_custom_service_worker_schemes = "";
|
||||
|
||||
scoped_refptr<net::X509Certificate> ImportCertFromFile(
|
||||
const base::FilePath& path) {
|
||||
if (path.empty())
|
||||
return nullptr;
|
||||
|
||||
std::string cert_data;
|
||||
if (!base::ReadFileToString(path, &cert_data))
|
||||
return nullptr;
|
||||
|
||||
net::CertificateList certs =
|
||||
net::X509Certificate::CreateCertificateListFromBytes(
|
||||
cert_data.data(), cert_data.size(),
|
||||
net::X509Certificate::FORMAT_AUTO);
|
||||
|
||||
if (certs.empty())
|
||||
return nullptr;
|
||||
|
||||
return certs[0];
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
@@ -81,11 +59,6 @@ void AtomBrowserClient::SuppressRendererProcessRestartForOnce() {
|
||||
g_suppress_renderer_process_restart = true;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::SetCustomSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
g_custom_schemes = base::JoinString(schemes, ",");
|
||||
}
|
||||
|
||||
void AtomBrowserClient::SetCustomServiceWorkerSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
g_custom_service_worker_schemes = base::JoinString(schemes, ",");
|
||||
@@ -173,11 +146,6 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
if (process_type != "renderer")
|
||||
return;
|
||||
|
||||
// The registered standard schemes.
|
||||
if (!g_custom_schemes.empty())
|
||||
command_line->AppendSwitchASCII(switches::kRegisterStandardSchemes,
|
||||
g_custom_schemes);
|
||||
|
||||
// The registered service worker schemes.
|
||||
if (!g_custom_service_worker_schemes.empty())
|
||||
command_line->AppendSwitchASCII(switches::kRegisterServiceWorkerSchemes,
|
||||
@@ -241,16 +209,6 @@ void AtomBrowserClient::SelectClientCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
scoped_ptr<content::ClientCertificateDelegate> delegate) {
|
||||
// --client-certificate=`path`
|
||||
auto cmd = base::CommandLine::ForCurrentProcess();
|
||||
if (cmd->HasSwitch(switches::kClientCertificate)) {
|
||||
auto cert_path = cmd->GetSwitchValuePath(switches::kClientCertificate);
|
||||
auto certificate = ImportCertFromFile(cert_path);
|
||||
if (certificate.get())
|
||||
delegate->ContinueWithCertificate(certificate.get());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cert_request_info->client_certs.empty() && delegate_) {
|
||||
delegate_->SelectClientCertificate(
|
||||
web_contents, cert_request_info, std::move(delegate));
|
||||
@@ -264,6 +222,39 @@ void AtomBrowserClient::ResourceDispatcherHostCreated() {
|
||||
resource_dispatcher_host_delegate_.get());
|
||||
}
|
||||
|
||||
bool AtomBrowserClient::CanCreateWindow(
|
||||
const GURL& opener_url,
|
||||
const GURL& opener_top_level_frame_url,
|
||||
const GURL& source_origin,
|
||||
WindowContainerType container_type,
|
||||
const std::string& frame_name,
|
||||
const GURL& target_url,
|
||||
const content::Referrer& referrer,
|
||||
WindowOpenDisposition disposition,
|
||||
const blink::WebWindowFeatures& features,
|
||||
bool user_gesture,
|
||||
bool opener_suppressed,
|
||||
content::ResourceContext* context,
|
||||
int render_process_id,
|
||||
int opener_render_view_id,
|
||||
int opener_render_frame_id,
|
||||
bool* no_javascript_access) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
|
||||
if (delegate_) {
|
||||
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&api::App::OnCreateWindow,
|
||||
base::Unretained(static_cast<api::App*>(delegate_)),
|
||||
target_url,
|
||||
frame_name,
|
||||
disposition,
|
||||
render_process_id,
|
||||
opener_render_frame_id));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
|
||||
const content::MainFunctionParams&) {
|
||||
v8::V8::Initialize(); // Init V8 before creating main parts.
|
||||
|
||||
@@ -36,8 +36,7 @@ class AtomBrowserClient : public brightray::BrowserClient,
|
||||
|
||||
// Don't force renderer process to restart for once.
|
||||
static void SuppressRendererProcessRestartForOnce();
|
||||
// Custom schemes to be registered to standard.
|
||||
static void SetCustomSchemes(const std::vector<std::string>& schemes);
|
||||
|
||||
// Custom schemes to be registered to handle service worker.
|
||||
static void SetCustomServiceWorkerSchemes(
|
||||
const std::vector<std::string>& schemes);
|
||||
@@ -76,6 +75,22 @@ class AtomBrowserClient : public brightray::BrowserClient,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
|
||||
void ResourceDispatcherHostCreated() override;
|
||||
bool CanCreateWindow(const GURL& opener_url,
|
||||
const GURL& opener_top_level_frame_url,
|
||||
const GURL& source_origin,
|
||||
WindowContainerType container_type,
|
||||
const std::string& frame_name,
|
||||
const GURL& target_url,
|
||||
const content::Referrer& referrer,
|
||||
WindowOpenDisposition disposition,
|
||||
const blink::WebWindowFeatures& features,
|
||||
bool user_gesture,
|
||||
bool opener_suppressed,
|
||||
content::ResourceContext* context,
|
||||
int render_process_id,
|
||||
int opener_render_view_id,
|
||||
int opener_render_frame_id,
|
||||
bool* no_javascript_access) override;
|
||||
|
||||
// brightray::BrowserClient:
|
||||
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/prefs/pref_registry_simple.h"
|
||||
#include "components/prefs/pref_registry_simple.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/threading/sequenced_worker_pool.h"
|
||||
@@ -65,10 +65,9 @@ std::string RemoveWhitespace(const std::string& str) {
|
||||
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||
bool in_memory)
|
||||
: brightray::BrowserContext(partition, in_memory),
|
||||
cert_verifier_(nullptr),
|
||||
cert_verifier_(new AtomCertVerifier),
|
||||
job_factory_(new AtomURLRequestJobFactory),
|
||||
network_delegate_(new AtomNetworkDelegate),
|
||||
allow_ntlm_everywhere_(false) {
|
||||
network_delegate_(new AtomNetworkDelegate) {
|
||||
}
|
||||
|
||||
AtomBrowserContext::~AtomBrowserContext() {
|
||||
@@ -178,8 +177,6 @@ content::PermissionManager* AtomBrowserContext::GetPermissionManager() {
|
||||
}
|
||||
|
||||
scoped_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier() {
|
||||
DCHECK(!cert_verifier_);
|
||||
cert_verifier_ = new AtomCertVerifier;
|
||||
return make_scoped_ptr(cert_verifier_);
|
||||
}
|
||||
|
||||
@@ -194,16 +191,7 @@ void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
|
||||
PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &download_dir);
|
||||
pref_registry->RegisterFilePathPref(prefs::kDownloadDefaultDirectory,
|
||||
download_dir);
|
||||
}
|
||||
|
||||
bool AtomBrowserContext::AllowNTLMCredentialsForDomain(const GURL& origin) {
|
||||
if (allow_ntlm_everywhere_)
|
||||
return true;
|
||||
return Delegate::AllowNTLMCredentialsForDomain(origin);
|
||||
}
|
||||
|
||||
void AtomBrowserContext::AllowNTLMCredentialsForAllDomains(bool should_allow) {
|
||||
allow_ntlm_everywhere_ = should_allow;
|
||||
pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -33,7 +33,6 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
const base::FilePath& base_path) override;
|
||||
scoped_ptr<net::CertVerifier> CreateCertVerifier() override;
|
||||
net::SSLConfigService* CreateSSLConfigService() override;
|
||||
bool AllowNTLMCredentialsForDomain(const GURL& auth_origin) override;
|
||||
|
||||
// content::BrowserContext:
|
||||
content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
|
||||
@@ -43,8 +42,6 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
// brightray::BrowserContext:
|
||||
void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
|
||||
|
||||
void AllowNTLMCredentialsForAllDomains(bool should_allow);
|
||||
|
||||
AtomCertVerifier* cert_verifier() const { return cert_verifier_; }
|
||||
|
||||
AtomURLRequestJobFactory* job_factory() const { return job_factory_; }
|
||||
@@ -61,8 +58,6 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
AtomURLRequestJobFactory* job_factory_;
|
||||
AtomNetworkDelegate* network_delegate_;
|
||||
|
||||
bool allow_ntlm_everywhere_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
|
||||
};
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ AtomBrowserMainParts::~AtomBrowserMainParts() {
|
||||
// Leak the JavascriptEnvironment on exit.
|
||||
// This is to work around the bug that V8 would be waiting for background
|
||||
// tasks to finish on exit, while somehow it waits forever in Electron, more
|
||||
// about this can be found at https://github.com/atom/electron/issues/4767.
|
||||
// about this can be found at https://github.com/electron/electron/issues/4767.
|
||||
// On the other handle there is actually no need to gracefully shutdown V8
|
||||
// on exit in the main process, we already ensured all necessary resources get
|
||||
// cleaned up, and it would make quitting faster.
|
||||
@@ -106,17 +106,21 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
|
||||
node_debugger_.reset(new NodeDebugger(js_env_->isolate()));
|
||||
|
||||
// Create the global environment.
|
||||
global_env = node_bindings_->CreateEnvironment(js_env_->context());
|
||||
node::Environment* env =
|
||||
node_bindings_->CreateEnvironment(js_env_->context());
|
||||
|
||||
// Make sure node can get correct environment when debugging.
|
||||
if (node_debugger_->IsRunning())
|
||||
global_env->AssignToContext(v8::Debug::GetDebugContext());
|
||||
env->AssignToContext(v8::Debug::GetDebugContext());
|
||||
|
||||
// Add atom-shell extended APIs.
|
||||
atom_bindings_->BindTo(js_env_->isolate(), global_env->process_object());
|
||||
atom_bindings_->BindTo(js_env_->isolate(), env->process_object());
|
||||
|
||||
// Load everything.
|
||||
node_bindings_->LoadEnvironment(global_env);
|
||||
node_bindings_->LoadEnvironment(env);
|
||||
|
||||
// Wrap the uv loop with global env.
|
||||
node_bindings_->set_uv_env(env);
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
||||
@@ -132,9 +136,8 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
||||
// Start idle gc.
|
||||
gc_timer_.Start(
|
||||
FROM_HERE, base::TimeDelta::FromMinutes(1),
|
||||
base::Bind(base::IgnoreResult(&v8::Isolate::IdleNotification),
|
||||
base::Unretained(js_env_->isolate()),
|
||||
1000));
|
||||
base::Bind(&v8::Isolate::LowMemoryNotification,
|
||||
base::Unretained(js_env_->isolate())));
|
||||
|
||||
brightray::BrowserMainParts::PreMainMessageLoopRun();
|
||||
bridge_task_runner_->MessageLoopIsReady();
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/prefs/pref_service.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
@@ -70,12 +70,15 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
|
||||
return;
|
||||
|
||||
NativeWindow* window = nullptr;
|
||||
auto relay = NativeWindowRelay::FromWebContents(item->GetWebContents());
|
||||
content::WebContents* web_contents = item->GetWebContents();
|
||||
auto relay = web_contents ? NativeWindowRelay::FromWebContents(web_contents)
|
||||
: nullptr;
|
||||
if (relay)
|
||||
window = relay->window.get();
|
||||
|
||||
base::FilePath path;
|
||||
if (file_dialog::ShowSaveDialog(window, item->GetURL().spec(), default_path,
|
||||
if (file_dialog::ShowSaveDialog(window, item->GetURL().spec(),
|
||||
"", default_path,
|
||||
file_dialog::Filters(), &path)) {
|
||||
// Remember the last selected download directory.
|
||||
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
|
||||
|
||||
@@ -40,7 +40,7 @@ void AtomPermissionManager::SetPermissionRequestHandler(
|
||||
if (handler.is_null() && !pending_requests_.empty()) {
|
||||
for (const auto& request : pending_requests_) {
|
||||
if (!WebContentsDestroyed(request.second.render_process_id))
|
||||
request.second.callback.Run(content::PERMISSION_STATUS_DENIED);
|
||||
request.second.callback.Run(content::PermissionStatus::DENIED);
|
||||
}
|
||||
pending_requests_.clear();
|
||||
}
|
||||
@@ -51,7 +51,6 @@ int AtomPermissionManager::RequestPermission(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
const ResponseCallback& response_callback) {
|
||||
int process_id = render_frame_host->GetProcess()->GetID();
|
||||
|
||||
@@ -74,7 +73,7 @@ int AtomPermissionManager::RequestPermission(
|
||||
return request_id_;
|
||||
}
|
||||
|
||||
response_callback.Run(content::PERMISSION_STATUS_GRANTED);
|
||||
response_callback.Run(content::PermissionStatus::GRANTED);
|
||||
return kNoPendingOperation;
|
||||
}
|
||||
|
||||
@@ -82,7 +81,6 @@ int AtomPermissionManager::RequestPermissions(
|
||||
const std::vector<content::PermissionType>& permissions,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
const base::Callback<void(
|
||||
const std::vector<content::PermissionStatus>&)>& callback) {
|
||||
// FIXME(zcbenz): Just ignore multiple permissions request for now.
|
||||
@@ -92,7 +90,7 @@ int AtomPermissionManager::RequestPermissions(
|
||||
content::ChildProcessSecurityPolicy::GetInstance()->
|
||||
GrantSendMidiSysExMessage(render_frame_host->GetProcess()->GetID());
|
||||
}
|
||||
permissionStatuses.push_back(content::PERMISSION_STATUS_GRANTED);
|
||||
permissionStatuses.push_back(content::PermissionStatus::GRANTED);
|
||||
}
|
||||
callback.Run(permissionStatuses);
|
||||
return kNoPendingOperation;
|
||||
@@ -115,7 +113,7 @@ void AtomPermissionManager::CancelPermissionRequest(int request_id) {
|
||||
auto request = pending_requests_.find(request_id);
|
||||
if (request != pending_requests_.end()) {
|
||||
if (!WebContentsDestroyed(request->second.render_process_id))
|
||||
request->second.callback.Run(content::PERMISSION_STATUS_DENIED);
|
||||
request->second.callback.Run(content::PermissionStatus::DENIED);
|
||||
pending_requests_.erase(request);
|
||||
}
|
||||
}
|
||||
@@ -130,7 +128,7 @@ content::PermissionStatus AtomPermissionManager::GetPermissionStatus(
|
||||
content::PermissionType permission,
|
||||
const GURL& requesting_origin,
|
||||
const GURL& embedding_origin) {
|
||||
return content::PERMISSION_STATUS_GRANTED;
|
||||
return content::PermissionStatus::GRANTED;
|
||||
}
|
||||
|
||||
void AtomPermissionManager::RegisterPermissionUsage(
|
||||
|
||||
@@ -37,13 +37,11 @@ class AtomPermissionManager : public content::PermissionManager {
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
const ResponseCallback& callback) override;
|
||||
int RequestPermissions(
|
||||
const std::vector<content::PermissionType>& permissions,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
bool user_gesture,
|
||||
const base::Callback<void(
|
||||
const std::vector<content::PermissionStatus>&)>& callback) override;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
|
||||
|
||||
#include "atom/browser/login_handler.h"
|
||||
#include "atom/browser/web_contents_permission_helper.h"
|
||||
#include "atom/common/platform_util.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "net/base/escape.h"
|
||||
@@ -14,20 +15,46 @@ using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
void OnOpenExternal(const GURL& escaped_url,
|
||||
bool allowed) {
|
||||
if (allowed)
|
||||
platform_util::OpenExternal(escaped_url, true);
|
||||
}
|
||||
|
||||
void HandleExternalProtocolInUI(
|
||||
const GURL& url,
|
||||
const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
|
||||
bool has_user_gesture) {
|
||||
content::WebContents* web_contents = web_contents_getter.Run();
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
GURL escaped_url(net::EscapeExternalHandlerValue(url.spec()));
|
||||
auto callback = base::Bind(&OnOpenExternal, escaped_url);
|
||||
auto permission_helper =
|
||||
WebContentsPermissionHelper::FromWebContents(web_contents);
|
||||
permission_helper->RequestOpenExternalPermission(callback, has_user_gesture);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomResourceDispatcherHostDelegate::AtomResourceDispatcherHostDelegate() {
|
||||
}
|
||||
|
||||
bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol(
|
||||
const GURL& url,
|
||||
int child_id,
|
||||
const content::ResourceRequestInfo::WebContentsGetter&,
|
||||
const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
|
||||
bool is_main_frame,
|
||||
ui::PageTransition transition,
|
||||
bool has_user_gesture) {
|
||||
GURL escaped_url(net::EscapeExternalHandlerValue(url.spec()));
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(
|
||||
base::IgnoreResult(platform_util::OpenExternal), escaped_url, true));
|
||||
base::Bind(&HandleExternalProtocolInUI,
|
||||
url,
|
||||
web_contents_getter,
|
||||
has_user_gesture));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
105
atom/browser/atom_security_state_model_client.cc
Normal file
105
atom/browser/atom_security_state_model_client.cc
Normal file
@@ -0,0 +1,105 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/atom_security_state_model_client.h"
|
||||
|
||||
#include "content/public/browser/cert_store.h"
|
||||
#include "content/public/browser/navigation_entry.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/origin_util.h"
|
||||
#include "content/public/common/ssl_status.h"
|
||||
#include "net/cert/x509_certificate.h"
|
||||
|
||||
DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::AtomSecurityStateModelClient);
|
||||
|
||||
using security_state::SecurityStateModel;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
SecurityStateModel::SecurityLevel GetSecurityLevelForSecurityStyle(
|
||||
content::SecurityStyle style) {
|
||||
switch (style) {
|
||||
case content::SECURITY_STYLE_UNKNOWN:
|
||||
return SecurityStateModel::NONE;
|
||||
case content::SECURITY_STYLE_UNAUTHENTICATED:
|
||||
return SecurityStateModel::NONE;
|
||||
case content::SECURITY_STYLE_AUTHENTICATION_BROKEN:
|
||||
return SecurityStateModel::SECURITY_ERROR;
|
||||
case content::SECURITY_STYLE_WARNING:
|
||||
return SecurityStateModel::SECURITY_WARNING;
|
||||
case content::SECURITY_STYLE_AUTHENTICATED:
|
||||
return SecurityStateModel::SECURE;
|
||||
}
|
||||
return SecurityStateModel::NONE;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomSecurityStateModelClient::AtomSecurityStateModelClient(
|
||||
content::WebContents* web_contents)
|
||||
: web_contents_(web_contents),
|
||||
security_state_model_(new SecurityStateModel()) {
|
||||
security_state_model_->SetClient(this);
|
||||
}
|
||||
|
||||
AtomSecurityStateModelClient::~AtomSecurityStateModelClient() {
|
||||
}
|
||||
|
||||
const SecurityStateModel::SecurityInfo&
|
||||
AtomSecurityStateModelClient::GetSecurityInfo() const {
|
||||
return security_state_model_->GetSecurityInfo();
|
||||
}
|
||||
|
||||
bool AtomSecurityStateModelClient::RetrieveCert(
|
||||
scoped_refptr<net::X509Certificate>* cert) {
|
||||
content::NavigationEntry* entry =
|
||||
web_contents_->GetController().GetVisibleEntry();
|
||||
if (!entry)
|
||||
return false;
|
||||
return content::CertStore::GetInstance()->RetrieveCert(
|
||||
entry->GetSSL().cert_id, cert);
|
||||
}
|
||||
|
||||
bool AtomSecurityStateModelClient::UsedPolicyInstalledCertificate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomSecurityStateModelClient::IsOriginSecure(const GURL& url) {
|
||||
return content::IsOriginSecure(url);
|
||||
}
|
||||
|
||||
void AtomSecurityStateModelClient::GetVisibleSecurityState(
|
||||
SecurityStateModel::VisibleSecurityState* state) {
|
||||
content::NavigationEntry* entry =
|
||||
web_contents_->GetController().GetVisibleEntry();
|
||||
if (!entry ||
|
||||
entry->GetSSL().security_style == content::SECURITY_STYLE_UNKNOWN) {
|
||||
*state = SecurityStateModel::VisibleSecurityState();
|
||||
return;
|
||||
}
|
||||
|
||||
state->initialized = true;
|
||||
state->url = entry->GetURL();
|
||||
const content::SSLStatus& ssl = entry->GetSSL();
|
||||
state->initial_security_level =
|
||||
GetSecurityLevelForSecurityStyle(ssl.security_style);
|
||||
state->cert_id = ssl.cert_id;
|
||||
state->cert_status = ssl.cert_status;
|
||||
state->connection_status = ssl.connection_status;
|
||||
state->security_bits = ssl.security_bits;
|
||||
state->sct_verify_statuses.clear();
|
||||
for (const auto& sct : ssl.signed_certificate_timestamp_ids)
|
||||
state->sct_verify_statuses.push_back(sct.status);
|
||||
state->displayed_mixed_content =
|
||||
(ssl.content_status & content::SSLStatus::DISPLAYED_INSECURE_CONTENT)
|
||||
? true
|
||||
: false;
|
||||
state->ran_mixed_content =
|
||||
(ssl.content_status & content::SSLStatus::RAN_INSECURE_CONTENT) ? true
|
||||
: false;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
42
atom/browser/atom_security_state_model_client.h
Normal file
42
atom/browser/atom_security_state_model_client.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_ATOM_SECURITY_STATE_MODEL_CLIENT_H_
|
||||
#define ATOM_BROWSER_ATOM_SECURITY_STATE_MODEL_CLIENT_H_
|
||||
|
||||
#include "components/security_state/security_state_model.h"
|
||||
#include "components/security_state/security_state_model_client.h"
|
||||
#include "content/public/browser/web_contents_user_data.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomSecurityStateModelClient
|
||||
: public security_state::SecurityStateModelClient,
|
||||
public content::WebContentsUserData<AtomSecurityStateModelClient> {
|
||||
public:
|
||||
~AtomSecurityStateModelClient() override;
|
||||
|
||||
const security_state::SecurityStateModel::SecurityInfo&
|
||||
GetSecurityInfo() const;
|
||||
|
||||
// security_state::SecurityStateModelClient:
|
||||
void GetVisibleSecurityState(
|
||||
security_state::SecurityStateModel::VisibleSecurityState* state) override;
|
||||
bool RetrieveCert(scoped_refptr<net::X509Certificate>* cert) override;
|
||||
bool UsedPolicyInstalledCertificate() override;
|
||||
bool IsOriginSecure(const GURL& url) override;
|
||||
|
||||
private:
|
||||
explicit AtomSecurityStateModelClient(content::WebContents* web_contents);
|
||||
friend class content::WebContentsUserData<AtomSecurityStateModelClient>;
|
||||
|
||||
content::WebContents* web_contents_;
|
||||
scoped_ptr<security_state::SecurityStateModel> security_state_model_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomSecurityStateModelClient);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_SECURITY_STATE_MODEL_CLIENT_H_
|
||||
@@ -22,6 +22,12 @@ SQRLUpdater* g_updater = nil;
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
|
||||
bool g_update_available = false;
|
||||
|
||||
}
|
||||
|
||||
// static
|
||||
void AutoUpdater::SetFeedURL(const std::string& feed) {
|
||||
if (g_updater == nil) {
|
||||
@@ -69,6 +75,7 @@ void AutoUpdater::CheckForUpdates() {
|
||||
take:1]
|
||||
subscribeNext:^(SQRLDownloadedUpdate *downloadedUpdate) {
|
||||
if (downloadedUpdate) {
|
||||
g_update_available = true;
|
||||
SQRLUpdate* update = downloadedUpdate.update;
|
||||
// There is a new update that has been downloaded.
|
||||
delegate->OnUpdateDownloaded(
|
||||
@@ -77,23 +84,32 @@ void AutoUpdater::CheckForUpdates() {
|
||||
base::Time::FromDoubleT(update.releaseDate.timeIntervalSince1970),
|
||||
base::SysNSStringToUTF8(update.updateURL.absoluteString));
|
||||
} else {
|
||||
g_update_available = false;
|
||||
// When the completed event is sent with no update, then we know there
|
||||
// is no update available.
|
||||
delegate->OnUpdateNotAvailable();
|
||||
}
|
||||
} error:^(NSError *error) {
|
||||
delegate->OnError(base::SysNSStringToUTF8(
|
||||
NSString* failureString = error.localizedFailureReason ?
|
||||
[NSString stringWithFormat:@"%@: %@",
|
||||
error.localizedDescription, error.localizedFailureReason]));
|
||||
error.localizedDescription,
|
||||
error.localizedFailureReason] :
|
||||
[NSString stringWithString:error.localizedDescription];
|
||||
delegate->OnError(base::SysNSStringToUTF8(failureString));
|
||||
}];
|
||||
}
|
||||
|
||||
void AutoUpdater::QuitAndInstall() {
|
||||
[[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) {
|
||||
Delegate* delegate = AutoUpdater::GetDelegate();
|
||||
Delegate* delegate = AutoUpdater::GetDelegate();
|
||||
if (g_update_available) {
|
||||
[[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) {
|
||||
if (delegate)
|
||||
delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription));
|
||||
}];
|
||||
} else {
|
||||
if (delegate)
|
||||
delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription));
|
||||
}];
|
||||
delegate->OnError("No update available, can't quit and install");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace auto_updater
|
||||
|
||||
@@ -9,12 +9,16 @@
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/path_service.h"
|
||||
#include "brightray/browser/brightray_paths.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
Browser::Browser()
|
||||
: is_quiting_(false),
|
||||
is_exiting_(false),
|
||||
is_ready_(false),
|
||||
is_shutdown_(false) {
|
||||
WindowList::AddObserver(this);
|
||||
@@ -49,9 +53,12 @@ void Browser::Exit(int code) {
|
||||
// Message loop is not ready, quit directly.
|
||||
exit(code);
|
||||
} else {
|
||||
// Prepare to quit when all windows have been closed..
|
||||
// Prepare to quit when all windows have been closed.
|
||||
is_quiting_ = true;
|
||||
|
||||
// Remember this caller so that we don't emit unrelated events.
|
||||
is_exiting_ = true;
|
||||
|
||||
// Must destroy windows before quitting, otherwise bad things can happen.
|
||||
atom::WindowList* window_list = atom::WindowList::GetInstance();
|
||||
if (window_list->size() == 0) {
|
||||
@@ -135,6 +142,11 @@ void Browser::WillFinishLaunching() {
|
||||
}
|
||||
|
||||
void Browser::DidFinishLaunching() {
|
||||
// Make sure the userData directory is created.
|
||||
base::FilePath user_data;
|
||||
if (PathService::Get(brightray::DIR_USER_DATA, &user_data))
|
||||
base::CreateDirectoryAndGetError(user_data, nullptr);
|
||||
|
||||
is_ready_ = true;
|
||||
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching());
|
||||
}
|
||||
@@ -175,14 +187,12 @@ void Browser::OnWindowCloseCancelled(NativeWindow* window) {
|
||||
}
|
||||
|
||||
void Browser::OnWindowAllClosed() {
|
||||
if (is_quiting_)
|
||||
if (is_exiting_)
|
||||
Shutdown();
|
||||
else if (is_quiting_)
|
||||
NotifyAndShutdown();
|
||||
else
|
||||
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnWindowAllClosed());
|
||||
}
|
||||
|
||||
void Browser::PlatformThemeChanged() {
|
||||
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnPlatformThemeChanged());
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -76,6 +76,15 @@ class Browser : public WindowListObserver {
|
||||
// Set the application user model ID.
|
||||
void SetAppUserModelID(const base::string16& name);
|
||||
|
||||
// Remove the default protocol handler registry key
|
||||
bool RemoveAsDefaultProtocolClient(const std::string& protocol);
|
||||
|
||||
// Set as default handler for a protocol.
|
||||
bool SetAsDefaultProtocolClient(const std::string& protocol);
|
||||
|
||||
// Query the current state of default handler for a protocol.
|
||||
bool IsDefaultProtocolClient(const std::string& protocol);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// Hide the application.
|
||||
void Hide();
|
||||
@@ -83,8 +92,16 @@ class Browser : public WindowListObserver {
|
||||
// Show the application.
|
||||
void Show();
|
||||
|
||||
// Check if the system is in Dark Mode.
|
||||
bool IsDarkMode();
|
||||
// Creates an activity and sets it as the one currently in use.
|
||||
void SetUserActivity(const std::string& type,
|
||||
const base::DictionaryValue& user_info);
|
||||
|
||||
// Returns the type name of the current user activity.
|
||||
std::string GetCurrentActivityType();
|
||||
|
||||
// Resumes an activity via hand-off.
|
||||
bool ContinueUserActivity(const std::string& type,
|
||||
const base::DictionaryValue& user_info);
|
||||
|
||||
// Bounce the dock icon.
|
||||
enum BounceType {
|
||||
@@ -94,6 +111,9 @@ class Browser : public WindowListObserver {
|
||||
int DockBounce(BounceType type);
|
||||
void DockCancelBounce(int request_id);
|
||||
|
||||
// Bounce the Downloads stack.
|
||||
void DockDownloadFinished(const std::string& filePath);
|
||||
|
||||
// Set/Get dock's badge text.
|
||||
void DockSetBadgeText(const std::string& label);
|
||||
std::string DockGetBadgeText();
|
||||
@@ -145,9 +165,6 @@ class Browser : public WindowListObserver {
|
||||
// Request basic auth login.
|
||||
void RequestLogin(LoginHandler* login_handler);
|
||||
|
||||
// Tell the application that plaform's theme changed.
|
||||
void PlatformThemeChanged();
|
||||
|
||||
void AddObserver(BrowserObserver* obs) {
|
||||
observers_.AddObserver(obs);
|
||||
}
|
||||
@@ -183,10 +200,13 @@ class Browser : public WindowListObserver {
|
||||
// Observers of the browser.
|
||||
base::ObserverList<BrowserObserver> observers_;
|
||||
|
||||
// Whether `app.exit()` has been called
|
||||
bool is_exiting_;
|
||||
|
||||
// Whether "ready" event has been emitted.
|
||||
bool is_ready_;
|
||||
|
||||
// The browse is being shutdown.
|
||||
// The browser is being shutdown.
|
||||
bool is_shutdown_;
|
||||
|
||||
std::string version_override_;
|
||||
|
||||
@@ -34,6 +34,18 @@ void Browser::ClearRecentDocuments() {
|
||||
void Browser::SetAppUserModelID(const base::string16& name) {
|
||||
}
|
||||
|
||||
bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Browser::GetExecutableFileVersion() const {
|
||||
return brightray::GetApplicationVersion();
|
||||
}
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
|
||||
#include "atom/browser/mac/atom_application.h"
|
||||
#include "atom/browser/mac/atom_application_delegate.h"
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/foundation_util.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
@@ -26,11 +28,6 @@ void Browser::Show() {
|
||||
[[AtomApplication sharedApplication] unhide:nil];
|
||||
}
|
||||
|
||||
bool Browser::IsDarkMode() {
|
||||
NSString *mode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
|
||||
return [mode isEqualToString: @"Dark"];
|
||||
}
|
||||
|
||||
void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||
NSString* path_string = base::mac::FilePathToNSString(path);
|
||||
if (!path_string)
|
||||
@@ -45,9 +42,100 @@ void Browser::ClearRecentDocuments() {
|
||||
[[NSDocumentController sharedDocumentController] clearRecentDocuments:nil];
|
||||
}
|
||||
|
||||
bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) {
|
||||
NSString* identifier = [base::mac::MainBundle() bundleIdentifier];
|
||||
if (!identifier)
|
||||
return false;
|
||||
|
||||
if (!Browser::IsDefaultProtocolClient(protocol))
|
||||
return false;
|
||||
|
||||
NSString* protocol_ns = [NSString stringWithUTF8String:protocol.c_str()];
|
||||
CFStringRef protocol_cf = base::mac::NSToCFCast(protocol_ns);
|
||||
CFArrayRef bundleList = LSCopyAllHandlersForURLScheme(protocol_cf);
|
||||
if (!bundleList) {
|
||||
return false;
|
||||
}
|
||||
// On Mac OS X, we can't query the default, but the handlers list seems to put
|
||||
// Apple's defaults first, so we'll use the first option that isn't our bundle
|
||||
CFStringRef other = nil;
|
||||
for (CFIndex i = 0; i < CFArrayGetCount(bundleList); i++) {
|
||||
other = (CFStringRef)CFArrayGetValueAtIndex(bundleList, i);
|
||||
if (![identifier isEqualToString: (__bridge NSString *)other]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus return_code = LSSetDefaultHandlerForURLScheme(protocol_cf, other);
|
||||
return return_code == noErr;
|
||||
}
|
||||
|
||||
bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
|
||||
if (protocol.empty())
|
||||
return false;
|
||||
|
||||
NSString* identifier = [base::mac::MainBundle() bundleIdentifier];
|
||||
if (!identifier)
|
||||
return false;
|
||||
|
||||
NSString* protocol_ns = [NSString stringWithUTF8String:protocol.c_str()];
|
||||
OSStatus return_code =
|
||||
LSSetDefaultHandlerForURLScheme(base::mac::NSToCFCast(protocol_ns),
|
||||
base::mac::NSToCFCast(identifier));
|
||||
return return_code == noErr;
|
||||
}
|
||||
|
||||
bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
|
||||
if (protocol.empty())
|
||||
return false;
|
||||
|
||||
NSString* identifier = [base::mac::MainBundle() bundleIdentifier];
|
||||
if (!identifier)
|
||||
return false;
|
||||
|
||||
NSString* protocol_ns = [NSString stringWithUTF8String:protocol.c_str()];
|
||||
|
||||
CFStringRef bundle =
|
||||
LSCopyDefaultHandlerForURLScheme(base::mac::NSToCFCast(protocol_ns));
|
||||
NSString* bundleId = static_cast<NSString*>(
|
||||
base::mac::CFTypeRefToNSObjectAutorelease(bundle));
|
||||
if (!bundleId)
|
||||
return false;
|
||||
|
||||
// Ensure the comparison is case-insensitive
|
||||
// as LS does not persist the case of the bundle id.
|
||||
NSComparisonResult result =
|
||||
[bundleId caseInsensitiveCompare:identifier];
|
||||
return result == NSOrderedSame;
|
||||
}
|
||||
|
||||
void Browser::SetAppUserModelID(const base::string16& name) {
|
||||
}
|
||||
|
||||
void Browser::SetUserActivity(
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
[[AtomApplication sharedApplication]
|
||||
setCurrentActivity:base::SysUTF8ToNSString(type)
|
||||
withUserInfo:DictionaryValueToNSDictionary(user_info)];
|
||||
}
|
||||
|
||||
std::string Browser::GetCurrentActivityType() {
|
||||
NSUserActivity* userActivity =
|
||||
[[AtomApplication sharedApplication] getCurrentActivity];
|
||||
return base::SysNSStringToUTF8(userActivity.activityType);
|
||||
}
|
||||
|
||||
bool Browser::ContinueUserActivity(
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
bool prevent_default = false;
|
||||
FOR_EACH_OBSERVER(BrowserObserver,
|
||||
observers_,
|
||||
OnContinueUserActivity(&prevent_default, type, user_info));
|
||||
return prevent_default;
|
||||
}
|
||||
|
||||
std::string Browser::GetExecutableFileVersion() const {
|
||||
return brightray::GetApplicationVersion();
|
||||
}
|
||||
@@ -70,6 +158,12 @@ void Browser::DockSetBadgeText(const std::string& label) {
|
||||
[tile setBadgeLabel:base::SysUTF8ToNSString(label)];
|
||||
}
|
||||
|
||||
void Browser::DockDownloadFinished(const std::string& filePath) {
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
postNotificationName: @"com.apple.DownloadFileFinished"
|
||||
object: base::SysUTF8ToNSString(filePath)];
|
||||
}
|
||||
|
||||
std::string Browser::DockGetBadgeText() {
|
||||
NSDockTile *tile = [[AtomApplication sharedApplication] dockTile];
|
||||
return base::SysNSStringToUTF8([tile badgeLabel]);
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class LoginHandler;
|
||||
@@ -45,7 +51,13 @@ class BrowserObserver {
|
||||
// The browser requests HTTP login.
|
||||
virtual void OnLogin(LoginHandler* login_handler) {}
|
||||
|
||||
virtual void OnPlatformThemeChanged() {}
|
||||
#if defined(OS_MACOSX)
|
||||
// The browser wants to resume a user activity via handoff. (OS X only)
|
||||
virtual void OnContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual ~BrowserObserver() {}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/win/win_util.h"
|
||||
#include "base/win/registry.h"
|
||||
#include "base/win/windows_version.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
|
||||
@@ -125,6 +126,149 @@ void Browser::SetUserTasks(const std::vector<UserTask>& tasks) {
|
||||
destinations->CommitList();
|
||||
}
|
||||
|
||||
bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) {
|
||||
if (protocol.empty())
|
||||
return false;
|
||||
|
||||
base::FilePath path;
|
||||
if (!PathService::Get(base::FILE_EXE, &path)) {
|
||||
LOG(ERROR) << "Error getting app exe path";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Main Registry Key
|
||||
HKEY root = HKEY_CURRENT_USER;
|
||||
std::string keyPathStr = "Software\\Classes\\" + protocol;
|
||||
std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end());
|
||||
|
||||
// Command Key
|
||||
std::string cmdPathStr = keyPathStr + "\\shell\\open\\command";
|
||||
std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end());
|
||||
|
||||
base::win::RegKey key;
|
||||
base::win::RegKey commandKey;
|
||||
if (FAILED(key.Open(root, keyPath.c_str(), KEY_ALL_ACCESS)))
|
||||
// Key doesn't even exist, we can confirm that it is not set
|
||||
return true;
|
||||
|
||||
if (FAILED(commandKey.Open(root, cmdPath.c_str(), KEY_ALL_ACCESS)))
|
||||
// Key doesn't even exist, we can confirm that it is not set
|
||||
return true;
|
||||
|
||||
std::wstring keyVal;
|
||||
if (FAILED(commandKey.ReadValue(L"", &keyVal)))
|
||||
// Default value not set, we can confirm that it is not set
|
||||
return true;
|
||||
|
||||
std::wstring exePath(path.value());
|
||||
std::wstring exe = L"\"" + exePath + L"\" \"%1\"";
|
||||
if (keyVal == exe) {
|
||||
// Let's kill the key
|
||||
if (FAILED(key.DeleteKey(L"shell")))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
|
||||
// HKEY_CLASSES_ROOT
|
||||
// $PROTOCOL
|
||||
// (Default) = "URL:$NAME"
|
||||
// URL Protocol = ""
|
||||
// shell
|
||||
// open
|
||||
// command
|
||||
// (Default) = "$COMMAND" "%1"
|
||||
//
|
||||
// However, the "HKEY_CLASSES_ROOT" key can only be written by the
|
||||
// Administrator user. So, we instead write to "HKEY_CURRENT_USER\
|
||||
// Software\Classes", which is inherited by "HKEY_CLASSES_ROOT"
|
||||
// anyway, and can be written by unprivileged users.
|
||||
|
||||
if (protocol.empty())
|
||||
return false;
|
||||
|
||||
base::FilePath path;
|
||||
if (!PathService::Get(base::FILE_EXE, &path)) {
|
||||
LOG(ERROR) << "Error getting app exe path";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Main Registry Key
|
||||
HKEY root = HKEY_CURRENT_USER;
|
||||
std::string keyPathStr = "Software\\Classes\\" + protocol;
|
||||
std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end());
|
||||
std::string urlDeclStr = "URL:" + protocol;
|
||||
std::wstring urlDecl = std::wstring(urlDeclStr.begin(), urlDeclStr.end());
|
||||
|
||||
// Command Key
|
||||
std::string cmdPathStr = keyPathStr + "\\shell\\open\\command";
|
||||
std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end());
|
||||
|
||||
// Executable Path
|
||||
std::wstring exePath(path.value());
|
||||
std::wstring exe = L"\"" + exePath + L"\" \"%1\"";
|
||||
|
||||
// Write information to registry
|
||||
base::win::RegKey key(root, keyPath.c_str(), KEY_ALL_ACCESS);
|
||||
if (FAILED(key.WriteValue(L"URL Protocol", L"")) ||
|
||||
FAILED(key.WriteValue(L"", urlDecl.c_str())))
|
||||
return false;
|
||||
|
||||
base::win::RegKey commandKey(root, cmdPath.c_str(), KEY_ALL_ACCESS);
|
||||
if (FAILED(commandKey.WriteValue(L"", exe.c_str())))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
|
||||
if (protocol.empty())
|
||||
return false;
|
||||
|
||||
base::FilePath path;
|
||||
if (!PathService::Get(base::FILE_EXE, &path)) {
|
||||
LOG(ERROR) << "Error getting app exe path";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Main Registry Key
|
||||
HKEY root = HKEY_CURRENT_USER;
|
||||
std::string keyPathStr = "Software\\Classes\\" + protocol;
|
||||
std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end());
|
||||
|
||||
// Command Key
|
||||
std::string cmdPathStr = keyPathStr + "\\shell\\open\\command";
|
||||
std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end());
|
||||
|
||||
base::win::RegKey key;
|
||||
base::win::RegKey commandKey;
|
||||
if (FAILED(key.Open(root, keyPath.c_str(), KEY_ALL_ACCESS)))
|
||||
// Key doesn't exist, we can confirm that it is not set
|
||||
return false;
|
||||
|
||||
if (FAILED(commandKey.Open(root, cmdPath.c_str(), KEY_ALL_ACCESS)))
|
||||
// Key doesn't exist, we can confirm that it is not set
|
||||
return false;
|
||||
|
||||
std::wstring keyVal;
|
||||
if (FAILED(commandKey.ReadValue(L"", &keyVal)))
|
||||
// Default value not set, we can confirm that it is not set
|
||||
return false;
|
||||
|
||||
std::wstring exePath(path.value());
|
||||
std::wstring exe = L"\"" + exePath + L"\" \"%1\"";
|
||||
if (keyVal == exe) {
|
||||
// Default value is the same as current file path
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PCWSTR Browser::GetAppUserModelID() {
|
||||
if (app_user_model_id_.empty()) {
|
||||
SetAppUserModelID(base::ReplaceStringPlaceholders(
|
||||
|
||||
@@ -4,38 +4,42 @@
|
||||
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_javascript_dialog_manager.h"
|
||||
#include "atom/browser/atom_security_state_model_client.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "atom/browser/web_dialog_helper.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "components/prefs/scoped_user_pref_update.h"
|
||||
#include "chrome/browser/printing/print_preview_message_handler.h"
|
||||
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||
#include "chrome/browser/ui/browser_dialogs.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/render_widget_host.h"
|
||||
#include "content/public/browser/security_style_explanation.h"
|
||||
#include "content/public/browser/security_style_explanations.h"
|
||||
#include "storage/browser/fileapi/isolated_context.h"
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#endif
|
||||
|
||||
#if defined(USE_X11)
|
||||
#include "atom/browser/browser.h"
|
||||
#endif
|
||||
|
||||
using content::BrowserThread;
|
||||
using security_state::SecurityStateModel;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kRootName[] = "<root>";
|
||||
|
||||
struct FileSystem {
|
||||
FileSystem() {
|
||||
}
|
||||
@@ -53,14 +57,14 @@ struct FileSystem {
|
||||
};
|
||||
|
||||
std::string RegisterFileSystem(content::WebContents* web_contents,
|
||||
const base::FilePath& path,
|
||||
std::string* registered_name) {
|
||||
const base::FilePath& path) {
|
||||
auto isolated_context = storage::IsolatedContext::GetInstance();
|
||||
std::string root_name(kRootName);
|
||||
std::string file_system_id = isolated_context->RegisterFileSystemForPath(
|
||||
storage::kFileSystemTypeNativeLocal,
|
||||
std::string(),
|
||||
path,
|
||||
registered_name);
|
||||
&root_name);
|
||||
|
||||
content::ChildProcessSecurityPolicy* policy =
|
||||
content::ChildProcessSecurityPolicy::GetInstance();
|
||||
@@ -80,13 +84,12 @@ std::string RegisterFileSystem(content::WebContents* web_contents,
|
||||
FileSystem CreateFileSystemStruct(
|
||||
content::WebContents* web_contents,
|
||||
const std::string& file_system_id,
|
||||
const std::string& registered_name,
|
||||
const std::string& file_system_path) {
|
||||
const GURL origin = web_contents->GetURL().GetOrigin();
|
||||
std::string file_system_name =
|
||||
storage::GetIsolatedFileSystemName(origin, file_system_id);
|
||||
std::string root_url = storage::GetIsolatedFileSystemRootURIString(
|
||||
origin, file_system_id, registered_name);
|
||||
origin, file_system_id, kRootName);
|
||||
return FileSystem(file_system_name, root_url, file_system_path);
|
||||
}
|
||||
|
||||
@@ -114,18 +117,66 @@ void AppendToFile(const base::FilePath& path,
|
||||
base::AppendToFile(path, content.data(), content.size());
|
||||
}
|
||||
|
||||
PrefService* GetPrefService(content::WebContents* web_contents) {
|
||||
auto context = web_contents->GetBrowserContext();
|
||||
return static_cast<atom::AtomBrowserContext*>(context)->prefs();
|
||||
}
|
||||
|
||||
std::set<std::string> GetAddedFileSystemPaths(
|
||||
content::WebContents* web_contents) {
|
||||
auto pref_service = GetPrefService(web_contents);
|
||||
const base::DictionaryValue* file_system_paths_value =
|
||||
pref_service->GetDictionary(prefs::kDevToolsFileSystemPaths);
|
||||
std::set<std::string> result;
|
||||
if (file_system_paths_value) {
|
||||
base::DictionaryValue::Iterator it(*file_system_paths_value);
|
||||
for (; !it.IsAtEnd(); it.Advance()) {
|
||||
result.insert(it.key());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IsDevToolsFileSystemAdded(
|
||||
content::WebContents* web_contents,
|
||||
const std::string& file_system_path) {
|
||||
auto file_system_paths = GetAddedFileSystemPaths(web_contents);
|
||||
return file_system_paths.find(file_system_path) != file_system_paths.end();
|
||||
}
|
||||
|
||||
content::SecurityStyle SecurityLevelToSecurityStyle(
|
||||
SecurityStateModel::SecurityLevel security_level) {
|
||||
switch (security_level) {
|
||||
case SecurityStateModel::NONE:
|
||||
return content::SECURITY_STYLE_UNAUTHENTICATED;
|
||||
case SecurityStateModel::SECURITY_WARNING:
|
||||
case SecurityStateModel::SECURITY_POLICY_WARNING:
|
||||
return content::SECURITY_STYLE_WARNING;
|
||||
case SecurityStateModel::EV_SECURE:
|
||||
case SecurityStateModel::SECURE:
|
||||
return content::SECURITY_STYLE_AUTHENTICATED;
|
||||
case SecurityStateModel::SECURITY_ERROR:
|
||||
return content::SECURITY_STYLE_AUTHENTICATION_BROKEN;
|
||||
}
|
||||
|
||||
return content::SECURITY_STYLE_UNKNOWN;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CommonWebContentsDelegate::CommonWebContentsDelegate()
|
||||
: html_fullscreen_(false),
|
||||
native_fullscreen_(false) {
|
||||
native_fullscreen_(false),
|
||||
devtools_file_system_indexer_(new DevToolsFileSystemIndexer) {
|
||||
}
|
||||
|
||||
CommonWebContentsDelegate::~CommonWebContentsDelegate() {
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::InitWithWebContents(
|
||||
content::WebContents* web_contents) {
|
||||
content::WebContents* web_contents,
|
||||
AtomBrowserContext* browser_context) {
|
||||
browser_context_ = browser_context;
|
||||
web_contents->SetDelegate(this);
|
||||
|
||||
printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
|
||||
@@ -239,6 +290,90 @@ bool CommonWebContentsDelegate::IsFullscreenForTabOrPending(
|
||||
return html_fullscreen_;
|
||||
}
|
||||
|
||||
content::SecurityStyle CommonWebContentsDelegate::GetSecurityStyle(
|
||||
content::WebContents* web_contents,
|
||||
content::SecurityStyleExplanations* explanations) {
|
||||
auto model_client =
|
||||
AtomSecurityStateModelClient::FromWebContents(web_contents);
|
||||
|
||||
const SecurityStateModel::SecurityInfo& security_info =
|
||||
model_client->GetSecurityInfo();
|
||||
|
||||
const content::SecurityStyle security_style =
|
||||
SecurityLevelToSecurityStyle(security_info.security_level);
|
||||
|
||||
explanations->ran_insecure_content_style =
|
||||
SecurityLevelToSecurityStyle(
|
||||
SecurityStateModel::kRanInsecureContentLevel);
|
||||
explanations->displayed_insecure_content_style =
|
||||
SecurityLevelToSecurityStyle(
|
||||
SecurityStateModel::kDisplayedInsecureContentLevel);
|
||||
|
||||
explanations->scheme_is_cryptographic = security_info.scheme_is_cryptographic;
|
||||
if (!security_info.scheme_is_cryptographic)
|
||||
return security_style;
|
||||
|
||||
if (security_info.sha1_deprecation_status ==
|
||||
SecurityStateModel::DEPRECATED_SHA1_MAJOR) {
|
||||
explanations->broken_explanations.push_back(
|
||||
content::SecurityStyleExplanation(
|
||||
kSHA1Certificate,
|
||||
kSHA1MajorDescription,
|
||||
security_info.cert_id));
|
||||
} else if (security_info.sha1_deprecation_status ==
|
||||
SecurityStateModel::DEPRECATED_SHA1_MINOR) {
|
||||
explanations->unauthenticated_explanations.push_back(
|
||||
content::SecurityStyleExplanation(
|
||||
kSHA1Certificate,
|
||||
kSHA1MinorDescription,
|
||||
security_info.cert_id));
|
||||
}
|
||||
|
||||
explanations->ran_insecure_content =
|
||||
security_info.mixed_content_status ==
|
||||
SecurityStateModel::RAN_MIXED_CONTENT ||
|
||||
security_info.mixed_content_status ==
|
||||
SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT;
|
||||
explanations->displayed_insecure_content =
|
||||
security_info.mixed_content_status ==
|
||||
SecurityStateModel::DISPLAYED_MIXED_CONTENT ||
|
||||
security_info.mixed_content_status ==
|
||||
SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT;
|
||||
|
||||
if (net::IsCertStatusError(security_info.cert_status)) {
|
||||
std::string error_string = net::ErrorToString(
|
||||
net::MapCertStatusToNetError(security_info.cert_status));
|
||||
|
||||
content::SecurityStyleExplanation explanation(
|
||||
kCertificateError,
|
||||
"There are issues with the site's certificate chain " + error_string,
|
||||
security_info.cert_id);
|
||||
|
||||
if (net::IsCertStatusMinorError(security_info.cert_status))
|
||||
explanations->unauthenticated_explanations.push_back(explanation);
|
||||
else
|
||||
explanations->broken_explanations.push_back(explanation);
|
||||
} else {
|
||||
if (security_info.sha1_deprecation_status ==
|
||||
SecurityStateModel::NO_DEPRECATED_SHA1) {
|
||||
explanations->secure_explanations.push_back(
|
||||
content::SecurityStyleExplanation(
|
||||
kValidCertificate,
|
||||
kValidCertificateDescription,
|
||||
security_info.cert_id));
|
||||
}
|
||||
}
|
||||
|
||||
if (security_info.is_secure_protocol_and_ciphersuite) {
|
||||
explanations->secure_explanations.push_back(
|
||||
content::SecurityStyleExplanation(
|
||||
kSecureProtocol,
|
||||
kSecureProtocolDescription));
|
||||
}
|
||||
|
||||
return security_style;
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsSaveToFile(
|
||||
const std::string& url, const std::string& content, bool save_as) {
|
||||
base::FilePath path;
|
||||
@@ -248,7 +383,7 @@ void CommonWebContentsDelegate::DevToolsSaveToFile(
|
||||
} else {
|
||||
file_dialog::Filters filters;
|
||||
base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url));
|
||||
if (!file_dialog::ShowSaveDialog(owner_window(), url, default_path,
|
||||
if (!file_dialog::ShowSaveDialog(owner_window(), url, "", default_path,
|
||||
filters, &path)) {
|
||||
base::StringValue url_value(url);
|
||||
web_contents_->CallClientFunction(
|
||||
@@ -278,6 +413,34 @@ void CommonWebContentsDelegate::DevToolsAppendToFile(
|
||||
base::Unretained(this), url));
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsRequestFileSystems() {
|
||||
auto file_system_paths = GetAddedFileSystemPaths(GetDevToolsWebContents());
|
||||
if (file_system_paths.empty()) {
|
||||
base::ListValue empty_file_system_value;
|
||||
web_contents_->CallClientFunction("DevToolsAPI.fileSystemsLoaded",
|
||||
&empty_file_system_value,
|
||||
nullptr, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<FileSystem> file_systems;
|
||||
for (auto file_system_path : file_system_paths) {
|
||||
base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path);
|
||||
std::string file_system_id = RegisterFileSystem(GetDevToolsWebContents(),
|
||||
path);
|
||||
FileSystem file_system = CreateFileSystemStruct(GetDevToolsWebContents(),
|
||||
file_system_id,
|
||||
file_system_path);
|
||||
file_systems.push_back(file_system);
|
||||
}
|
||||
|
||||
base::ListValue file_system_value;
|
||||
for (size_t i = 0; i < file_systems.size(); ++i)
|
||||
file_system_value.Append(CreateFileSystemValue(file_systems[i]));
|
||||
web_contents_->CallClientFunction("DevToolsAPI.fileSystemsLoaded",
|
||||
&file_system_value, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsAddFileSystem(
|
||||
const base::FilePath& file_system_path) {
|
||||
base::FilePath path = file_system_path;
|
||||
@@ -286,39 +449,32 @@ void CommonWebContentsDelegate::DevToolsAddFileSystem(
|
||||
base::FilePath default_path;
|
||||
std::vector<base::FilePath> paths;
|
||||
int flag = file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
|
||||
if (!file_dialog::ShowOpenDialog(owner_window(), "", default_path,
|
||||
if (!file_dialog::ShowOpenDialog(owner_window(), "", "", default_path,
|
||||
filters, flag, &paths))
|
||||
return;
|
||||
|
||||
path = paths[0];
|
||||
}
|
||||
|
||||
std::string registered_name;
|
||||
std::string file_system_id = RegisterFileSystem(GetDevToolsWebContents(),
|
||||
path,
|
||||
®istered_name);
|
||||
|
||||
WorkspaceMap::iterator it = saved_paths_.find(file_system_id);
|
||||
if (it != saved_paths_.end())
|
||||
path);
|
||||
if (IsDevToolsFileSystemAdded(GetDevToolsWebContents(), path.AsUTF8Unsafe()))
|
||||
return;
|
||||
|
||||
saved_paths_[file_system_id] = path;
|
||||
|
||||
FileSystem file_system = CreateFileSystemStruct(GetDevToolsWebContents(),
|
||||
file_system_id,
|
||||
registered_name,
|
||||
path.AsUTF8Unsafe());
|
||||
file_system_id,
|
||||
path.AsUTF8Unsafe());
|
||||
scoped_ptr<base::DictionaryValue> file_system_value(
|
||||
CreateFileSystemValue(file_system));
|
||||
|
||||
scoped_ptr<base::StringValue> error_string_value(
|
||||
new base::StringValue(std::string()));
|
||||
scoped_ptr<base::DictionaryValue> file_system_value;
|
||||
if (!file_system.file_system_path.empty())
|
||||
file_system_value.reset(CreateFileSystemValue(file_system));
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.fileSystemAdded",
|
||||
error_string_value.get(),
|
||||
file_system_value.get(),
|
||||
nullptr);
|
||||
auto pref_service = GetPrefService(GetDevToolsWebContents());
|
||||
DictionaryPrefUpdate update(pref_service, prefs::kDevToolsFileSystemPaths);
|
||||
update.Get()->SetWithoutPathExpansion(
|
||||
path.AsUTF8Unsafe(), base::Value::CreateNullValue());
|
||||
|
||||
web_contents_->CallClientFunction("DevToolsAPI.fileSystemAdded",
|
||||
file_system_value.get(),
|
||||
nullptr, nullptr);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsRemoveFileSystem(
|
||||
@@ -326,21 +482,73 @@ void CommonWebContentsDelegate::DevToolsRemoveFileSystem(
|
||||
if (!web_contents_)
|
||||
return;
|
||||
|
||||
std::string path = file_system_path.AsUTF8Unsafe();
|
||||
storage::IsolatedContext::GetInstance()->
|
||||
RevokeFileSystemByPath(file_system_path);
|
||||
|
||||
for (auto it = saved_paths_.begin(); it != saved_paths_.end(); ++it)
|
||||
if (it->second == file_system_path) {
|
||||
saved_paths_.erase(it);
|
||||
break;
|
||||
}
|
||||
auto pref_service = GetPrefService(GetDevToolsWebContents());
|
||||
DictionaryPrefUpdate update(pref_service, prefs::kDevToolsFileSystemPaths);
|
||||
update.Get()->RemoveWithoutPathExpansion(path, nullptr);
|
||||
|
||||
base::StringValue file_system_path_value(file_system_path.AsUTF8Unsafe());
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.fileSystemRemoved",
|
||||
&file_system_path_value,
|
||||
nullptr,
|
||||
nullptr);
|
||||
base::StringValue file_system_path_value(path);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.fileSystemRemoved",
|
||||
&file_system_path_value,
|
||||
nullptr, nullptr);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsIndexPath(
|
||||
int request_id,
|
||||
const std::string& file_system_path) {
|
||||
if (!IsDevToolsFileSystemAdded(GetDevToolsWebContents(), file_system_path)) {
|
||||
OnDevToolsIndexingDone(request_id, file_system_path);
|
||||
return;
|
||||
}
|
||||
if (devtools_indexing_jobs_.count(request_id) != 0)
|
||||
return;
|
||||
devtools_indexing_jobs_[request_id] =
|
||||
scoped_refptr<DevToolsFileSystemIndexer::FileSystemIndexingJob>(
|
||||
devtools_file_system_indexer_->IndexPath(
|
||||
file_system_path,
|
||||
base::Bind(
|
||||
&CommonWebContentsDelegate::OnDevToolsIndexingWorkCalculated,
|
||||
base::Unretained(this),
|
||||
request_id,
|
||||
file_system_path),
|
||||
base::Bind(&CommonWebContentsDelegate::OnDevToolsIndexingWorked,
|
||||
base::Unretained(this),
|
||||
request_id,
|
||||
file_system_path),
|
||||
base::Bind(&CommonWebContentsDelegate::OnDevToolsIndexingDone,
|
||||
base::Unretained(this),
|
||||
request_id,
|
||||
file_system_path)));
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsStopIndexing(int request_id) {
|
||||
auto it = devtools_indexing_jobs_.find(request_id);
|
||||
if (it == devtools_indexing_jobs_.end())
|
||||
return;
|
||||
it->second->Stop();
|
||||
devtools_indexing_jobs_.erase(it);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsSearchInPath(
|
||||
int request_id,
|
||||
const std::string& file_system_path,
|
||||
const std::string& query) {
|
||||
if (!IsDevToolsFileSystemAdded(GetDevToolsWebContents(), file_system_path)) {
|
||||
OnDevToolsSearchCompleted(request_id,
|
||||
file_system_path,
|
||||
std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
devtools_file_system_indexer_->SearchInPath(
|
||||
file_system_path,
|
||||
query,
|
||||
base::Bind(&CommonWebContentsDelegate::OnDevToolsSearchCompleted,
|
||||
base::Unretained(this),
|
||||
request_id,
|
||||
file_system_path));
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::OnDevToolsSaveToFile(
|
||||
@@ -359,22 +567,60 @@ void CommonWebContentsDelegate::OnDevToolsAppendToFile(
|
||||
"DevToolsAPI.appendedToURL", &url_value, nullptr, nullptr);
|
||||
}
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
gfx::ImageSkia CommonWebContentsDelegate::GetDevToolsWindowIcon() {
|
||||
if (!owner_window())
|
||||
return gfx::ImageSkia();
|
||||
return static_cast<views::WidgetDelegate*>(static_cast<NativeWindowViews*>(
|
||||
owner_window()))->GetWindowAppIcon();
|
||||
void CommonWebContentsDelegate::OnDevToolsIndexingWorkCalculated(
|
||||
int request_id,
|
||||
const std::string& file_system_path,
|
||||
int total_work) {
|
||||
base::FundamentalValue request_id_value(request_id);
|
||||
base::StringValue file_system_path_value(file_system_path);
|
||||
base::FundamentalValue total_work_value(total_work);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.indexingTotalWorkCalculated",
|
||||
&request_id_value,
|
||||
&file_system_path_value,
|
||||
&total_work_value);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_X11)
|
||||
void CommonWebContentsDelegate::GetDevToolsWindowWMClass(
|
||||
std::string* name, std::string* class_name) {
|
||||
*class_name = Browser::Get()->GetName();
|
||||
*name = base::ToLowerASCII(*class_name);
|
||||
void CommonWebContentsDelegate::OnDevToolsIndexingWorked(
|
||||
int request_id,
|
||||
const std::string& file_system_path,
|
||||
int worked) {
|
||||
base::FundamentalValue request_id_value(request_id);
|
||||
base::StringValue file_system_path_value(file_system_path);
|
||||
base::FundamentalValue worked_value(worked);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.indexingWorked",
|
||||
&request_id_value,
|
||||
&file_system_path_value,
|
||||
&worked_value);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::OnDevToolsIndexingDone(
|
||||
int request_id,
|
||||
const std::string& file_system_path) {
|
||||
devtools_indexing_jobs_.erase(request_id);
|
||||
base::FundamentalValue request_id_value(request_id);
|
||||
base::StringValue file_system_path_value(file_system_path);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.indexingDone",
|
||||
&request_id_value,
|
||||
&file_system_path_value,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::OnDevToolsSearchCompleted(
|
||||
int request_id,
|
||||
const std::string& file_system_path,
|
||||
const std::vector<std::string>& file_paths) {
|
||||
base::ListValue file_paths_value;
|
||||
for (std::vector<std::string>::const_iterator it(file_paths.begin());
|
||||
it != file_paths.end(); ++it) {
|
||||
file_paths_value.AppendString(*it);
|
||||
}
|
||||
base::FundamentalValue request_id_value(request_id);
|
||||
base::StringValue file_system_path_value(file_system_path);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.searchCompleted",
|
||||
&request_id_value,
|
||||
&file_system_path_value,
|
||||
&file_paths_value);
|
||||
}
|
||||
#endif
|
||||
|
||||
void CommonWebContentsDelegate::SetHtmlApiFullscreen(bool enter_fullscreen) {
|
||||
// Window is already in fullscreen mode, save the state.
|
||||
|
||||
@@ -12,10 +12,14 @@
|
||||
#include "brightray/browser/inspectable_web_contents_impl.h"
|
||||
#include "brightray/browser/inspectable_web_contents_delegate.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view_delegate.h"
|
||||
#include "brightray/browser/devtools_file_system_indexer.h"
|
||||
#include "content/public/browser/web_contents_delegate.h"
|
||||
|
||||
using brightray::DevToolsFileSystemIndexer;
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserContext;
|
||||
class AtomJavaScriptDialogManager;
|
||||
class NativeWindow;
|
||||
class WebDialogHelper;
|
||||
@@ -30,7 +34,8 @@ class CommonWebContentsDelegate
|
||||
|
||||
// Creates a InspectableWebContents object and takes onwership of
|
||||
// |web_contents|.
|
||||
void InitWithWebContents(content::WebContents* web_contents);
|
||||
void InitWithWebContents(content::WebContents* web_contents,
|
||||
AtomBrowserContext* browser_context);
|
||||
|
||||
// Set the window as owner window.
|
||||
void SetOwnerWindow(NativeWindow* owner_window);
|
||||
@@ -76,6 +81,12 @@ class CommonWebContentsDelegate
|
||||
void ExitFullscreenModeForTab(content::WebContents* source) override;
|
||||
bool IsFullscreenForTabOrPending(
|
||||
const content::WebContents* source) const override;
|
||||
content::SecurityStyle GetSecurityStyle(
|
||||
content::WebContents* web_contents,
|
||||
content::SecurityStyleExplanations* explanations) override;
|
||||
void HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
|
||||
// brightray::InspectableWebContentsDelegate:
|
||||
void DevToolsSaveToFile(const std::string& url,
|
||||
@@ -83,9 +94,16 @@ class CommonWebContentsDelegate
|
||||
bool save_as) override;
|
||||
void DevToolsAppendToFile(const std::string& url,
|
||||
const std::string& content) override;
|
||||
void DevToolsRequestFileSystems() override;
|
||||
void DevToolsAddFileSystem(const base::FilePath& path) override;
|
||||
void DevToolsRemoveFileSystem(
|
||||
const base::FilePath& file_system_path) override;
|
||||
void DevToolsIndexPath(int request_id,
|
||||
const std::string& file_system_path) override;
|
||||
void DevToolsStopIndexing(int request_id) override;
|
||||
void DevToolsSearchInPath(int request_id,
|
||||
const std::string& file_system_path,
|
||||
const std::string& query) override;
|
||||
|
||||
// brightray::InspectableWebContentsViewDelegate:
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
@@ -103,6 +121,19 @@ class CommonWebContentsDelegate
|
||||
// Callback for when DevToolsAppendToFile has completed.
|
||||
void OnDevToolsAppendToFile(const std::string& url);
|
||||
|
||||
//
|
||||
void OnDevToolsIndexingWorkCalculated(int request_id,
|
||||
const std::string& file_system_path,
|
||||
int total_work);
|
||||
void OnDevToolsIndexingWorked(int request_id,
|
||||
const std::string& file_system_path,
|
||||
int worked);
|
||||
void OnDevToolsIndexingDone(int request_id,
|
||||
const std::string& file_system_path);
|
||||
void OnDevToolsSearchCompleted(int request_id,
|
||||
const std::string& file_system_path,
|
||||
const std::vector<std::string>& file_paths);
|
||||
|
||||
// Set fullscreen mode triggered by html api.
|
||||
void SetHtmlApiFullscreen(bool enter_fullscreen);
|
||||
|
||||
@@ -117,6 +148,10 @@ class CommonWebContentsDelegate
|
||||
|
||||
scoped_ptr<WebDialogHelper> web_dialog_helper_;
|
||||
scoped_ptr<AtomJavaScriptDialogManager> dialog_manager_;
|
||||
scoped_refptr<DevToolsFileSystemIndexer> devtools_file_system_indexer_;
|
||||
|
||||
// Make sure BrowserContext is alwasys destroyed after WebContents.
|
||||
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||
|
||||
// The stored InspectableWebContents object.
|
||||
// Notice that web_contents_ must be placed after dialog_manager_, so we can
|
||||
@@ -128,10 +163,12 @@ class CommonWebContentsDelegate
|
||||
typedef std::map<std::string, base::FilePath> PathsMap;
|
||||
PathsMap saved_files_;
|
||||
|
||||
// Maps file system id to file path, used by the file system requests
|
||||
// sent from devtools.
|
||||
typedef std::map<std::string, base::FilePath> WorkspaceMap;
|
||||
WorkspaceMap saved_paths_;
|
||||
// Map id to index job, used for file system indexing requests from devtools.
|
||||
typedef std::map<
|
||||
int,
|
||||
scoped_refptr<DevToolsFileSystemIndexer::FileSystemIndexingJob>>
|
||||
DevToolsIndexingJobsMap;
|
||||
DevToolsIndexingJobsMap devtools_indexing_jobs_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CommonWebContentsDelegate);
|
||||
};
|
||||
|
||||
39
atom/browser/common_web_contents_delegate_mac.mm
Normal file
39
atom/browser/common_web_contents_delegate_mac.mm
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "content/public/browser/native_web_keyboard_event.h"
|
||||
#include "ui/events/keycodes/keyboard_codes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
void CommonWebContentsDelegate::HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
if (event.skip_in_browser ||
|
||||
event.type == content::NativeWebKeyboardEvent::Char)
|
||||
return;
|
||||
|
||||
// Escape exits tabbed fullscreen mode.
|
||||
if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen())
|
||||
ExitFullscreenModeForTab(source);
|
||||
|
||||
BOOL handled = [[NSApp mainMenu] performKeyEquivalent:event.os_event];
|
||||
if (!handled && event.os_event.window) {
|
||||
// Handle the cmd+~ shortcut.
|
||||
if ((event.os_event.modifierFlags & NSCommandKeyMask) /* cmd */ &&
|
||||
(event.os_event.keyCode == 50 /* ~ */)) {
|
||||
if (event.os_event.modifierFlags & NSShiftKeyMask) {
|
||||
[NSApp sendAction:@selector(_cycleWindowsReversed:) to:nil from:nil];
|
||||
} else {
|
||||
[NSApp sendAction:@selector(_cycleWindows:) to:nil from:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
45
atom/browser/common_web_contents_delegate_views.cc
Normal file
45
atom/browser/common_web_contents_delegate_views.cc
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "content/public/browser/native_web_keyboard_event.h"
|
||||
#include "ui/events/keycodes/keyboard_codes.h"
|
||||
|
||||
#if defined(USE_X11)
|
||||
#include "atom/browser/browser.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
void CommonWebContentsDelegate::HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
// Escape exits tabbed fullscreen mode.
|
||||
if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen())
|
||||
ExitFullscreenModeForTab(source);
|
||||
|
||||
// Let the NativeWindow handle other parts.
|
||||
if (owner_window())
|
||||
owner_window()->HandleKeyboardEvent(source, event);
|
||||
}
|
||||
|
||||
gfx::ImageSkia CommonWebContentsDelegate::GetDevToolsWindowIcon() {
|
||||
if (!owner_window())
|
||||
return gfx::ImageSkia();
|
||||
return static_cast<views::WidgetDelegate*>(static_cast<NativeWindowViews*>(
|
||||
owner_window()))->GetWindowAppIcon();
|
||||
}
|
||||
|
||||
#if defined(USE_X11)
|
||||
void CommonWebContentsDelegate::GetDevToolsWindowWMClass(
|
||||
std::string* name, std::string* class_name) {
|
||||
*class_name = Browser::Get()->GetName();
|
||||
*name = base::ToLowerASCII(*class_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace atom
|
||||
@@ -3,11 +3,13 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "base/mac/scoped_sending_event.h"
|
||||
#import "base/mac/scoped_nsobject.h"
|
||||
|
||||
@interface AtomApplication : NSApplication<CrAppProtocol,
|
||||
CrAppControlProtocol> {
|
||||
@private
|
||||
BOOL handlingSendEvent_;
|
||||
base::scoped_nsobject<NSUserActivity> currentActivity_;
|
||||
}
|
||||
|
||||
+ (AtomApplication*)sharedApplication;
|
||||
@@ -18,4 +20,7 @@
|
||||
// CrAppControlProtocol:
|
||||
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent;
|
||||
|
||||
- (NSUserActivity*)getCurrentActivity;
|
||||
- (void)setCurrentActivity:(NSString*)type withUserInfo:(NSDictionary*)userInfo;
|
||||
|
||||
@end
|
||||
|
||||
@@ -28,6 +28,18 @@
|
||||
handlingSendEvent_ = handlingSendEvent;
|
||||
}
|
||||
|
||||
- (void)setCurrentActivity:(NSString*)type
|
||||
withUserInfo:(NSDictionary*)userInfo {
|
||||
currentActivity_ = base::scoped_nsobject<NSUserActivity>(
|
||||
[[NSUserActivity alloc] initWithActivityType:type]);
|
||||
[currentActivity_ setUserInfo:userInfo];
|
||||
[currentActivity_ becomeCurrent];
|
||||
}
|
||||
|
||||
- (NSUserActivity*)getCurrentActivity {
|
||||
return currentActivity_.get();
|
||||
}
|
||||
|
||||
- (void)awakeFromNib {
|
||||
[[NSAppleEventManager sharedAppleEventManager]
|
||||
setEventHandler:self
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
|
||||
#import "atom/browser/mac/atom_application.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/values.h"
|
||||
|
||||
@implementation AtomApplicationDelegate
|
||||
|
||||
@@ -24,9 +26,6 @@
|
||||
// Don't add the "Enter Full Screen" menu item automatically.
|
||||
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSFullScreenMenuItemEverywhere"];
|
||||
|
||||
// Add observer to monitor the system's Dark Mode theme.
|
||||
[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(platformThemeChanged:) name:@"AppleInterfaceThemeChangedNotification" object:nil];
|
||||
|
||||
atom::Browser::Get()->WillFinishLaunching();
|
||||
}
|
||||
|
||||
@@ -62,8 +61,17 @@
|
||||
return flag;
|
||||
}
|
||||
|
||||
- (void)platformThemeChanged:(NSNotification *)notify {
|
||||
atom::Browser::Get()->PlatformThemeChanged();
|
||||
- (BOOL)application:(NSApplication*)sender
|
||||
continueUserActivity:(NSUserActivity*)userActivity
|
||||
restorationHandler:(void (^)(NSArray*restorableObjects))restorationHandler {
|
||||
std::string activity_type(base::SysNSStringToUTF8(userActivity.activityType));
|
||||
scoped_ptr<base::DictionaryValue> user_info =
|
||||
atom::NSDictionaryToDictionaryValue(userActivity.userInfo);
|
||||
if (!user_info)
|
||||
return NO;
|
||||
|
||||
atom::Browser* browser = atom::Browser::Get();
|
||||
return browser->ContinueUserActivity(activity_type, *user_info) ? YES : NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
26
atom/browser/mac/dict_util.h
Normal file
26
atom/browser/mac/dict_util.h
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_MAC_DICT_UTIL_H_
|
||||
#define ATOM_BROWSER_MAC_DICT_UTIL_H_
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
|
||||
namespace base {
|
||||
class Value;
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
NSDictionary* DictionaryValueToNSDictionary(const base::DictionaryValue& value);
|
||||
|
||||
scoped_ptr<base::DictionaryValue> NSDictionaryToDictionaryValue(
|
||||
NSDictionary* dict);
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_MAC_DICT_UTIL_H_
|
||||
118
atom/browser/mac/dict_util.mm
Normal file
118
atom/browser/mac/dict_util.mm
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
|
||||
#include "base/json/json_writer.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/values.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
scoped_ptr<base::ListValue> NSArrayToListValue(NSArray* arr) {
|
||||
if (!arr)
|
||||
return nullptr;
|
||||
|
||||
scoped_ptr<base::ListValue> result(new base::ListValue);
|
||||
for (id value in arr) {
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
result->AppendString(base::SysNSStringToUTF8(value));
|
||||
} else if ([value isKindOfClass:[NSNumber class]]) {
|
||||
const char* objc_type = [value objCType];
|
||||
if (strcmp(objc_type, @encode(BOOL)) == 0 ||
|
||||
strcmp(objc_type, @encode(char)) == 0)
|
||||
result->AppendBoolean([value boolValue]);
|
||||
else if (strcmp(objc_type, @encode(double)) == 0 ||
|
||||
strcmp(objc_type, @encode(float)) == 0)
|
||||
result->AppendDouble([value doubleValue]);
|
||||
else
|
||||
result->AppendInteger([value intValue]);
|
||||
} else if ([value isKindOfClass:[NSArray class]]) {
|
||||
scoped_ptr<base::ListValue> sub_arr = NSArrayToListValue(value);
|
||||
if (sub_arr)
|
||||
result->Append(std::move(sub_arr));
|
||||
else
|
||||
result->Append(base::Value::CreateNullValue());
|
||||
} else if ([value isKindOfClass:[NSDictionary class]]) {
|
||||
scoped_ptr<base::DictionaryValue> sub_dict =
|
||||
NSDictionaryToDictionaryValue(value);
|
||||
if (sub_dict)
|
||||
result->Append(std::move(sub_dict));
|
||||
else
|
||||
result->Append(base::Value::CreateNullValue());
|
||||
} else {
|
||||
result->AppendString(base::SysNSStringToUTF8([value description]));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NSDictionary* DictionaryValueToNSDictionary(const base::DictionaryValue& value) {
|
||||
std::string json;
|
||||
if (!base::JSONWriter::Write(value, &json))
|
||||
return nil;
|
||||
NSData* jsonData = [NSData dataWithBytes:json.c_str() length:json.length()];
|
||||
id obj = [NSJSONSerialization JSONObjectWithData:jsonData
|
||||
options:0
|
||||
error:nil];
|
||||
if (![obj isKindOfClass:[NSDictionary class]])
|
||||
return nil;
|
||||
return obj;
|
||||
}
|
||||
|
||||
scoped_ptr<base::DictionaryValue> NSDictionaryToDictionaryValue(
|
||||
NSDictionary* dict) {
|
||||
if (!dict)
|
||||
return nullptr;
|
||||
|
||||
scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue);
|
||||
for (id key in dict) {
|
||||
std::string str_key = base::SysNSStringToUTF8(
|
||||
[key isKindOfClass:[NSString class]] ? key : [key description]);
|
||||
|
||||
id value = [dict objectForKey:key];
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
result->SetStringWithoutPathExpansion(
|
||||
str_key, base::SysNSStringToUTF8(value));
|
||||
} else if ([value isKindOfClass:[NSNumber class]]) {
|
||||
const char* objc_type = [value objCType];
|
||||
if (strcmp(objc_type, @encode(BOOL)) == 0 ||
|
||||
strcmp(objc_type, @encode(char)) == 0)
|
||||
result->SetBooleanWithoutPathExpansion(str_key, [value boolValue]);
|
||||
else if (strcmp(objc_type, @encode(double)) == 0 ||
|
||||
strcmp(objc_type, @encode(float)) == 0)
|
||||
result->SetDoubleWithoutPathExpansion(str_key, [value doubleValue]);
|
||||
else
|
||||
result->SetIntegerWithoutPathExpansion(str_key, [value intValue]);
|
||||
} else if ([value isKindOfClass:[NSArray class]]) {
|
||||
scoped_ptr<base::ListValue> sub_arr = NSArrayToListValue(value);
|
||||
if (sub_arr)
|
||||
result->SetWithoutPathExpansion(str_key, std::move(sub_arr));
|
||||
else
|
||||
result->SetWithoutPathExpansion(str_key,
|
||||
base::Value::CreateNullValue());
|
||||
} else if ([value isKindOfClass:[NSDictionary class]]) {
|
||||
scoped_ptr<base::DictionaryValue> sub_dict =
|
||||
NSDictionaryToDictionaryValue(value);
|
||||
if (sub_dict)
|
||||
result->SetWithoutPathExpansion(str_key, std::move(sub_dict));
|
||||
else
|
||||
result->SetWithoutPathExpansion(str_key,
|
||||
base::Value::CreateNullValue());
|
||||
} else {
|
||||
result->SetStringWithoutPathExpansion(
|
||||
str_key,
|
||||
base::SysNSStringToUTF8([value description]));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -12,12 +12,11 @@
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/json/json_writer.h"
|
||||
#include "base/prefs/pref_service.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
@@ -49,11 +48,12 @@ NativeWindow::NativeWindow(
|
||||
const mate::Dictionary& options)
|
||||
: content::WebContentsObserver(inspectable_web_contents->GetWebContents()),
|
||||
has_frame_(true),
|
||||
force_using_draggable_region_(false),
|
||||
transparent_(false),
|
||||
enable_larger_than_screen_(false),
|
||||
is_closed_(false),
|
||||
has_dialog_attached_(false),
|
||||
sheet_offset_x_(0.0),
|
||||
sheet_offset_y_(0.0),
|
||||
aspect_ratio_(0.0),
|
||||
inspectable_web_contents_(inspectable_web_contents),
|
||||
weak_factory_(this) {
|
||||
@@ -65,9 +65,6 @@ NativeWindow::NativeWindow(
|
||||
// mode.
|
||||
ui::GpuSwitchingManager::SetTransparent(transparent_);
|
||||
|
||||
// Read icon before window is created.
|
||||
options.Get(options::kIcon, &icon_);
|
||||
|
||||
WindowList::AddWindow(this);
|
||||
}
|
||||
|
||||
@@ -162,6 +159,9 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
|
||||
std::string color;
|
||||
if (options.Get(options::kBackgroundColor, &color)) {
|
||||
SetBackgroundColor(color);
|
||||
} else if (!transparent()) {
|
||||
// For normal window, use white as default background.
|
||||
SetBackgroundColor("#FFFF");
|
||||
}
|
||||
std::string title("Electron");
|
||||
options.Get(options::kTitle, &title);
|
||||
@@ -251,6 +251,19 @@ gfx::Size NativeWindow::GetMaximumSize() {
|
||||
return GetSizeConstraints().GetMaximumSize();
|
||||
}
|
||||
|
||||
void NativeWindow::SetSheetOffset(const double offsetX, const double offsetY) {
|
||||
sheet_offset_x_ = offsetX;
|
||||
sheet_offset_y_ = offsetY;
|
||||
}
|
||||
|
||||
double NativeWindow::GetSheetOffsetX() {
|
||||
return sheet_offset_x_;
|
||||
}
|
||||
|
||||
double NativeWindow::GetSheetOffsetY() {
|
||||
return sheet_offset_y_;
|
||||
}
|
||||
|
||||
void NativeWindow::SetRepresentedFilename(const std::string& filename) {
|
||||
}
|
||||
|
||||
@@ -306,9 +319,9 @@ void NativeWindow::CapturePage(const gfx::Rect& rect,
|
||||
// current system, increase the requested bitmap size to capture it all.
|
||||
gfx::Size bitmap_size = view_size;
|
||||
const gfx::NativeView native_view = view->GetNativeView();
|
||||
gfx::Screen* const screen = gfx::Screen::GetScreenFor(native_view);
|
||||
const float scale =
|
||||
screen->GetDisplayNearestWindow(native_view).device_scale_factor();
|
||||
gfx::Screen::GetScreen()->GetDisplayNearestWindow(native_view)
|
||||
.device_scale_factor();
|
||||
if (scale > 1.0f)
|
||||
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
|
||||
|
||||
@@ -400,7 +413,7 @@ void NativeWindow::RendererUnresponsive(content::WebContents* source) {
|
||||
// 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
|
||||
// explicity started a close timeout counter. This is on purpose because we
|
||||
// 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);
|
||||
@@ -480,6 +493,11 @@ void NativeWindow::NotifyWindowScrollTouchEnd() {
|
||||
OnWindowScrollTouchEnd());
|
||||
}
|
||||
|
||||
void NativeWindow::NotifyWindowSwipe(const std::string& direction) {
|
||||
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
|
||||
OnWindowSwipe(direction));
|
||||
}
|
||||
|
||||
void NativeWindow::NotifyWindowLeaveFullScreen() {
|
||||
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
|
||||
OnWindowLeaveFullScreen());
|
||||
@@ -556,7 +574,7 @@ bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
|
||||
void NativeWindow::UpdateDraggableRegions(
|
||||
const std::vector<DraggableRegion>& regions) {
|
||||
// Draggable region is not supported for non-frameless window.
|
||||
if (has_frame_ && !force_using_draggable_region_)
|
||||
if (has_frame_)
|
||||
return;
|
||||
draggable_region_ = DraggableRegionsToSkRegion(regions);
|
||||
}
|
||||
@@ -589,27 +607,4 @@ void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback,
|
||||
callback.Run(bitmap);
|
||||
}
|
||||
|
||||
SkColor NativeWindow::ParseHexColor(const std::string& name) {
|
||||
auto color = name.substr(1);
|
||||
unsigned length = color.size();
|
||||
SkColor result = (length != 8 ? 0xFF000000 : 0x00000000);
|
||||
unsigned value = 0;
|
||||
if (length != 3 && length != 6 && length != 8)
|
||||
return result;
|
||||
for (unsigned i = 0; i < length; ++i) {
|
||||
if (!base::IsHexDigit(color[i]))
|
||||
return result;
|
||||
value <<= 4;
|
||||
value |= (color[i] < 'A' ? color[i] - '0' : (color[i] - 'A' + 10) & 0xF);
|
||||
}
|
||||
if (length == 6 || length == 8) {
|
||||
result |= value;
|
||||
return result;
|
||||
}
|
||||
result |= (value & 0xF00) << 12 | (value & 0xF00) << 8
|
||||
| (value & 0xF0) << 8 | (value & 0xF0) << 4
|
||||
| (value & 0xF) << 4 | (value & 0xF);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -123,6 +123,9 @@ class NativeWindow : public base::SupportsUserData,
|
||||
virtual gfx::Size GetMinimumSize();
|
||||
virtual void SetMaximumSize(const gfx::Size& size);
|
||||
virtual gfx::Size GetMaximumSize();
|
||||
virtual void SetSheetOffset(const double offsetX, const double offsetY);
|
||||
virtual double GetSheetOffsetX();
|
||||
virtual double GetSheetOffsetY();
|
||||
virtual void SetResizable(bool resizable) = 0;
|
||||
virtual bool IsResizable() = 0;
|
||||
virtual void SetMovable(bool movable) = 0;
|
||||
@@ -188,7 +191,7 @@ class NativeWindow : public base::SupportsUserData,
|
||||
// Set the aspect ratio when resizing window.
|
||||
double GetAspectRatio();
|
||||
gfx::Size GetAspectRatioExtraSize();
|
||||
void SetAspectRatio(double aspect_ratio, const gfx::Size& extra_size);
|
||||
virtual void SetAspectRatio(double aspect_ratio, const gfx::Size& extra_size);
|
||||
|
||||
base::WeakPtr<NativeWindow> GetWeakPtr() {
|
||||
return weak_factory_.GetWeakPtr();
|
||||
@@ -221,6 +224,7 @@ class NativeWindow : public base::SupportsUserData,
|
||||
void NotifyWindowMoved();
|
||||
void NotifyWindowScrollTouchBegin();
|
||||
void NotifyWindowScrollTouchEnd();
|
||||
void NotifyWindowSwipe(const std::string& direction);
|
||||
void NotifyWindowEnterFullScreen();
|
||||
void NotifyWindowLeaveFullScreen();
|
||||
void NotifyWindowEnterHtmlFullScreen();
|
||||
@@ -243,17 +247,11 @@ class NativeWindow : public base::SupportsUserData,
|
||||
}
|
||||
|
||||
bool has_frame() const { return has_frame_; }
|
||||
void set_has_frame(bool has_frame) { has_frame_ = has_frame; }
|
||||
|
||||
bool transparent() const { return transparent_; }
|
||||
SkRegion* draggable_region() const { return draggable_region_.get(); }
|
||||
bool enable_larger_than_screen() const { return enable_larger_than_screen_; }
|
||||
gfx::ImageSkia icon() const { return icon_; }
|
||||
|
||||
bool force_using_draggable_region() const {
|
||||
return force_using_draggable_region_;
|
||||
}
|
||||
void set_force_using_draggable_region(bool force) {
|
||||
force_using_draggable_region_ = true;
|
||||
}
|
||||
|
||||
void set_has_dialog_attached(bool has_dialog_attached) {
|
||||
has_dialog_attached_ = has_dialog_attached;
|
||||
@@ -281,9 +279,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||
void BeforeUnloadDialogCancelled() override;
|
||||
bool OnMessageReceived(const IPC::Message& message) override;
|
||||
|
||||
// Parse hex color like "#FFF" or "#EFEFEF"
|
||||
SkColor ParseHexColor(const std::string& name);
|
||||
|
||||
private:
|
||||
// Schedule a notification unresponsive event.
|
||||
void ScheduleUnresponsiveEvent(int ms);
|
||||
@@ -299,9 +294,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||
// Whether window has standard frame.
|
||||
bool has_frame_;
|
||||
|
||||
// Force the window to be aware of draggable regions.
|
||||
bool force_using_draggable_region_;
|
||||
|
||||
// Whether window is transparent.
|
||||
bool transparent_;
|
||||
|
||||
@@ -315,9 +307,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||
// Whether window can be resized larger than screen.
|
||||
bool enable_larger_than_screen_;
|
||||
|
||||
// Window icon.
|
||||
gfx::ImageSkia icon_;
|
||||
|
||||
// The windows has been closed.
|
||||
bool is_closed_;
|
||||
|
||||
@@ -328,6 +317,11 @@ class NativeWindow : public base::SupportsUserData,
|
||||
// it should be cancelled when we can prove that the window is responsive.
|
||||
base::CancelableClosure window_unresposive_closure_;
|
||||
|
||||
// Used to display sheets at the appropriate horizontal and vertical offsets
|
||||
// on OS X.
|
||||
double sheet_offset_x_;
|
||||
double sheet_offset_y_;
|
||||
|
||||
// Used to maintain the aspect ratio of a view which is inside of the
|
||||
// content view.
|
||||
double aspect_ratio_;
|
||||
|
||||
@@ -49,6 +49,8 @@ class NativeWindowMac : public NativeWindow {
|
||||
void SetResizable(bool resizable) override;
|
||||
bool IsResizable() override;
|
||||
void SetMovable(bool movable) override;
|
||||
void SetAspectRatio(double aspect_ratio, const gfx::Size& extra_size)
|
||||
override;
|
||||
bool IsMovable() override;
|
||||
void SetMinimizable(bool minimizable) override;
|
||||
bool IsMinimizable() override;
|
||||
@@ -91,16 +93,15 @@ class NativeWindowMac : public NativeWindow {
|
||||
UpdateDraggableRegionViews(draggable_regions_);
|
||||
}
|
||||
|
||||
// Set the attribute of NSWindow while work around a bug of zoom button.
|
||||
void SetStyleMask(bool on, NSUInteger flag);
|
||||
void SetCollectionBehavior(bool on, NSUInteger flag);
|
||||
|
||||
bool should_hide_native_toolbar_in_fullscreen() const {
|
||||
return should_hide_native_toolbar_in_fullscreen_;
|
||||
}
|
||||
|
||||
protected:
|
||||
// NativeWindow:
|
||||
void HandleKeyboardEvent(
|
||||
content::WebContents*,
|
||||
const content::NativeWebKeyboardEvent&) override;
|
||||
|
||||
// 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(
|
||||
@@ -120,10 +121,6 @@ class NativeWindowMac : public NativeWindow {
|
||||
// whehter we can drag.
|
||||
void UpdateDraggableRegionViews(const std::vector<DraggableRegion>& regions);
|
||||
|
||||
// Set the attribute of NSWindow while work around a bug of zo0m button.
|
||||
void SetStyleMask(bool on, NSUInteger flag);
|
||||
void SetCollectionBehavior(bool on, NSUInteger flag);
|
||||
|
||||
base::scoped_nsobject<AtomNSWindow> window_;
|
||||
base::scoped_nsobject<AtomNSWindowDelegate> window_delegate_;
|
||||
|
||||
@@ -142,6 +139,10 @@ class NativeWindowMac : public NativeWindow {
|
||||
// The presentation options before entering kiosk mode.
|
||||
NSApplicationPresentationOptions kiosk_options_;
|
||||
|
||||
// Force showing the buttons for frameless window.
|
||||
bool force_show_buttons_;
|
||||
|
||||
// Whether to hide the native toolbar under fullscreen mode.
|
||||
bool should_hide_native_toolbar_in_fullscreen_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NativeWindowMac);
|
||||
|
||||
@@ -6,18 +6,20 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/common/color_util.h"
|
||||
#include "atom/common/draggable_region.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/mac/mac_util.h"
|
||||
#include "base/mac/scoped_cftyperef.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_accessibility_state.h"
|
||||
#include "content/public/browser/native_web_keyboard_event.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "skia/ext/skia_utils_mac.h"
|
||||
#include "ui/gfx/skia_util.h"
|
||||
|
||||
namespace {
|
||||
@@ -139,22 +141,9 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
newSize.width =
|
||||
roundf((frameSize.height - extraHeightPlusFrame) * aspectRatio +
|
||||
extraWidthPlusFrame);
|
||||
|
||||
// If the new width is less than the frame size use it as the primary
|
||||
// constraint. This ensures that the value returned by this method will
|
||||
// never be larger than the users requested window size.
|
||||
if (newSize.width <= frameSize.width) {
|
||||
newSize.height =
|
||||
roundf((newSize.width - extraWidthPlusFrame) / aspectRatio +
|
||||
extraHeightPlusFrame);
|
||||
} else {
|
||||
newSize.height =
|
||||
roundf((frameSize.width - extraWidthPlusFrame) / aspectRatio +
|
||||
extraHeightPlusFrame);
|
||||
newSize.width =
|
||||
roundf((newSize.height - extraHeightPlusFrame) * aspectRatio +
|
||||
extraWidthPlusFrame);
|
||||
}
|
||||
newSize.height =
|
||||
roundf((newSize.width - extraWidthPlusFrame) / aspectRatio +
|
||||
extraHeightPlusFrame);
|
||||
}
|
||||
|
||||
return newSize;
|
||||
@@ -211,10 +200,22 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
[[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"]);
|
||||
[toolbar setShowsBaselineSeparator:NO];
|
||||
[window setToolbar:toolbar];
|
||||
|
||||
// Set window style to hide the toolbar, otherwise the toolbar will show in
|
||||
// fullscreen mode.
|
||||
shell_->SetStyleMask(true, NSFullSizeContentViewWindowMask);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)windowWillExitFullScreen:(NSNotification*)notification {
|
||||
// Turn off the style for toolbar.
|
||||
if (shell_->should_hide_native_toolbar_in_fullscreen())
|
||||
shell_->SetStyleMask(false, NSFullSizeContentViewWindowMask);
|
||||
}
|
||||
|
||||
- (void)windowDidExitFullScreen:(NSNotification*)notification {
|
||||
// For certain versions of OS X the fullscreen button will automatically show
|
||||
// after exiting fullscreen mode.
|
||||
if (!shell_->has_frame()) {
|
||||
NSWindow* window = shell_->GetNativeWindow();
|
||||
[[window standardWindowButton:NSWindowFullScreenButton] setHidden:YES];
|
||||
@@ -240,6 +241,15 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSRect)window:(NSWindow*)window
|
||||
willPositionSheet:(NSWindow*)sheet usingRect:(NSRect)rect {
|
||||
NSView* view = window.contentView;
|
||||
|
||||
rect.origin.x = shell_->GetSheetOffsetX();
|
||||
rect.origin.y = view.frame.size.height - shell_->GetSheetOffsetY();
|
||||
return rect;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface AtomNSWindow : NSWindow {
|
||||
@@ -267,6 +277,18 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
|
||||
// NSWindow overrides.
|
||||
|
||||
- (void)swipeWithEvent:(NSEvent *)event {
|
||||
if (event.deltaY == 1.0) {
|
||||
shell_->NotifyWindowSwipe("up");
|
||||
} else if (event.deltaX == -1.0) {
|
||||
shell_->NotifyWindowSwipe("right");
|
||||
} else if (event.deltaY == -1.0) {
|
||||
shell_->NotifyWindowSwipe("down");
|
||||
} else if (event.deltaX == 1.0) {
|
||||
shell_->NotifyWindowSwipe("left");
|
||||
}
|
||||
}
|
||||
|
||||
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen {
|
||||
// Resizing is disabled.
|
||||
if (ScopedDisableResize::IsResizeDisabled())
|
||||
@@ -369,6 +391,7 @@ NativeWindowMac::NativeWindowMac(
|
||||
: NativeWindow(web_contents, options),
|
||||
is_kiosk_(false),
|
||||
attention_request_id_(0),
|
||||
force_show_buttons_(false),
|
||||
should_hide_native_toolbar_in_fullscreen_(false) {
|
||||
int width = 800, height = 600;
|
||||
options.Get(options::kWidth, &width);
|
||||
@@ -416,22 +439,17 @@ NativeWindowMac::NativeWindowMac(
|
||||
if (closable) {
|
||||
styleMask |= NSClosableWindowMask;
|
||||
}
|
||||
if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) {
|
||||
// The window without titlebar is treated the same with frameless window.
|
||||
set_has_frame(false);
|
||||
force_show_buttons_ = true;
|
||||
}
|
||||
if (!useStandardWindow || transparent() || !has_frame()) {
|
||||
styleMask |= NSTexturedBackgroundWindowMask;
|
||||
}
|
||||
if (resizable) {
|
||||
styleMask |= NSResizableWindowMask;
|
||||
}
|
||||
if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) {
|
||||
styleMask |= NSFullSizeContentViewWindowMask;
|
||||
styleMask |= NSUnifiedTitleAndToolbarWindowMask;
|
||||
}
|
||||
// We capture this because we need to access the option later when
|
||||
// entering/exiting fullscreen and since the options dict is only passed to
|
||||
// the constructor but not stored, let’s store this option this way.
|
||||
if (titleBarStyle == "hidden-inset") {
|
||||
should_hide_native_toolbar_in_fullscreen_ = true;
|
||||
}
|
||||
|
||||
window_.reset([[AtomNSWindow alloc]
|
||||
initWithContentRect:cocoa_bounds
|
||||
@@ -468,7 +486,7 @@ NativeWindowMac::NativeWindowMac(
|
||||
[window_ setReleasedWhenClosed:NO];
|
||||
|
||||
// Hide the title bar.
|
||||
if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) {
|
||||
if (titleBarStyle == "hidden-inset") {
|
||||
[window_ setTitlebarAppearsTransparent:YES];
|
||||
[window_ setTitleVisibility:NSWindowTitleHidden];
|
||||
if (titleBarStyle == "hidden-inset") {
|
||||
@@ -476,9 +494,8 @@ NativeWindowMac::NativeWindowMac(
|
||||
[[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"]);
|
||||
[toolbar setShowsBaselineSeparator:NO];
|
||||
[window_ setToolbar:toolbar];
|
||||
should_hide_native_toolbar_in_fullscreen_ = true;
|
||||
}
|
||||
// We should be aware of draggable regions when using hidden titlebar.
|
||||
set_force_using_draggable_region(true);
|
||||
}
|
||||
|
||||
// On OS X the initial window size doesn't include window frame.
|
||||
@@ -580,10 +597,16 @@ bool NativeWindowMac::IsVisible() {
|
||||
}
|
||||
|
||||
void NativeWindowMac::Maximize() {
|
||||
if (IsMaximized())
|
||||
return;
|
||||
|
||||
[window_ zoom:nil];
|
||||
}
|
||||
|
||||
void NativeWindowMac::Unmaximize() {
|
||||
if (!IsMaximized())
|
||||
return;
|
||||
|
||||
[window_ zoom:nil];
|
||||
}
|
||||
|
||||
@@ -685,6 +708,20 @@ bool NativeWindowMac::IsResizable() {
|
||||
return [window_ styleMask] & NSResizableWindowMask;
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetAspectRatio(double aspect_ratio,
|
||||
const gfx::Size& extra_size) {
|
||||
NativeWindow::SetAspectRatio(aspect_ratio, extra_size);
|
||||
|
||||
// We can't just pass the aspect ratio to Cocoa, since our API receives
|
||||
// it as a float, and Cocoa expects an NSRect with explicit width & height
|
||||
// arguments. Instead we derive those args ourselves from the given aspect
|
||||
// ratio.
|
||||
double width = roundf([window_ frame].size.height * aspect_ratio);
|
||||
double height = roundf(width / aspect_ratio);
|
||||
|
||||
[window_ setAspectRatio:NSMakeSize(width, height)];
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetMovable(bool movable) {
|
||||
[window_ setMovable:movable];
|
||||
}
|
||||
@@ -792,12 +829,14 @@ bool NativeWindowMac::IsKiosk() {
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetBackgroundColor(const std::string& color_name) {
|
||||
SkColor background_color = NativeWindow::ParseHexColor(color_name);
|
||||
NSColor *color = [NSColor colorWithCalibratedRed:SkColorGetR(background_color)
|
||||
green:SkColorGetG(background_color)
|
||||
blue:SkColorGetB(background_color)
|
||||
alpha:SkColorGetA(background_color)/255.0f];
|
||||
[window_ setBackgroundColor:color];
|
||||
SkColor color = ParseHexColor(color_name);
|
||||
base::ScopedCFTypeRef<CGColorRef> cgcolor =
|
||||
skia::CGColorCreateFromSkColor(color);
|
||||
[[[window_ contentView] layer] setBackgroundColor:cgcolor];
|
||||
|
||||
const auto view = web_contents()->GetRenderWidgetHostView();
|
||||
if (view)
|
||||
view->SetBackgroundColor(color);
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetHasShadow(bool has_shadow) {
|
||||
@@ -898,27 +937,6 @@ bool NativeWindowMac::IsVisibleOnAllWorkspaces() {
|
||||
return collectionBehavior & NSWindowCollectionBehaviorCanJoinAllSpaces;
|
||||
}
|
||||
|
||||
void NativeWindowMac::HandleKeyboardEvent(
|
||||
content::WebContents*,
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
if (event.skip_in_browser ||
|
||||
event.type == content::NativeWebKeyboardEvent::Char)
|
||||
return;
|
||||
|
||||
BOOL handled = [[NSApp mainMenu] performKeyEquivalent:event.os_event];
|
||||
if (!handled && event.os_event.window) {
|
||||
// Handle the cmd+~ shortcut.
|
||||
if ((event.os_event.modifierFlags & NSCommandKeyMask) /* cmd */ &&
|
||||
(event.os_event.keyCode == 50 /* ~ */)) {
|
||||
if (event.os_event.modifierFlags & NSShiftKeyMask) {
|
||||
[NSApp sendAction:@selector(_cycleWindowsReversed:) to:nil from:nil];
|
||||
} else {
|
||||
[NSApp sendAction:@selector(_cycleWindows:) to:nil from:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<gfx::Rect> NativeWindowMac::CalculateNonDraggableRegions(
|
||||
const std::vector<DraggableRegion>& regions, int width, int height) {
|
||||
std::vector<gfx::Rect> result;
|
||||
@@ -983,6 +1001,10 @@ void NativeWindowMac::InstallView() {
|
||||
[view setFrame:[content_view_ bounds]];
|
||||
[content_view_ addSubview:view];
|
||||
|
||||
if (force_show_buttons_)
|
||||
return;
|
||||
|
||||
// Hide the window buttons.
|
||||
[[window_ standardWindowButton:NSWindowZoomButton] setHidden:YES];
|
||||
[[window_ standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
|
||||
[[window_ standardWindowButton:NSWindowCloseButton] setHidden:YES];
|
||||
@@ -1001,7 +1023,7 @@ void NativeWindowMac::UninstallView() {
|
||||
|
||||
void NativeWindowMac::UpdateDraggableRegionViews(
|
||||
const std::vector<DraggableRegion>& regions) {
|
||||
if (has_frame() && !force_using_draggable_region())
|
||||
if (has_frame())
|
||||
return;
|
||||
|
||||
// All ControlRegionViews should be added as children of the WebContentsView,
|
||||
|
||||
@@ -58,6 +58,7 @@ class NativeWindowObserver {
|
||||
virtual void OnWindowMoved() {}
|
||||
virtual void OnWindowScrollTouchBegin() {}
|
||||
virtual void OnWindowScrollTouchEnd() {}
|
||||
virtual void OnWindowSwipe(const std::string& direction) {}
|
||||
virtual void OnWindowEnterFullScreen() {}
|
||||
virtual void OnWindowLeaveFullScreen() {}
|
||||
virtual void OnWindowEnterHtmlFullScreen() {}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user