mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
717 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29052b0498 | ||
|
|
153c751fd7 | ||
|
|
8e2faba8f7 | ||
|
|
c1d6d68783 | ||
|
|
866cff8b9c | ||
|
|
784d2633a9 | ||
|
|
eec93665b7 | ||
|
|
79397abbeb | ||
|
|
80dfa4bf09 | ||
|
|
962134c612 | ||
|
|
65c823407d | ||
|
|
eca98b85fc | ||
|
|
026a1f9a4f | ||
|
|
fd3b8ad623 | ||
|
|
bee1af3264 | ||
|
|
f2472274b7 | ||
|
|
1b464c82e1 | ||
|
|
611f87d17f | ||
|
|
08c13cf446 | ||
|
|
44c562ebd9 | ||
|
|
dd8ef33e42 | ||
|
|
1392873cbc | ||
|
|
47d7d49d19 | ||
|
|
b9ddb0c268 | ||
|
|
9a20b33d97 | ||
|
|
d427ae1030 | ||
|
|
ed1f9989b0 | ||
|
|
2c06afad6a | ||
|
|
52e34ca0f9 | ||
|
|
c63121c2f6 | ||
|
|
69388e185c | ||
|
|
2affc44000 | ||
|
|
afbceab2ab | ||
|
|
e9b8e66f2b | ||
|
|
8900d67c67 | ||
|
|
ba5f8aa096 | ||
|
|
0232b77ce3 | ||
|
|
b7ae9d3337 | ||
|
|
e4803e6f97 | ||
|
|
f581730516 | ||
|
|
ef64a211a2 | ||
|
|
82e2da1d9a | ||
|
|
e2cd0578f3 | ||
|
|
70c7abbbfe | ||
|
|
f0d2bc87e8 | ||
|
|
cc5a4f1dfe | ||
|
|
9db4af4cf3 | ||
|
|
0c2d769b8a | ||
|
|
6058c7e14d | ||
|
|
250575719d | ||
|
|
6892f0d2d4 | ||
|
|
87546bd4f8 | ||
|
|
1ee69540b0 | ||
|
|
151f8e7f8a | ||
|
|
a3460e8e19 | ||
|
|
bcdd0952f8 | ||
|
|
9e67dc385b | ||
|
|
45e3d4ea6b | ||
|
|
25e5c38556 | ||
|
|
47d7f2c050 | ||
|
|
9ca022c98a | ||
|
|
c5bfac1969 | ||
|
|
3af4a40860 | ||
|
|
e432abfb42 | ||
|
|
74e8c8d6a5 | ||
|
|
341341bf28 | ||
|
|
9a0dc3bfd7 | ||
|
|
c2eddb20f7 | ||
|
|
1022179a1f | ||
|
|
d129aa9085 | ||
|
|
0e8ab0688d | ||
|
|
0dd14ad204 | ||
|
|
7cc965b178 | ||
|
|
57aecbc415 | ||
|
|
9c69416e32 | ||
|
|
c21d7b537a | ||
|
|
78dac21b84 | ||
|
|
b4eca40d07 | ||
|
|
456154a6a2 | ||
|
|
247a0a8ae2 | ||
|
|
ab54fedc9a | ||
|
|
961ee5a4d9 | ||
|
|
ebe66daa56 | ||
|
|
e3517b701e | ||
|
|
ea1e4160ea | ||
|
|
37f355724a | ||
|
|
217311ef21 | ||
|
|
24f573eceb | ||
|
|
855c1ead00 | ||
|
|
9a9f912f24 | ||
|
|
5995451366 | ||
|
|
099da729c7 | ||
|
|
69a6e80ab8 | ||
|
|
68099a71b0 | ||
|
|
b4d3c8f248 | ||
|
|
3b826ed1a5 | ||
|
|
ee12dc3d17 | ||
|
|
83dfef2e66 | ||
|
|
5b8e94ca28 | ||
|
|
7ef347e69e | ||
|
|
d05def1e3e | ||
|
|
f312a4e6ec | ||
|
|
66816ea2e0 | ||
|
|
92c3ee8e16 | ||
|
|
62e6332366 | ||
|
|
7dcc537359 | ||
|
|
202d2eeb8a | ||
|
|
14740eeb8a | ||
|
|
1d800d5e26 | ||
|
|
9e70d35afa | ||
|
|
728a5db3b4 | ||
|
|
feedd0c43d | ||
|
|
3f0f1a2ce9 | ||
|
|
2a9a66144c | ||
|
|
0f89573719 | ||
|
|
c27c7b05fe | ||
|
|
ceee820d4a | ||
|
|
266c22903b | ||
|
|
c5e706bc30 | ||
|
|
19a2c24927 | ||
|
|
5fff06d2c2 | ||
|
|
bb6d7d1498 | ||
|
|
abba83397b | ||
|
|
1254331c5e | ||
|
|
e12e119381 | ||
|
|
ad776887da | ||
|
|
42a3771f98 | ||
|
|
c1373d7480 | ||
|
|
9f9436d6dc | ||
|
|
78542ab54c | ||
|
|
9987082de5 | ||
|
|
e2959ed3fc | ||
|
|
2a7f874373 | ||
|
|
fe214e0806 | ||
|
|
5cacf79bc5 | ||
|
|
94e24abb99 | ||
|
|
b925ac0056 | ||
|
|
099278855c | ||
|
|
9bf0a8647e | ||
|
|
e76a7f7b7d | ||
|
|
5d52ff76ab | ||
|
|
e8ffd24e4e | ||
|
|
52f1431bde | ||
|
|
fbb8e61958 | ||
|
|
9ac87e844a | ||
|
|
8f56387bd9 | ||
|
|
860c46b3c1 | ||
|
|
0f23d6faa9 | ||
|
|
fdc19f2d3a | ||
|
|
d3caea91b0 | ||
|
|
05d2e431de | ||
|
|
83ae9f8d71 | ||
|
|
996a3c2a35 | ||
|
|
78934dceb9 | ||
|
|
0321a77a94 | ||
|
|
3a5160f799 | ||
|
|
f2439cefd0 | ||
|
|
bfaa50a79e | ||
|
|
852500e5fa | ||
|
|
37e6e6fab7 | ||
|
|
bb439c5f1c | ||
|
|
3d5437e0a4 | ||
|
|
d072e61282 | ||
|
|
ce6a7c7d08 | ||
|
|
edd807d227 | ||
|
|
c5913c3149 | ||
|
|
2ca5a33d28 | ||
|
|
c649c4cf4f | ||
|
|
eac2e7cc61 | ||
|
|
8b2942c279 | ||
|
|
1d1f911b09 | ||
|
|
fb5beb9af5 | ||
|
|
f9d7e7ce55 | ||
|
|
c2c09daa23 | ||
|
|
ce0167756e | ||
|
|
cb1dc6b2e2 | ||
|
|
020214ff95 | ||
|
|
ca49ddc95d | ||
|
|
c571776da6 | ||
|
|
28db51ad83 | ||
|
|
f08bd721f3 | ||
|
|
0e9415a256 | ||
|
|
0a5b234e3d | ||
|
|
e41cf8111a | ||
|
|
f63a4a05b7 | ||
|
|
60ec1ca3f7 | ||
|
|
ba457681b2 | ||
|
|
b807685453 | ||
|
|
960d325a58 | ||
|
|
5cca947f4d | ||
|
|
737e22b003 | ||
|
|
d37aa8bed9 | ||
|
|
961e06ba6c | ||
|
|
3af1d907d8 | ||
|
|
319acc1e8a | ||
|
|
b611154f43 | ||
|
|
8774e7cf8d | ||
|
|
916671d4d2 | ||
|
|
ed179ecf03 | ||
|
|
d1e8e71e3f | ||
|
|
f98147ea01 | ||
|
|
f6a0e5ad31 | ||
|
|
6c7acd8aa5 | ||
|
|
08e245e3dc | ||
|
|
1f01a4535a | ||
|
|
d582ddf790 | ||
|
|
682433028c | ||
|
|
20c8637810 | ||
|
|
0af1308ad7 | ||
|
|
d234f10177 | ||
|
|
90a7d4a906 | ||
|
|
05611f5e60 | ||
|
|
751af25f37 | ||
|
|
844cea8f21 | ||
|
|
6515a445a0 | ||
|
|
765cfb1094 | ||
|
|
828d911ed1 | ||
|
|
5d1f7ed029 | ||
|
|
bd1f6e2edf | ||
|
|
91c4ed26fc | ||
|
|
f0bd28ca8d | ||
|
|
89ff62b1b5 | ||
|
|
a23ffd7a1b | ||
|
|
13b917dd95 | ||
|
|
dd8fb9739d | ||
|
|
5e3b8d51e4 | ||
|
|
91c7043a1b | ||
|
|
429723c8a9 | ||
|
|
ae2b004db7 | ||
|
|
09169ed402 | ||
|
|
3465095c49 | ||
|
|
312a79165b | ||
|
|
829c396efe | ||
|
|
c4ee8c1b1f | ||
|
|
d70706f876 | ||
|
|
acf4372cf7 | ||
|
|
863199348f | ||
|
|
c10c74b23a | ||
|
|
0e950e6d26 | ||
|
|
8a296f82a0 | ||
|
|
ee783a13ad | ||
|
|
818892d474 | ||
|
|
5b0ea5bd46 | ||
|
|
2505ebb9a6 | ||
|
|
47649ffd17 | ||
|
|
4ff5ce4d6d | ||
|
|
4ce840d8e6 | ||
|
|
fbe1200dc7 | ||
|
|
e4f74bb87e | ||
|
|
9f536f4783 | ||
|
|
d56b34de3b | ||
|
|
07c55f321f | ||
|
|
84410a7e1c | ||
|
|
323abef362 | ||
|
|
75f49477ca | ||
|
|
441cc3e57e | ||
|
|
96cc5485cb | ||
|
|
526b2083c4 | ||
|
|
4013b652ff | ||
|
|
28abc8defe | ||
|
|
1ad77da9d6 | ||
|
|
df5a3d4e68 | ||
|
|
7c41f0e0e3 | ||
|
|
8c989c4630 | ||
|
|
053cd3dad0 | ||
|
|
1b165559f5 | ||
|
|
726910df39 | ||
|
|
8a3268b70c | ||
|
|
7b47b70c9e | ||
|
|
9047f81835 | ||
|
|
7c7a7b96de | ||
|
|
d332f2ab1c | ||
|
|
9236adfbf5 | ||
|
|
56e6b28370 | ||
|
|
f7c0418bd8 | ||
|
|
4804d6b79b | ||
|
|
b5f7c433c6 | ||
|
|
647a0c4e2b | ||
|
|
88fc4e9d05 | ||
|
|
72d7fb7b8a | ||
|
|
c763cbe298 | ||
|
|
f7108af36b | ||
|
|
d097082baf | ||
|
|
bbb5aef5d2 | ||
|
|
5b49655d1f | ||
|
|
c969052f12 | ||
|
|
6a02586176 | ||
|
|
cb91d4487b | ||
|
|
323ab92299 | ||
|
|
db3cd1af36 | ||
|
|
a957ea1ed9 | ||
|
|
aa98720356 | ||
|
|
2c59f4567e | ||
|
|
d223faa9f4 | ||
|
|
58595a23fe | ||
|
|
95ef73ebc1 | ||
|
|
9c69877421 | ||
|
|
21a7c459d8 | ||
|
|
aeeada546f | ||
|
|
8cd8495df7 | ||
|
|
28fb0d0e92 | ||
|
|
3a154ab8ea | ||
|
|
ac4df34ecd | ||
|
|
eae7c840b7 | ||
|
|
62d15953ff | ||
|
|
386325915b | ||
|
|
72e8660245 | ||
|
|
b8cc2e1649 | ||
|
|
c7372f8f93 | ||
|
|
917b33dbe7 | ||
|
|
0f89f67a84 | ||
|
|
bf9e6ba11e | ||
|
|
f13a02e4fa | ||
|
|
ef038257d1 | ||
|
|
f22837523f | ||
|
|
2ac40cc28e | ||
|
|
16eafdb0ce | ||
|
|
2384c9f493 | ||
|
|
4efff08007 | ||
|
|
974b5005bc | ||
|
|
51ba37440d | ||
|
|
862c3187f5 | ||
|
|
569e87035a | ||
|
|
f40a3f72d7 | ||
|
|
4eac6b31b1 | ||
|
|
131531219e | ||
|
|
d05255179a | ||
|
|
54dad72d92 | ||
|
|
9847747736 | ||
|
|
5d8a31c140 | ||
|
|
3881ad1c4b | ||
|
|
9df89cf79b | ||
|
|
b86267aa3b | ||
|
|
5fd310c75f | ||
|
|
0c5fe03999 | ||
|
|
079796de26 | ||
|
|
e90961ac4f | ||
|
|
c9b53a6e8b | ||
|
|
142f380376 | ||
|
|
f69bafd48a | ||
|
|
fa24e15d8b | ||
|
|
e355532d27 | ||
|
|
b4d9b92ecb | ||
|
|
dacd921a04 | ||
|
|
9b17241f6f | ||
|
|
3042f604cc | ||
|
|
2a85bd3360 | ||
|
|
f1fad96b56 | ||
|
|
a84f4dc3e6 | ||
|
|
00493f64b7 | ||
|
|
2e3a5f5a3e | ||
|
|
d1c5d07451 | ||
|
|
edbebf84b9 | ||
|
|
b29a8c94b9 | ||
|
|
65ece4b1ca | ||
|
|
f399f50e9e | ||
|
|
e6f54f447c | ||
|
|
adb11225d2 | ||
|
|
c973357752 | ||
|
|
b71ec748ad | ||
|
|
70fe169b0f | ||
|
|
8976708e67 | ||
|
|
da82eaefa7 | ||
|
|
3dd6425592 | ||
|
|
37240c2235 | ||
|
|
d528704bd6 | ||
|
|
fd94ff97e7 | ||
|
|
9b36abc816 | ||
|
|
8e5c1a505e | ||
|
|
2effe6eff5 | ||
|
|
8555aea40f | ||
|
|
30ec7fdeed | ||
|
|
0e3e1be85c | ||
|
|
df9ea104c2 | ||
|
|
88b05cff3e | ||
|
|
fae2c7bc7a | ||
|
|
96130dd4c2 | ||
|
|
79e593aca6 | ||
|
|
aeafc46ded | ||
|
|
f89d28a63e | ||
|
|
d74ef5c078 | ||
|
|
85c84a0eb0 | ||
|
|
a3f62da615 | ||
|
|
95fe4beda8 | ||
|
|
d5c964c68c | ||
|
|
07adbc8e8a | ||
|
|
90e3f726e4 | ||
|
|
83ef23ff8d | ||
|
|
e36d455d51 | ||
|
|
4a6134f3f7 | ||
|
|
6182e4ce81 | ||
|
|
79d4d52172 | ||
|
|
e3ce1b50ec | ||
|
|
e9a5d05b27 | ||
|
|
61f07307cb | ||
|
|
6bfe06ec4e | ||
|
|
7b5a1b06ba | ||
|
|
d52ef50b01 | ||
|
|
93a3a946f3 | ||
|
|
afc1fff792 | ||
|
|
70e74d05e0 | ||
|
|
f9d797d1ea | ||
|
|
e14fd62f46 | ||
|
|
ca876e424b | ||
|
|
230f2760e7 | ||
|
|
f01e84a418 | ||
|
|
05c6300329 | ||
|
|
bcb78ebc00 | ||
|
|
310954713f | ||
|
|
acb2c099f6 | ||
|
|
63cc2ec369 | ||
|
|
04d3eed60e | ||
|
|
f7840e7379 | ||
|
|
15e0248d82 | ||
|
|
9411508d3e | ||
|
|
f5659cd9a9 | ||
|
|
803b3c8d5b | ||
|
|
bac3d2e372 | ||
|
|
759b6a1534 | ||
|
|
de66888051 | ||
|
|
d020a7dc86 | ||
|
|
938d68eb36 | ||
|
|
b61c2e6ff7 | ||
|
|
658a9872fb | ||
|
|
a160891a27 | ||
|
|
acbd7d7541 | ||
|
|
38d6ff79c8 | ||
|
|
bca88c1fb9 | ||
|
|
73f4aa1113 | ||
|
|
444f461269 | ||
|
|
2d410ede48 | ||
|
|
ed9579a2f7 | ||
|
|
567d8e7434 | ||
|
|
d092c6acc9 | ||
|
|
99c496471b | ||
|
|
e5094fff3e | ||
|
|
fe25f3e747 | ||
|
|
b6859cab91 | ||
|
|
26d922d18d | ||
|
|
15f00db1bf | ||
|
|
4a7a09aae1 | ||
|
|
f759471e01 | ||
|
|
4bc54ac5e3 | ||
|
|
5886398f22 | ||
|
|
7491d5cfb5 | ||
|
|
b6f1729acd | ||
|
|
5d4c29a1e3 | ||
|
|
a2eedcc027 | ||
|
|
63417bc975 | ||
|
|
4a4b829cfc | ||
|
|
50fab0733b | ||
|
|
b02f89e63b | ||
|
|
cdd51fa96d | ||
|
|
c38f2fcf75 | ||
|
|
7491ae4000 | ||
|
|
4d5495a0a0 | ||
|
|
717aba9631 | ||
|
|
8288a22458 | ||
|
|
88dd1480cc | ||
|
|
c46579b1ac | ||
|
|
1b3363c811 | ||
|
|
daa65a138b | ||
|
|
d3b23a2032 | ||
|
|
05b22b9372 | ||
|
|
ff2d9759d5 | ||
|
|
90b997ef08 | ||
|
|
27fa5d880a | ||
|
|
285a4789b3 | ||
|
|
da7161d5a7 | ||
|
|
db3bc28937 | ||
|
|
a0e2af6fac | ||
|
|
1ad979f9bd | ||
|
|
f7a9b02c63 | ||
|
|
7a0db35d91 | ||
|
|
c928894627 | ||
|
|
a7a399dcd8 | ||
|
|
14e2bbe4c7 | ||
|
|
370cb5b5e1 | ||
|
|
78261973fb | ||
|
|
be36a17dbf | ||
|
|
fb8ca33d5d | ||
|
|
2c4a24d26b | ||
|
|
4005e65e28 | ||
|
|
86327fb4bb | ||
|
|
5a46147e9b | ||
|
|
bb8bb3dbea | ||
|
|
d09b09b744 | ||
|
|
bc7c7da799 | ||
|
|
9f8479e9d8 | ||
|
|
e3535d664b | ||
|
|
b3c7e2bf33 | ||
|
|
489090fcf8 | ||
|
|
0afefe13f6 | ||
|
|
7f15d63552 | ||
|
|
09ee24514e | ||
|
|
d9c7401d0b | ||
|
|
de3e16ce60 | ||
|
|
72e0da069c | ||
|
|
0d9e0a38c0 | ||
|
|
810af2f95d | ||
|
|
0aefa98e5a | ||
|
|
0e50b00fdf | ||
|
|
60b14d03e9 | ||
|
|
49d25d0069 | ||
|
|
82e6058607 | ||
|
|
c46ed897dd | ||
|
|
c7d9352972 | ||
|
|
cd2f924db8 | ||
|
|
b958982d99 | ||
|
|
a3fc25110e | ||
|
|
5ae6bd2ef4 | ||
|
|
7ac643d5f8 | ||
|
|
5e7a30deea | ||
|
|
72078f7b02 | ||
|
|
b5478eaef7 | ||
|
|
1ae4be7571 | ||
|
|
32523ae352 | ||
|
|
c0ee8f4e60 | ||
|
|
edd6032ed0 | ||
|
|
f05fc3c0ea | ||
|
|
f0825bf7ef | ||
|
|
d9fdfb711f | ||
|
|
94f64c755d | ||
|
|
4871ea715c | ||
|
|
115bb31ab4 | ||
|
|
2725068a0c | ||
|
|
5e5caf2e86 | ||
|
|
22e9c2f4eb | ||
|
|
c371c713a9 | ||
|
|
776077c8de | ||
|
|
16b9f8995d | ||
|
|
18fd126c64 | ||
|
|
7bdbe45c91 | ||
|
|
fb99e72484 | ||
|
|
0e94ccb72b | ||
|
|
aeb24b784d | ||
|
|
125444df15 | ||
|
|
facd0fbc08 | ||
|
|
3dba56c335 | ||
|
|
89527ec232 | ||
|
|
904f3c2564 | ||
|
|
d2b3d6d129 | ||
|
|
909779babf | ||
|
|
f5c25d6277 | ||
|
|
d90b598125 | ||
|
|
55d5660ddb | ||
|
|
11a49bba35 | ||
|
|
6aec8b092c | ||
|
|
f52c4af605 | ||
|
|
b61baacfe1 | ||
|
|
79311af8eb | ||
|
|
7a6ef0ec6e | ||
|
|
4270eba438 | ||
|
|
d14b59c754 | ||
|
|
95c4847d60 | ||
|
|
74d389b2b0 | ||
|
|
eb344f3f04 | ||
|
|
b47076231c | ||
|
|
51335934c1 | ||
|
|
d6842751bb | ||
|
|
96c15f19e3 | ||
|
|
9e51ff2b4b | ||
|
|
48faf74f7f | ||
|
|
df7a9b80b1 | ||
|
|
3afc9c4ebe | ||
|
|
7b57a945f8 | ||
|
|
b62e3554dc | ||
|
|
a9f5667899 | ||
|
|
644af0800c | ||
|
|
699dafc5db | ||
|
|
d152b25fb6 | ||
|
|
af8049941e | ||
|
|
d9a4a41293 | ||
|
|
ddea2fced4 | ||
|
|
34d49441b1 | ||
|
|
b9b25180f8 | ||
|
|
b9d838975d | ||
|
|
5ff97c686a | ||
|
|
460adfa1bc | ||
|
|
ff9846da48 | ||
|
|
9de9d2ecc1 | ||
|
|
799748cc5d | ||
|
|
ab1f39589a | ||
|
|
9419a2ec2c | ||
|
|
c58ca76cac | ||
|
|
36bbf5d51f | ||
|
|
8012792457 | ||
|
|
2820fa8fd4 | ||
|
|
bd95be23f3 | ||
|
|
6ec184a2ce | ||
|
|
cb903a09c0 | ||
|
|
4e8db2c3be | ||
|
|
692816f9d2 | ||
|
|
0cd1195eea | ||
|
|
71fdb91f5c | ||
|
|
6d20d37101 | ||
|
|
df12f181a4 | ||
|
|
be5f1b09f4 | ||
|
|
b5b6e30c8b | ||
|
|
ccd17f060d | ||
|
|
c71efc8ca5 | ||
|
|
8278ee533d | ||
|
|
b6cfa6f967 | ||
|
|
1896deb10e | ||
|
|
095b2e6047 | ||
|
|
e682dc7544 | ||
|
|
4392f1d77c | ||
|
|
288572f08e | ||
|
|
6cbbce544f | ||
|
|
8127bbc992 | ||
|
|
9fd46ac4db | ||
|
|
1e13159157 | ||
|
|
215ca78c7f | ||
|
|
0404cc850b | ||
|
|
fb5260eb30 | ||
|
|
28b3678159 | ||
|
|
965471d9f8 | ||
|
|
d7c67d795b | ||
|
|
841407a619 | ||
|
|
1759a71814 | ||
|
|
d61bec0fb8 | ||
|
|
442db4c5ba | ||
|
|
922fce1892 | ||
|
|
38b27bbd66 | ||
|
|
6bc59cf2d7 | ||
|
|
957de56343 | ||
|
|
1a2b5834ed | ||
|
|
59b43a6571 | ||
|
|
1a55cd3efe | ||
|
|
c8122392de | ||
|
|
8b7d2b5ce3 | ||
|
|
d9c6cf7b75 | ||
|
|
e1318ffb34 | ||
|
|
7756bb6762 | ||
|
|
d9cf9a7cbc | ||
|
|
87faae1b13 | ||
|
|
051548aa69 | ||
|
|
9dd714f056 | ||
|
|
fe4d86925b | ||
|
|
617892400f | ||
|
|
73ab6d409b | ||
|
|
55715bec23 | ||
|
|
115526424a | ||
|
|
aebc1d0650 | ||
|
|
c7dc901607 | ||
|
|
b1ae60a639 | ||
|
|
7e7b6df72b | ||
|
|
05f0b5a8a4 | ||
|
|
2978beaeb7 | ||
|
|
6f61832a34 | ||
|
|
63c1fdd22a | ||
|
|
3966441d21 | ||
|
|
579f253340 | ||
|
|
821005e6b4 | ||
|
|
871571c65e | ||
|
|
326af3cbe3 | ||
|
|
4c3fd38774 | ||
|
|
74be1d5b25 | ||
|
|
cab466f999 | ||
|
|
4cb3e2ecb5 | ||
|
|
cb22b88e6a | ||
|
|
5bdc077b48 | ||
|
|
927c3f34c3 | ||
|
|
c916baa939 | ||
|
|
3a97439fe9 | ||
|
|
c6d5a92d34 | ||
|
|
2d802d6f1e | ||
|
|
fa59ea3bc5 | ||
|
|
804cf5e8ba | ||
|
|
fc0153f0bc | ||
|
|
c823e31904 | ||
|
|
2ef66cb660 | ||
|
|
f607e81fac | ||
|
|
e06778178a | ||
|
|
f6327de7f7 | ||
|
|
8e40947938 | ||
|
|
898db4d6bd | ||
|
|
6fea6cf58a | ||
|
|
428c5b6d01 | ||
|
|
3f37439da3 | ||
|
|
db46c1b925 | ||
|
|
c3cd438d34 | ||
|
|
ccf4ed907a | ||
|
|
b70e7c6a4c | ||
|
|
4d302956d3 | ||
|
|
c8723238f8 | ||
|
|
60fb406c61 | ||
|
|
bb49515145 | ||
|
|
87e0c812e9 | ||
|
|
ea3e84e7ff | ||
|
|
239b97cde1 | ||
|
|
c22ffd863b | ||
|
|
857acd2574 | ||
|
|
3b1ee994e2 | ||
|
|
e675407552 | ||
|
|
d19ead1907 | ||
|
|
a9b0111c3e | ||
|
|
279407f7a3 | ||
|
|
a76ea00249 | ||
|
|
8577f2b52f | ||
|
|
526cee7ec3 | ||
|
|
2b9b4c6789 | ||
|
|
de24ed7cea | ||
|
|
c34c123b33 | ||
|
|
4d02fc58fa | ||
|
|
aea1f8aebb | ||
|
|
bb938b02d8 | ||
|
|
8c31c7fb59 | ||
|
|
2365ffe143 | ||
|
|
6c4016af46 | ||
|
|
154ca8575c | ||
|
|
ae5411c37b | ||
|
|
62882fe49e | ||
|
|
a8469fc79d | ||
|
|
7aa60baafb | ||
|
|
99f352228c | ||
|
|
621178f558 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
.DS_Store
|
||||
/.idea/
|
||||
/build/
|
||||
/dist/
|
||||
/external_binaries/
|
||||
|
||||
@@ -10,6 +10,7 @@ os:
|
||||
- osx
|
||||
env:
|
||||
- TARGET_ARCH=x64
|
||||
osx_image: xcode7
|
||||
|
||||
matrix:
|
||||
include:
|
||||
|
||||
40
README-ko.md
40
README-ko.md
@@ -8,18 +8,26 @@
|
||||
|
||||
:zap: *프레임워크 이름이 Atom Shell에서 Electron으로 변경되었습니다* :zap:
|
||||
|
||||
Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여 Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다. 이 프레임워크는 [io.js](http://iojs.org) 와
|
||||
[Chromium](http://www.chromium.org)을 기반으로 만들어 졌으며 [Atom Editor](https://github.com/atom/atom)에 사용되고 있습니다.
|
||||
Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여
|
||||
Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다.
|
||||
[Node.js](https://nodejs.org/)와 [Chromium](http://www.chromium.org)을 기반으로
|
||||
만들어졌으며 [Atom Editor](https://github.com/atom/atom)에 사용되고 있습니다.
|
||||
|
||||
Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서 [@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요.
|
||||
Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서
|
||||
[@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요.
|
||||
|
||||
이 프로젝트는 기여자 규약 1.2를 준수합니다. 이 프로젝트에 참여할 때 코드를 유지해야 합니다. 받아들일 수 없는 행동은 atom@github.com로 보고 하십시오.
|
||||
이 프로젝트는 [기여자 규약 1.2](http://contributor-covenant.org/version/1/2/0/)을
|
||||
준수합니다. 따라서 이 프로젝트의 개발에 참여하려면 이 계약을 지켜야 합니다. 받아들일 수
|
||||
없는 행위를 발견했을 경우 atom@github.com로 보고 하십시오.
|
||||
|
||||
## 다운로드
|
||||
|
||||
Linux, Windows, Mac용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어 있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 받아 볼 수 있습니다.
|
||||
Linux, Windows, OS X 용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어
|
||||
있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 받아 볼
|
||||
수 있습니다.
|
||||
|
||||
또한 [`npm`](https://docs.npmjs.com/)을 통해 미리 빌드된 Electron 바이너리를 받을 수도 있습니다:
|
||||
또한 [`npm`](https://docs.npmjs.com/)을 통해 미리 빌드된 Electron 바이너리를 설치할
|
||||
수도 있습니다:
|
||||
|
||||
```sh
|
||||
# $PATH에 `electron` 커맨드를 등록하고 전역에 설치합니다.
|
||||
@@ -35,8 +43,9 @@ npm install electron-prebuilt --save-dev
|
||||
|
||||
## 참조 문서
|
||||
|
||||
[Docs](https://github.com/atom/electron/tree/master/docs/README.md)에 개발 가이드와 API 레퍼런스가 있습니다.
|
||||
Electron을 빌드 하는 방법과 프로젝트에 기여하는 방법도 문서에 포함되어 있으니 참고하시기 바랍니다.
|
||||
[Docs](https://github.com/atom/electron/tree/master/docs/README.md)에 개발 지침과
|
||||
API 레퍼런스가 있습니다. Electron을 빌드 하는 방법과 프로젝트에 기여하는법 또한 문서에
|
||||
포함되어 있으니 참고하시기 바랍니다.
|
||||
|
||||
## 참조 문서 (번역)
|
||||
|
||||
@@ -47,12 +56,19 @@ Electron을 빌드 하는 방법과 프로젝트에 기여하는 방법도 문
|
||||
- [중국어 간체](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
||||
- [중국어 번체](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
||||
|
||||
## 시작하기
|
||||
|
||||
[`atom/electron-quick-start`](https://github.com/atom/electron-quick-start)
|
||||
저장소를 클론하여 Electron을 간단히 접해볼 수 있습니다.
|
||||
|
||||
## 커뮤니티
|
||||
|
||||
다음 링크를 통해 커뮤니티에 질문을 올리거나 토론을 나누실 수 있습니다:
|
||||
다음 링크를 통해 커뮤니티에 질문을 올리거나 토론을 나눌 수 있습니다:
|
||||
|
||||
- Atom 포럼의 [`electron`](http://discuss.atom.io/category/electron) 카테고리
|
||||
- Freenode 채팅의 `#atom-shell` 채널
|
||||
- Atom 포럼의 [`electron`](http://discuss.atom.io/c/electron) 카테고리
|
||||
- Freenode 채팅의 `#atom-shell` 채널
|
||||
- Slack의 [`Atom`](http://atom-slack.herokuapp.com/) 채널
|
||||
|
||||
[awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트엔 커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 한번 참고해 보시기 바랍니다.
|
||||
[awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트에
|
||||
커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 한번 참고해 보시기
|
||||
바랍니다.
|
||||
|
||||
13
README.md
13
README.md
@@ -7,20 +7,20 @@
|
||||
:zap: *Formerly known as Atom Shell* :zap:
|
||||
|
||||
The Electron framework lets you write cross-platform desktop applications
|
||||
using JavaScript, HTML and CSS. It is based on [io.js](http://iojs.org) and
|
||||
using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and
|
||||
[Chromium](http://www.chromium.org) and is used in the [Atom
|
||||
editor](https://github.com/atom/atom).
|
||||
|
||||
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
|
||||
announcements.
|
||||
|
||||
This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0).
|
||||
This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0/).
|
||||
By participating, you are expected to uphold this code. Please report
|
||||
unacceptable behavior to atom@github.com.
|
||||
|
||||
## Downloads
|
||||
|
||||
Prebuilt binaries and debug symbols of Electron for Linux, Windows and Mac can
|
||||
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.
|
||||
|
||||
You can also use [`npm`](https://docs.npmjs.com/) to install prebuilt electron
|
||||
@@ -53,11 +53,16 @@ contains documents describing how to build and contribute to Electron.
|
||||
- [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)
|
||||
|
||||
## Quick Start
|
||||
|
||||
Clone and run the [`atom/electron-quick-start`](https://github.com/atom/electron-quick-start)
|
||||
repository to see a minimal Electron app in action.
|
||||
|
||||
## Community
|
||||
|
||||
You can ask questions and interact with the community in the following
|
||||
locations:
|
||||
- [`electron`](http://discuss.atom.io/category/electron) category on the Atom
|
||||
- [`electron`](http://discuss.atom.io/c/electron) category on the Atom
|
||||
forums
|
||||
- `#atom-shell` channel on Freenode
|
||||
- [`Atom`](http://atom-slack.herokuapp.com/) channel on Slack
|
||||
|
||||
69
atom.gyp
69
atom.gyp
@@ -4,7 +4,7 @@
|
||||
'product_name%': 'Electron',
|
||||
'company_name%': 'GitHub, Inc',
|
||||
'company_abbr%': 'github',
|
||||
'version%': '0.33.6',
|
||||
'version%': '0.35.1',
|
||||
},
|
||||
'includes': [
|
||||
'filenames.gypi',
|
||||
@@ -64,9 +64,6 @@
|
||||
'files': [
|
||||
'<(PRODUCT_DIR)/<(product_name) Helper.app',
|
||||
'<(PRODUCT_DIR)/<(product_name) Framework.framework',
|
||||
'external_binaries/Squirrel.framework',
|
||||
'external_binaries/ReactiveCocoa.framework',
|
||||
'external_binaries/Mantle.framework',
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -109,7 +106,21 @@
|
||||
'<@(locale_dirs)',
|
||||
],
|
||||
},
|
||||
]
|
||||
],
|
||||
'conditions': [
|
||||
['mas_build==0', {
|
||||
'copies': [
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Frameworks',
|
||||
'files': [
|
||||
'external_binaries/Squirrel.framework',
|
||||
'external_binaries/ReactiveCocoa.framework',
|
||||
'external_binaries/Mantle.framework',
|
||||
],
|
||||
},
|
||||
],
|
||||
}],
|
||||
],
|
||||
}, { # OS=="mac"
|
||||
'dependencies': [
|
||||
'make_locale_paks',
|
||||
@@ -285,12 +296,28 @@
|
||||
'vendor/breakpad/breakpad.gyp:breakpad_sender',
|
||||
],
|
||||
}], # OS=="win"
|
||||
['OS=="mac"', {
|
||||
['OS=="mac" and mas_build==0', {
|
||||
'dependencies': [
|
||||
'vendor/crashpad/client/client.gyp:crashpad_client',
|
||||
'vendor/crashpad/handler/handler.gyp:crashpad_handler',
|
||||
],
|
||||
}], # OS=="mac"
|
||||
'link_settings': {
|
||||
# Do not link with QTKit for mas build.
|
||||
'libraries': [
|
||||
'$(SDKROOT)/System/Library/Frameworks/QTKit.framework',
|
||||
],
|
||||
},
|
||||
}], # OS=="mac" and mas_build==0
|
||||
['OS=="mac" and mas_build==1', {
|
||||
'defines': [
|
||||
'MAS_BUILD',
|
||||
],
|
||||
'sources!': [
|
||||
'atom/browser/auto_updater_mac.mm',
|
||||
'atom/common/crash_reporter/crash_reporter_mac.h',
|
||||
'atom/common/crash_reporter/crash_reporter_mac.mm',
|
||||
],
|
||||
}], # OS=="mac" and mas_build==1
|
||||
['OS=="linux"', {
|
||||
'link_settings': {
|
||||
'ldflags': [
|
||||
@@ -393,9 +420,6 @@
|
||||
'libraries': [
|
||||
'$(SDKROOT)/System/Library/Frameworks/Carbon.framework',
|
||||
'$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework',
|
||||
'external_binaries/Squirrel.framework',
|
||||
'external_binaries/ReactiveCocoa.framework',
|
||||
'external_binaries/Mantle.framework',
|
||||
],
|
||||
},
|
||||
'mac_bundle': 1,
|
||||
@@ -439,12 +463,6 @@
|
||||
'<@(copied_libraries)',
|
||||
],
|
||||
},
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Resources',
|
||||
'files': [
|
||||
'<(PRODUCT_DIR)/crashpad_handler',
|
||||
],
|
||||
},
|
||||
],
|
||||
'postbuilds': [
|
||||
{
|
||||
@@ -476,6 +494,25 @@
|
||||
],
|
||||
},
|
||||
],
|
||||
'conditions': [
|
||||
['mas_build==0', {
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'external_binaries/Squirrel.framework',
|
||||
'external_binaries/ReactiveCocoa.framework',
|
||||
'external_binaries/Mantle.framework',
|
||||
],
|
||||
},
|
||||
'copies': [
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Resources',
|
||||
'files': [
|
||||
'<(PRODUCT_DIR)/crashpad_handler',
|
||||
],
|
||||
},
|
||||
],
|
||||
}],
|
||||
],
|
||||
}, # target framework
|
||||
{
|
||||
'target_name': '<(project_name)_helper',
|
||||
|
||||
@@ -99,7 +99,7 @@ void AtomContentClient::AddAdditionalSchemes(
|
||||
void AtomContentClient::AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto flash_path = command_line->GetSwitchValueNative(
|
||||
auto flash_path = command_line->GetSwitchValuePath(
|
||||
switches::kPpapiFlashPath);
|
||||
if (flash_path.empty())
|
||||
return;
|
||||
@@ -108,7 +108,7 @@ void AtomContentClient::AddPepperPlugins(
|
||||
switches::kPpapiFlashVersion);
|
||||
|
||||
plugins->push_back(
|
||||
CreatePepperFlashInfo(base::FilePath(flash_path), flash_version));
|
||||
CreatePepperFlashInfo(flash_path, flash_version));
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "base/at_exit.h"
|
||||
#include "base/i18n/icu_util.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
||||
#include "brightray/common/mac/main_application_bundle.h"
|
||||
#include "content/public/app/content_main.h"
|
||||
|
||||
@@ -25,6 +26,7 @@ int AtomMain(int argc, const char* argv[]) {
|
||||
|
||||
int AtomInitializeICUandStartNode(int argc, char *argv[]) {
|
||||
base::AtExitManager atexit_manager;
|
||||
base::mac::ScopedNSAutoreleasePool pool;
|
||||
base::mac::SetOverrideFrameworkBundlePath(
|
||||
brightray::MainApplicationBundlePath()
|
||||
.Append("Contents")
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "atom/app/atom_content_client.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
@@ -15,11 +16,21 @@
|
||||
#include "base/debug/stack_trace.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/logging.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsBrowserProcess(base::CommandLine* cmd) {
|
||||
std::string process_type = cmd->GetSwitchValueASCII(switches::kProcessType);
|
||||
return process_type.empty();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomMainDelegate::AtomMainDelegate() {
|
||||
}
|
||||
|
||||
@@ -27,8 +38,14 @@ AtomMainDelegate::~AtomMainDelegate() {
|
||||
}
|
||||
|
||||
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
logging::LoggingSettings settings;
|
||||
#if defined(OS_WIN)
|
||||
// On Windows the terminal returns immediately, so we add a new line to
|
||||
// prevent output in the same line as the prompt.
|
||||
if (IsBrowserProcess(command_line))
|
||||
std::wcout << std::endl;
|
||||
#if defined(DEBUG)
|
||||
// Print logging to debug.log on Windows
|
||||
settings.logging_dest = logging::LOG_TO_ALL;
|
||||
@@ -43,19 +60,27 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
#endif // !defined(OS_WIN)
|
||||
|
||||
// Only enable logging when --enable-logging is specified.
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (!command_line->HasSwitch(switches::kEnableLogging))
|
||||
scoped_ptr<base::Environment> env(base::Environment::Create());
|
||||
if (!command_line->HasSwitch(switches::kEnableLogging) &&
|
||||
!env->HasVar("ELECTRON_ENABLE_LOGGING")) {
|
||||
settings.logging_dest = logging::LOG_NONE;
|
||||
logging::SetMinLogLevel(logging::LOG_NUM_SEVERITIES);
|
||||
}
|
||||
|
||||
logging::InitLogging(settings);
|
||||
|
||||
// Logging with pid and timestamp.
|
||||
logging::SetLogItems(true, false, true, false);
|
||||
|
||||
#if defined(DEBUG) && defined(OS_LINUX)
|
||||
// Enable convient stack printing.
|
||||
base::debug::EnableInProcessStackDumping();
|
||||
bool enable_stack_dumping = env->HasVar("ELECTRON_ENABLE_STACK_DUMPING");
|
||||
#if defined(DEBUG) && defined(OS_LINUX)
|
||||
enable_stack_dumping = true;
|
||||
#endif
|
||||
if (enable_stack_dumping)
|
||||
base::debug::EnableInProcessStackDumping();
|
||||
|
||||
chrome::RegisterPathProvider();
|
||||
|
||||
return brightray::MainDelegate::BasicStartupComplete(exit_code);
|
||||
}
|
||||
@@ -77,16 +102,9 @@ void AtomMainDelegate::PreSandboxStartup() {
|
||||
}
|
||||
|
||||
// Only append arguments for browser process.
|
||||
if (!process_type.empty())
|
||||
if (!IsBrowserProcess(command_line))
|
||||
return;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Disable the LegacyRenderWidgetHostHWND, it made frameless windows unable
|
||||
// to move and resize. We may consider enabling it again after upgraded to
|
||||
// Chrome 38, which should have fixed the problem.
|
||||
command_line->AppendSwitch(switches::kDisableLegacyIntermediateWindow);
|
||||
#endif
|
||||
|
||||
// Disable renderer sandbox for most of node's functions.
|
||||
command_line->AppendSwitch(switches::kNoSandbox);
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include "atom/app/uv_task_runner.h"
|
||||
#include "atom/browser/javascript_environment.h"
|
||||
#include "atom/browser/node_debugger.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/command_line.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/thread_task_runner_handle.h"
|
||||
#include "gin/array_buffer.h"
|
||||
#include "gin/public/isolate_holder.h"
|
||||
@@ -19,25 +19,22 @@ namespace atom {
|
||||
int NodeMain(int argc, char *argv[]) {
|
||||
base::CommandLine::Init(argc, argv);
|
||||
|
||||
argv = uv_setup_args(argc, argv);
|
||||
int exec_argc;
|
||||
const char** exec_argv;
|
||||
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
|
||||
|
||||
int exit_code = 1;
|
||||
{
|
||||
// Feed gin::PerIsolateData with a task runner.
|
||||
argv = uv_setup_args(argc, argv);
|
||||
uv_loop_t* loop = uv_default_loop();
|
||||
scoped_refptr<UvTaskRunner> uv_task_runner(new UvTaskRunner(loop));
|
||||
base::ThreadTaskRunnerHandle handle(uv_task_runner);
|
||||
|
||||
gin::V8Initializer::LoadV8Snapshot();
|
||||
gin::V8Initializer::LoadV8Natives();
|
||||
gin::IsolateHolder::Initialize(
|
||||
gin::IsolateHolder::kNonStrictMode,
|
||||
gin::ArrayBufferAllocator::SharedInstance());
|
||||
|
||||
JavascriptEnvironment gin_env;
|
||||
|
||||
int exec_argc;
|
||||
const char** exec_argv;
|
||||
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
|
||||
|
||||
node::Environment* env = node::CreateEnvironment(
|
||||
gin_env.isolate(), loop, gin_env.context(), argc, argv,
|
||||
exec_argc, exec_argv);
|
||||
|
||||
@@ -48,8 +48,13 @@ void UvTaskRunner::OnTimeout(uv_timer_t* timer) {
|
||||
|
||||
self->tasks_[timer].Run();
|
||||
self->tasks_.erase(timer);
|
||||
uv_unref(reinterpret_cast<uv_handle_t*>(timer));
|
||||
delete timer;
|
||||
uv_timer_stop(timer);
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(timer), UvTaskRunner::OnClose);
|
||||
}
|
||||
|
||||
// static
|
||||
void UvTaskRunner::OnClose(uv_handle_t* handle) {
|
||||
delete reinterpret_cast<uv_timer_t*>(handle);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -31,6 +31,7 @@ class UvTaskRunner : public base::SingleThreadTaskRunner {
|
||||
|
||||
private:
|
||||
static void OnTimeout(uv_timer_t* timer);
|
||||
static void OnClose(uv_handle_t* handle);
|
||||
|
||||
uv_loop_t* loop_;
|
||||
|
||||
|
||||
@@ -7,26 +7,29 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/api/atom_api_session.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.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/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/path_service.h"
|
||||
#include "brightray/browser/brightray_paths.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "content/public/browser/client_certificate_delegate.h"
|
||||
#include "content/public/browser/gpu_data_manager.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
@@ -61,21 +64,6 @@ struct Converter<Browser::UserTask> {
|
||||
};
|
||||
#endif
|
||||
|
||||
template<>
|
||||
struct Converter<scoped_refptr<net::X509Certificate>> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const scoped_refptr<net::X509Certificate>& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
std::string encoded_data;
|
||||
net::X509Certificate::GetPEMEncoded(
|
||||
val->os_cert_handle(), &encoded_data);
|
||||
dict.Set("data", encoded_data);
|
||||
dict.Set("issuerName", val->issuer().GetDisplayName());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
|
||||
@@ -99,22 +87,47 @@ int GetPathConstant(const std::string& name) {
|
||||
return base::DIR_HOME;
|
||||
else if (name == "temp")
|
||||
return base::DIR_TEMP;
|
||||
else if (name == "userDesktop")
|
||||
else if (name == "userDesktop" || name == "desktop")
|
||||
return base::DIR_USER_DESKTOP;
|
||||
else if (name == "exe")
|
||||
return base::FILE_EXE;
|
||||
else if (name == "module")
|
||||
return base::FILE_MODULE;
|
||||
else if (name == "documents")
|
||||
return chrome::DIR_USER_DOCUMENTS;
|
||||
else if (name == "downloads")
|
||||
return chrome::DIR_DEFAULT_DOWNLOADS;
|
||||
else if (name == "music")
|
||||
return chrome::DIR_USER_MUSIC;
|
||||
else if (name == "pictures")
|
||||
return chrome::DIR_USER_PICTURES;
|
||||
else if (name == "videos")
|
||||
return chrome::DIR_USER_VIDEOS;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool NotificationCallbackWrapper(
|
||||
const ProcessSingleton::NotificationCallback& callback,
|
||||
const base::CommandLine::StringVector& cmd,
|
||||
const base::FilePath& cwd) {
|
||||
// Make sure the callback is called after app gets ready.
|
||||
if (Browser::Get()->is_ready()) {
|
||||
callback.Run(cmd, cwd);
|
||||
} else {
|
||||
scoped_refptr<base::SingleThreadTaskRunner> task_runner(
|
||||
base::ThreadTaskRunnerHandle::Get());
|
||||
task_runner->PostTask(
|
||||
FROM_HERE, base::Bind(base::IgnoreResult(callback), cmd, cwd));
|
||||
}
|
||||
// ProcessSingleton needs to know whether current process is quiting.
|
||||
return !Browser::Get()->is_shutting_down();
|
||||
}
|
||||
|
||||
void OnClientCertificateSelected(
|
||||
v8::Isolate* isolate,
|
||||
std::shared_ptr<content::ClientCertificateDelegate> delegate,
|
||||
mate::Arguments* args) {
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
mate::Dictionary cert_data;
|
||||
if (!(args->Length() == 1 && args->GetNext(&cert_data))) {
|
||||
args->ThrowError();
|
||||
@@ -128,18 +141,29 @@ void OnClientCertificateSelected(
|
||||
net::X509Certificate::CreateCertificateListFromBytes(
|
||||
encoded_data.data(), encoded_data.size(),
|
||||
net::X509Certificate::FORMAT_AUTO);
|
||||
|
||||
delegate->ContinueWithCertificate(certs[0].get());
|
||||
}
|
||||
|
||||
void PassLoginInformation(scoped_refptr<LoginHandler> login_handler,
|
||||
mate::Arguments* args) {
|
||||
base::string16 username, password;
|
||||
if (args->GetNext(&username) && args->GetNext(&password))
|
||||
login_handler->Login(username, password);
|
||||
else
|
||||
login_handler->CancelAuth();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
App::App() {
|
||||
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())->set_delegate(this);
|
||||
Browser::Get()->AddObserver(this);
|
||||
content::GpuDataManager::GetInstance()->AddObserver(this);
|
||||
}
|
||||
|
||||
App::~App() {
|
||||
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())->set_delegate(
|
||||
nullptr);
|
||||
Browser::Get()->RemoveObserver(this);
|
||||
content::GpuDataManager::GetInstance()->RemoveObserver(this);
|
||||
}
|
||||
@@ -158,6 +182,11 @@ void App::OnWindowAllClosed() {
|
||||
|
||||
void App::OnQuit() {
|
||||
Emit("quit");
|
||||
|
||||
if (process_singleton_.get()) {
|
||||
process_singleton_->Cleanup();
|
||||
process_singleton_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void App::OnOpenFile(bool* prevent_default, const std::string& file_path) {
|
||||
@@ -177,26 +206,62 @@ void App::OnWillFinishLaunching() {
|
||||
}
|
||||
|
||||
void App::OnFinishLaunching() {
|
||||
// Create the defaultSession.
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto browser_context = static_cast<AtomBrowserContext*>(
|
||||
AtomBrowserMainParts::Get()->browser_context());
|
||||
auto handle = Session::CreateFrom(isolate(), browser_context);
|
||||
default_session_.Reset(isolate(), handle.ToV8());
|
||||
|
||||
Emit("ready");
|
||||
}
|
||||
|
||||
void App::OnSelectCertificate(
|
||||
void App::OnLogin(LoginHandler* login_handler) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
bool prevent_default = Emit(
|
||||
"login",
|
||||
WebContents::CreateFrom(isolate(), login_handler->GetWebContents()),
|
||||
login_handler->request(),
|
||||
login_handler->auth_info(),
|
||||
base::Bind(&PassLoginInformation, make_scoped_refptr(login_handler)));
|
||||
|
||||
// Default behavior is to always cancel the auth.
|
||||
if (!prevent_default)
|
||||
login_handler->CancelAuth();
|
||||
}
|
||||
|
||||
void App::AllowCertificateError(
|
||||
int pid,
|
||||
int fid,
|
||||
int cert_error,
|
||||
const net::SSLInfo& ssl_info,
|
||||
const GURL& request_url,
|
||||
content::ResourceType resource_type,
|
||||
bool overridable,
|
||||
bool strict_enforcement,
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(bool)>& callback,
|
||||
content::CertificateRequestResultType* request) {
|
||||
auto rfh = content::RenderFrameHost::FromID(pid, fid);
|
||||
auto web_contents = content::WebContents::FromRenderFrameHost(rfh);
|
||||
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
bool prevent_default = Emit("certificate-error",
|
||||
WebContents::CreateFrom(isolate(), web_contents),
|
||||
request_url,
|
||||
net::ErrorToString(cert_error),
|
||||
ssl_info.cert,
|
||||
callback);
|
||||
|
||||
// Deny the certificate by default.
|
||||
if (!prevent_default)
|
||||
*request = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
|
||||
}
|
||||
|
||||
void App::SelectClientCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
scoped_ptr<content::ClientCertificateDelegate> delegate) {
|
||||
std::shared_ptr<content::ClientCertificateDelegate>
|
||||
shared_delegate(delegate.release());
|
||||
bool prevent_default =
|
||||
Emit("select-certificate",
|
||||
api::WebContents::CreateFrom(isolate(), web_contents),
|
||||
Emit("select-client-certificate",
|
||||
WebContents::CreateFrom(isolate(), web_contents),
|
||||
cert_request_info->host_and_port.ToString(),
|
||||
cert_request_info->client_certs,
|
||||
base::Bind(&OnClientCertificateSelected,
|
||||
@@ -242,22 +307,36 @@ void App::SetDesktopName(const std::string& desktop_name) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void App::SetAppUserModelId(const std::string& app_id) {
|
||||
#if defined(OS_WIN)
|
||||
base::string16 app_id_utf16 = base::UTF8ToUTF16(app_id);
|
||||
SetCurrentProcessExplicitAppUserModelID(app_id_utf16.c_str());
|
||||
#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("");
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> App::DefaultSession(v8::Isolate* isolate) {
|
||||
if (default_session_.IsEmpty())
|
||||
return v8::Null(isolate);
|
||||
else
|
||||
return v8::Local<v8::Value>::New(isolate, default_session_);
|
||||
bool App::MakeSingleInstance(
|
||||
const ProcessSingleton::NotificationCallback& callback) {
|
||||
if (process_singleton_.get())
|
||||
return false;
|
||||
|
||||
base::FilePath user_dir;
|
||||
PathService::Get(brightray::DIR_USER_DATA, &user_dir);
|
||||
process_singleton_.reset(new ProcessSingleton(
|
||||
user_dir, base::Bind(NotificationCallbackWrapper, callback)));
|
||||
|
||||
switch (process_singleton_->NotifyOtherProcessOrCreate()) {
|
||||
case ProcessSingleton::NotifyResult::LOCK_ERROR:
|
||||
case ProcessSingleton::NotifyResult::PROFILE_IN_USE:
|
||||
case ProcessSingleton::NotifyResult::PROCESS_NOTIFIED:
|
||||
process_singleton_.reset();
|
||||
return true;
|
||||
case ProcessSingleton::NotifyResult::PROCESS_NONE:
|
||||
default: // Shouldn't be needed, but VS warns if it is not there.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||
@@ -265,6 +344,7 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||
auto browser = base::Unretained(Browser::Get());
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("quit", base::Bind(&Browser::Quit, browser))
|
||||
.SetMethod("exit", base::Bind(&Browser::Exit, browser))
|
||||
.SetMethod("focus", base::Bind(&Browser::Focus, browser))
|
||||
.SetMethod("getVersion", base::Bind(&Browser::GetVersion, browser))
|
||||
.SetMethod("setVersion", base::Bind(&Browser::SetVersion, browser))
|
||||
@@ -275,6 +355,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||
base::Bind(&Browser::AddRecentDocument, browser))
|
||||
.SetMethod("clearRecentDocuments",
|
||||
base::Bind(&Browser::ClearRecentDocuments, browser))
|
||||
.SetMethod("setAppUserModelId",
|
||||
base::Bind(&Browser::SetAppUserModelID, browser))
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("setUserTasks",
|
||||
base::Bind(&Browser::SetUserTasks, browser))
|
||||
@@ -282,9 +364,10 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||
.SetMethod("setPath", &App::SetPath)
|
||||
.SetMethod("getPath", &App::GetPath)
|
||||
.SetMethod("setDesktopName", &App::SetDesktopName)
|
||||
.SetMethod("setAppUserModelId", &App::SetAppUserModelId)
|
||||
.SetMethod("allowNTLMCredentialsForAllDomains",
|
||||
&App::AllowNTLMCredentialsForAllDomains)
|
||||
.SetMethod("getLocale", &App::GetLocale)
|
||||
.SetProperty("defaultSession", &App::DefaultSession);
|
||||
.SetMethod("makeSingleInstance", &App::MakeSingleInstance);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -301,6 +384,16 @@ 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 ||
|
||||
switch_string == switches::kLogNetLog) {
|
||||
base::FilePath path;
|
||||
args->GetNext(&path);
|
||||
command_line->AppendSwitchPath(switch_string, path);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string value;
|
||||
if (args->GetNext(&value))
|
||||
command_line->AppendSwitchASCII(switch_string, value);
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/browser_observer.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "chrome/browser/process_singleton.h"
|
||||
#include "content/public/browser/gpu_data_manager_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
@@ -24,7 +27,8 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class App : public mate::EventEmitter,
|
||||
class App : public AtomBrowserClient::Delegate,
|
||||
public mate::EventEmitter,
|
||||
public BrowserObserver,
|
||||
public content::GpuDataManagerObserver {
|
||||
public:
|
||||
@@ -44,7 +48,22 @@ class App : public mate::EventEmitter,
|
||||
void OnActivate(bool has_visible_windows) override;
|
||||
void OnWillFinishLaunching() override;
|
||||
void OnFinishLaunching() override;
|
||||
void OnSelectCertificate(
|
||||
void OnLogin(LoginHandler* login_handler) override;
|
||||
|
||||
// content::ContentBrowserClient:
|
||||
void AllowCertificateError(
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
int cert_error,
|
||||
const net::SSLInfo& ssl_info,
|
||||
const GURL& request_url,
|
||||
content::ResourceType resource_type,
|
||||
bool overridable,
|
||||
bool strict_enforcement,
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(bool)>& callback,
|
||||
content::CertificateRequestResultType* request) override;
|
||||
void SelectClientCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
|
||||
@@ -64,11 +83,12 @@ class App : public mate::EventEmitter,
|
||||
const base::FilePath& path);
|
||||
|
||||
void SetDesktopName(const std::string& desktop_name);
|
||||
void SetAppUserModelId(const std::string& app_id);
|
||||
void AllowNTLMCredentialsForAllDomains(bool should_allow);
|
||||
bool MakeSingleInstance(
|
||||
const ProcessSingleton::NotificationCallback& callback);
|
||||
std::string GetLocale();
|
||||
v8::Local<v8::Value> DefaultSession(v8::Isolate* isolate);
|
||||
|
||||
v8::Global<v8::Value> default_session_;
|
||||
scoped_ptr<ProcessSingleton> process_singleton_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(App);
|
||||
};
|
||||
|
||||
@@ -5,12 +5,31 @@
|
||||
#include "atom/browser/api/atom_api_auto_updater.h"
|
||||
|
||||
#include "base/time/time.h"
|
||||
#include "atom/browser/auto_updater.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<base::Time> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const base::Time& val) {
|
||||
v8::MaybeLocal<v8::Value> date = v8::Date::New(
|
||||
isolate->GetCurrentContext(), val.ToJsTime());
|
||||
if (date.IsEmpty())
|
||||
return v8::Null(isolate);
|
||||
else
|
||||
return date.ToLocalChecked();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -20,11 +39,18 @@ AutoUpdater::AutoUpdater() {
|
||||
}
|
||||
|
||||
AutoUpdater::~AutoUpdater() {
|
||||
auto_updater::AutoUpdater::SetDelegate(NULL);
|
||||
auto_updater::AutoUpdater::SetDelegate(nullptr);
|
||||
}
|
||||
|
||||
void AutoUpdater::OnError(const std::string& error) {
|
||||
Emit("error", error);
|
||||
void AutoUpdater::OnError(const std::string& message) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
|
||||
EmitCustomEvent(
|
||||
"error",
|
||||
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked(),
|
||||
// Message is also emitted to keep compatibility with old code.
|
||||
message);
|
||||
}
|
||||
|
||||
void AutoUpdater::OnCheckingForUpdate() {
|
||||
@@ -42,26 +68,36 @@ void AutoUpdater::OnUpdateNotAvailable() {
|
||||
void AutoUpdater::OnUpdateDownloaded(const std::string& release_notes,
|
||||
const std::string& release_name,
|
||||
const base::Time& release_date,
|
||||
const std::string& update_url,
|
||||
const base::Closure& quit_and_install) {
|
||||
quit_and_install_ = quit_and_install;
|
||||
Emit("update-downloaded-raw", release_notes, release_name,
|
||||
release_date.ToJsTime(), update_url);
|
||||
const std::string& url) {
|
||||
Emit("update-downloaded", release_notes, release_name, release_date, url,
|
||||
// Keep compatibility with old APIs.
|
||||
base::Bind(&AutoUpdater::QuitAndInstall, base::Unretained(this)));
|
||||
}
|
||||
|
||||
void AutoUpdater::OnWindowAllClosed() {
|
||||
QuitAndInstall();
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder AutoUpdater::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("setFeedUrl", &auto_updater::AutoUpdater::SetFeedURL)
|
||||
.SetMethod("setFeedURL", &auto_updater::AutoUpdater::SetFeedURL)
|
||||
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
|
||||
.SetMethod("_quitAndInstall", &AutoUpdater::QuitAndInstall);
|
||||
.SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall);
|
||||
}
|
||||
|
||||
void AutoUpdater::QuitAndInstall() {
|
||||
if (quit_and_install_.is_null())
|
||||
Browser::Get()->Shutdown();
|
||||
else
|
||||
quit_and_install_.Run();
|
||||
// If we don't have any window then quitAndInstall immediately.
|
||||
WindowList* window_list = WindowList::GetInstance();
|
||||
if (window_list->size() == 0) {
|
||||
auto_updater::AutoUpdater::QuitAndInstall();
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise do the restart after all windows have been closed.
|
||||
window_list->AddObserver(this);
|
||||
for (NativeWindow* window : *window_list)
|
||||
window->Close();
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/auto_updater_delegate.h"
|
||||
#include "atom/browser/auto_updater.h"
|
||||
#include "atom/browser/window_list_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -17,7 +17,8 @@ namespace atom {
|
||||
namespace api {
|
||||
|
||||
class AutoUpdater : public mate::EventEmitter,
|
||||
public auto_updater::AutoUpdaterDelegate {
|
||||
public auto_updater::Delegate,
|
||||
public WindowListObserver {
|
||||
public:
|
||||
static mate::Handle<AutoUpdater> Create(v8::Isolate* isolate);
|
||||
|
||||
@@ -25,17 +26,18 @@ class AutoUpdater : public mate::EventEmitter,
|
||||
AutoUpdater();
|
||||
virtual ~AutoUpdater();
|
||||
|
||||
// AutoUpdaterDelegate implementations.
|
||||
// Delegate implementations.
|
||||
void OnError(const std::string& error) override;
|
||||
void OnCheckingForUpdate() override;
|
||||
void OnUpdateAvailable() override;
|
||||
void OnUpdateNotAvailable() override;
|
||||
void OnUpdateDownloaded(
|
||||
const std::string& release_notes,
|
||||
const std::string& release_name,
|
||||
const base::Time& release_date,
|
||||
const std::string& update_url,
|
||||
const base::Closure& quit_and_install) override;
|
||||
void OnUpdateDownloaded(const std::string& release_notes,
|
||||
const std::string& release_name,
|
||||
const base::Time& release_date,
|
||||
const std::string& update_url) override;
|
||||
|
||||
// WindowListObserver:
|
||||
void OnWindowAllClosed() override;
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
@@ -44,8 +46,6 @@ class AutoUpdater : public mate::EventEmitter,
|
||||
private:
|
||||
void QuitAndInstall();
|
||||
|
||||
base::Closure quit_and_install_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AutoUpdater);
|
||||
};
|
||||
|
||||
|
||||
@@ -204,7 +204,7 @@ void Cookies::GetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> filter,
|
||||
Passed(&filter), callback))) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&RunGetCookiesCallbackOnUIThread, isolate(),
|
||||
"Url is not valid", net::CookieList(), callback));
|
||||
"URL is not valid", net::CookieList(), callback));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ void Cookies::Remove(const mate::Dictionary& details,
|
||||
error_message = "Details(url, name) of removing cookie are required.";
|
||||
}
|
||||
if (error_message.empty() && !url.is_valid()) {
|
||||
error_message = "Url is not valid.";
|
||||
error_message = "URL is not valid.";
|
||||
}
|
||||
if (!error_message.empty()) {
|
||||
RunRemoveCookiesCallbackOnUIThread(isolate(), error_message, callback);
|
||||
@@ -261,7 +261,7 @@ void Cookies::Set(const base::DictionaryValue& options,
|
||||
|
||||
GURL gurl(url);
|
||||
if (error_message.empty() && !gurl.is_valid()) {
|
||||
error_message = "Url is not valid.";
|
||||
error_message = "URL is not valid.";
|
||||
}
|
||||
|
||||
if (!error_message.empty()) {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
@@ -102,7 +103,7 @@ int64 DownloadItem::GetTotalBytes() {
|
||||
return download_item_->GetTotalBytes();
|
||||
}
|
||||
|
||||
const GURL& DownloadItem::GetUrl() {
|
||||
const GURL& DownloadItem::GetURL() {
|
||||
return download_item_->GetURL();
|
||||
}
|
||||
|
||||
@@ -115,7 +116,7 @@ bool DownloadItem::HasUserGesture() {
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetFilename() {
|
||||
return base::UTF16ToUTF8(net::GenerateFileName(GetUrl(),
|
||||
return base::UTF16ToUTF8(net::GenerateFileName(GetURL(),
|
||||
GetContentDisposition(),
|
||||
std::string(),
|
||||
download_item_->GetSuggestedFilename(),
|
||||
@@ -151,7 +152,7 @@ mate::ObjectTemplateBuilder DownloadItem::GetObjectTemplateBuilder(
|
||||
.SetMethod("cancel", &DownloadItem::Cancel)
|
||||
.SetMethod("getReceivedBytes", &DownloadItem::GetReceivedBytes)
|
||||
.SetMethod("getTotalBytes", &DownloadItem::GetTotalBytes)
|
||||
.SetMethod("getUrl", &DownloadItem::GetUrl)
|
||||
.SetMethod("getURL", &DownloadItem::GetURL)
|
||||
.SetMethod("getMimeType", &DownloadItem::GetMimeType)
|
||||
.SetMethod("hasUserGesture", &DownloadItem::HasUserGesture)
|
||||
.SetMethod("getFilename", &DownloadItem::GetFilename)
|
||||
@@ -159,14 +160,6 @@ mate::ObjectTemplateBuilder DownloadItem::GetObjectTemplateBuilder(
|
||||
.SetMethod("setSavePath", &DownloadItem::SetSavePath);
|
||||
}
|
||||
|
||||
void SetWrapDownloadItem(const WrapDownloadItemCallback& callback) {
|
||||
g_wrap_download_item = callback;
|
||||
}
|
||||
|
||||
void ClearWrapDownloadItem() {
|
||||
g_wrap_download_item.Reset();
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<DownloadItem> DownloadItem::Create(
|
||||
v8::Isolate* isolate, content::DownloadItem* item) {
|
||||
@@ -182,6 +175,18 @@ void* DownloadItem::UserDataKey() {
|
||||
return &kDownloadItemSavePathKey;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
} // namespace atom
|
||||
@@ -193,7 +198,6 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.SetMethod("_setWrapDownloadItem", &atom::api::SetWrapDownloadItem);
|
||||
dict.SetMethod("_clearWrapDownloadItem", &atom::api::ClearWrapDownloadItem);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -49,7 +49,7 @@ class DownloadItem : public mate::EventEmitter,
|
||||
bool HasUserGesture();
|
||||
std::string GetFilename();
|
||||
std::string GetContentDisposition();
|
||||
const GURL& GetUrl();
|
||||
const GURL& GetURL();
|
||||
void SetSavePath(const base::FilePath& path);
|
||||
|
||||
private:
|
||||
|
||||
@@ -23,6 +23,9 @@ GlobalShortcut::GlobalShortcut() {
|
||||
}
|
||||
|
||||
GlobalShortcut::~GlobalShortcut() {
|
||||
}
|
||||
|
||||
void GlobalShortcut::Destroy() {
|
||||
UnregisterAll();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "base/callback.h"
|
||||
#include "chrome/browser/extensions/global_shortcut_listener.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "ui/base/accelerators/accelerator.h"
|
||||
|
||||
@@ -19,13 +19,16 @@ namespace atom {
|
||||
namespace api {
|
||||
|
||||
class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
|
||||
public mate::Wrappable {
|
||||
public mate::TrackableObject<GlobalShortcut> {
|
||||
public:
|
||||
static mate::Handle<GlobalShortcut> Create(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
GlobalShortcut();
|
||||
virtual ~GlobalShortcut();
|
||||
~GlobalShortcut() override;
|
||||
|
||||
// mate::TrackableObject:
|
||||
void Destroy() override;
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
|
||||
@@ -27,6 +27,14 @@ Menu::Menu()
|
||||
Menu::~Menu() {
|
||||
}
|
||||
|
||||
void Menu::Destroy() {
|
||||
model_.reset();
|
||||
}
|
||||
|
||||
bool Menu::IsDestroyed() const {
|
||||
return !model_;
|
||||
}
|
||||
|
||||
void Menu::AfterInit(v8::Isolate* isolate) {
|
||||
mate::Dictionary wrappable(isolate, GetWrapper(isolate));
|
||||
mate::Dictionary delegate;
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/atom_api_window.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/ui/atom_menu_model.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Menu : public mate::Wrappable,
|
||||
class Menu : public mate::TrackableObject<Menu>,
|
||||
public AtomMenuModel::Delegate {
|
||||
public:
|
||||
static mate::Wrappable* Create();
|
||||
@@ -37,9 +37,13 @@ class Menu : public mate::Wrappable,
|
||||
|
||||
protected:
|
||||
Menu();
|
||||
virtual ~Menu();
|
||||
~Menu() override;
|
||||
|
||||
// mate::TrackableObject:
|
||||
void Destroy() override;
|
||||
|
||||
// mate::Wrappable:
|
||||
bool IsDestroyed() const override;
|
||||
void AfterInit(v8::Isolate* isolate) override;
|
||||
|
||||
// ui::SimpleMenuModel::Delegate:
|
||||
|
||||
@@ -19,6 +19,7 @@ class MenuMac : public Menu {
|
||||
protected:
|
||||
MenuMac();
|
||||
|
||||
void Destroy() override;
|
||||
void Popup(Window* window) override;
|
||||
void PopupAt(Window* window, int x, int y) override;
|
||||
|
||||
|
||||
@@ -18,6 +18,11 @@ namespace api {
|
||||
MenuMac::MenuMac() {
|
||||
}
|
||||
|
||||
void MenuMac::Destroy() {
|
||||
menu_controller_.reset();
|
||||
Menu::Destroy();
|
||||
}
|
||||
|
||||
void MenuMac::Popup(Window* window) {
|
||||
NativeWindow* native_window = window->window();
|
||||
if (!native_window)
|
||||
|
||||
@@ -19,6 +19,9 @@ PowerMonitor::PowerMonitor() {
|
||||
}
|
||||
|
||||
PowerMonitor::~PowerMonitor() {
|
||||
}
|
||||
|
||||
void PowerMonitor::Destroy() {
|
||||
base::PowerMonitor::Get()->RemoveObserver(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/power_monitor/power_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
@@ -14,14 +14,17 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class PowerMonitor : public mate::EventEmitter,
|
||||
class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
|
||||
public base::PowerObserver {
|
||||
public:
|
||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
PowerMonitor();
|
||||
virtual ~PowerMonitor();
|
||||
~PowerMonitor() override;
|
||||
|
||||
// mate::TrackableObject:
|
||||
void Destroy() override;
|
||||
|
||||
// base::PowerObserver implementations:
|
||||
void OnPowerStateChange(bool on_battery_power) override;
|
||||
|
||||
@@ -45,6 +45,11 @@ PowerSaveBlocker::PowerSaveBlocker()
|
||||
PowerSaveBlocker::~PowerSaveBlocker() {
|
||||
}
|
||||
|
||||
void PowerSaveBlocker::Destroy() {
|
||||
power_save_blocker_types_.clear();
|
||||
power_save_blocker_.reset();
|
||||
}
|
||||
|
||||
void PowerSaveBlocker::UpdatePowerSaveBlocker() {
|
||||
if (power_save_blocker_types_.empty()) {
|
||||
power_save_blocker_.reset();
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "content/public/browser/power_save_blocker.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
|
||||
namespace mate {
|
||||
class Dictionary;
|
||||
@@ -20,13 +20,16 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class PowerSaveBlocker : public mate::Wrappable {
|
||||
class PowerSaveBlocker : public mate::TrackableObject<PowerSaveBlocker> {
|
||||
public:
|
||||
static mate::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
PowerSaveBlocker();
|
||||
virtual ~PowerSaveBlocker();
|
||||
~PowerSaveBlocker() override;
|
||||
|
||||
// mate::TrackableObject:
|
||||
void Destroy() override;
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
@@ -48,7 +51,6 @@ class PowerSaveBlocker : public mate::Wrappable {
|
||||
std::map<int, content::PowerSaveBlocker::PowerSaveBlockerType>;
|
||||
PowerSaveBlockerTypeMap power_save_blocker_types_;
|
||||
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
|
||||
};
|
||||
|
||||
|
||||
@@ -12,27 +12,12 @@
|
||||
#include "atom/browser/net/url_request_fetch_job.h"
|
||||
#include "atom/browser/net/url_request_string_job.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<const net::URLRequest*> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const net::URLRequest* val) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetValue("method", val->method())
|
||||
.SetValue("url", val->url().spec())
|
||||
.SetValue("referrer", val->referrer())
|
||||
.Build()->NewInstance();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -52,7 +37,7 @@ mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
|
||||
.SetMethod("registerBufferProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestBufferJob>)
|
||||
.SetMethod("registerFileProtocol",
|
||||
&Protocol::RegisterProtocol<UrlRequestAsyncAsarJob>)
|
||||
&Protocol::RegisterProtocol<URLRequestAsyncAsarJob>)
|
||||
.SetMethod("registerHttpProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
|
||||
@@ -62,7 +47,7 @@ mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
|
||||
.SetMethod("interceptBufferProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestBufferJob>)
|
||||
.SetMethod("interceptFileProtocol",
|
||||
&Protocol::InterceptProtocol<UrlRequestAsyncAsarJob>)
|
||||
&Protocol::InterceptProtocol<URLRequestAsyncAsarJob>)
|
||||
.SetMethod("interceptHttpProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
|
||||
|
||||
@@ -9,11 +9,15 @@
|
||||
|
||||
#include "atom/browser/api/atom_api_cookies.h"
|
||||
#include "atom/browser/api/atom_api_download_item.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.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/net/atom_cert_verifier.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#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"
|
||||
@@ -104,6 +108,24 @@ struct Converter<ClearStorageDataOptions> {
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<net::ProxyConfig> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
net::ProxyConfig* out) {
|
||||
std::string proxy;
|
||||
if (!ConvertFromV8(isolate, val, &proxy))
|
||||
return false;
|
||||
auto pac_url = GURL(proxy);
|
||||
if (pac_url.is_valid()) {
|
||||
out->set_pac_url(pac_url);
|
||||
} else {
|
||||
out->proxy_rules().ParseFromString(proxy);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
@@ -208,12 +230,12 @@ void ClearHttpCacheInIO(
|
||||
}
|
||||
|
||||
void SetProxyInIO(net::URLRequestContextGetter* getter,
|
||||
const std::string& proxy,
|
||||
const net::ProxyConfig& config,
|
||||
const base::Closure& callback) {
|
||||
net::ProxyConfig config;
|
||||
config.proxy_rules().ParseFromString(proxy);
|
||||
auto proxy_service = getter->GetURLRequestContext()->proxy_service();
|
||||
proxy_service->ResetConfigService(new net::ProxyConfigServiceFixed(config));
|
||||
// Refetches and applies the new pac script if provided.
|
||||
proxy_service->ForceReloadProxyConfig();
|
||||
RunCallbackInUI(callback);
|
||||
}
|
||||
|
||||
@@ -237,6 +259,8 @@ Session::~Session() {
|
||||
void Session::OnDownloadCreated(content::DownloadManager* manager,
|
||||
content::DownloadItem* item) {
|
||||
auto web_contents = item->GetWebContents();
|
||||
if (SavePageHandler::IsSavePageTypes(item->GetMimeType()))
|
||||
return;
|
||||
bool prevent_default = Emit(
|
||||
"will-download",
|
||||
DownloadItem::Create(isolate(), item),
|
||||
@@ -284,11 +308,11 @@ void Session::ClearStorageData(mate::Arguments* args) {
|
||||
base::Time(), base::Time::Max(), callback);
|
||||
}
|
||||
|
||||
void Session::SetProxy(const std::string& proxy,
|
||||
void Session::SetProxy(const net::ProxyConfig& config,
|
||||
const base::Closure& callback) {
|
||||
auto getter = browser_context_->GetRequestContext();
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&SetProxyInIO, base::Unretained(getter), proxy, callback));
|
||||
base::Bind(&SetProxyInIO, base::Unretained(getter), config, callback));
|
||||
}
|
||||
|
||||
void Session::SetDownloadPath(const base::FilePath& path) {
|
||||
@@ -333,6 +357,17 @@ void Session::DisableNetworkEmulation() {
|
||||
base::Passed(&conditions)));
|
||||
}
|
||||
|
||||
void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
AtomCertVerifier::VerifyProc proc;
|
||||
if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &proc))) {
|
||||
args->ThrowError("Must pass null or function");
|
||||
return;
|
||||
}
|
||||
|
||||
browser_context_->cert_verifier()->SetVerifyProc(proc);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
|
||||
if (cookies_.IsEmpty()) {
|
||||
auto handle = atom::api::Cookies::Create(isolate, browser_context());
|
||||
@@ -351,6 +386,7 @@ mate::ObjectTemplateBuilder Session::GetObjectTemplateBuilder(
|
||||
.SetMethod("setDownloadPath", &Session::SetDownloadPath)
|
||||
.SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation)
|
||||
.SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation)
|
||||
.SetMethod("setCertificateVerifyProc", &Session::SetCertVerifyProc)
|
||||
.SetProperty("cookies", &Session::Cookies);
|
||||
}
|
||||
|
||||
@@ -374,14 +410,18 @@ mate::Handle<Session> Session::FromPartition(
|
||||
static_cast<AtomBrowserContext*>(browser_context.get()));
|
||||
}
|
||||
|
||||
void SetWrapSession(const WrapSessionCallback& callback) {
|
||||
g_wrap_session = callback;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
} // namespace atom
|
||||
@@ -394,7 +434,6 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.SetMethod("fromPartition", &atom::api::Session::FromPartition);
|
||||
dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession);
|
||||
dict.SetMethod("_clearWrapSession", &atom::api::ClearWrapSession);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -23,6 +23,10 @@ class Arguments;
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class ProxyConfig;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserContext;
|
||||
@@ -64,10 +68,11 @@ class Session: public mate::TrackableObject<Session>,
|
||||
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
|
||||
void ClearCache(const net::CompletionCallback& callback);
|
||||
void ClearStorageData(mate::Arguments* args);
|
||||
void SetProxy(const std::string& proxy, const base::Closure& callback);
|
||||
void SetProxy(const net::ProxyConfig& config, const base::Closure& callback);
|
||||
void SetDownloadPath(const base::FilePath& path);
|
||||
void EnableNetworkEmulation(const mate::Dictionary& options);
|
||||
void DisableNetworkEmulation();
|
||||
void SetCertVerifyProc(v8::Local<v8::Value> proc, mate::Arguments* args);
|
||||
v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
|
||||
|
||||
// Cached object for cookies API.
|
||||
|
||||
@@ -44,21 +44,21 @@ mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) {
|
||||
void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
EmitCustomEvent("clicked",
|
||||
EmitCustomEvent("click",
|
||||
ModifiersToObject(isolate(), modifiers), bounds);
|
||||
}
|
||||
|
||||
void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
EmitCustomEvent("double-clicked",
|
||||
EmitCustomEvent("double-click",
|
||||
ModifiersToObject(isolate(), modifiers), bounds);
|
||||
}
|
||||
|
||||
void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
EmitCustomEvent("right-clicked",
|
||||
EmitCustomEvent("right-click",
|
||||
ModifiersToObject(isolate(), modifiers), bounds);
|
||||
}
|
||||
|
||||
@@ -67,17 +67,33 @@ void Tray::OnBalloonShow() {
|
||||
}
|
||||
|
||||
void Tray::OnBalloonClicked() {
|
||||
Emit("balloon-clicked");
|
||||
Emit("balloon-click");
|
||||
}
|
||||
|
||||
void Tray::OnBalloonClosed() {
|
||||
Emit("balloon-closed");
|
||||
}
|
||||
|
||||
void Tray::OnDrop() {
|
||||
Emit("drop");
|
||||
}
|
||||
|
||||
void Tray::OnDropFiles(const std::vector<std::string>& files) {
|
||||
Emit("drop-files", files);
|
||||
}
|
||||
|
||||
void Tray::OnDragEntered() {
|
||||
Emit("drag-enter");
|
||||
}
|
||||
|
||||
void Tray::OnDragExited() {
|
||||
Emit("drag-leave");
|
||||
}
|
||||
|
||||
void Tray::OnDragEnded() {
|
||||
Emit("drag-end");
|
||||
}
|
||||
|
||||
bool Tray::IsDestroyed() const {
|
||||
return !tray_icon_;
|
||||
}
|
||||
@@ -145,6 +161,7 @@ void Tray::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("destroy", &Tray::Destroy, true)
|
||||
.SetMethod("isDestroyed", &Tray::IsDestroyed, true)
|
||||
.SetMethod("setImage", &Tray::SetImage)
|
||||
.SetMethod("setPressedImage", &Tray::SetPressedImage)
|
||||
.SetMethod("setToolTip", &Tray::SetToolTip)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/ui/tray_icon_observer.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace api {
|
||||
|
||||
class Menu;
|
||||
|
||||
class Tray : public mate::EventEmitter,
|
||||
class Tray : public mate::TrackableObject<Tray>,
|
||||
public TrayIconObserver {
|
||||
public:
|
||||
static mate::Wrappable* New(v8::Isolate* isolate, const gfx::Image& image);
|
||||
@@ -39,7 +39,7 @@ class Tray : public mate::EventEmitter,
|
||||
|
||||
protected:
|
||||
explicit Tray(const gfx::Image& image);
|
||||
virtual ~Tray();
|
||||
~Tray() override;
|
||||
|
||||
// TrayIconObserver:
|
||||
void OnClicked(const gfx::Rect& bounds, int modifiers) override;
|
||||
@@ -48,12 +48,18 @@ class Tray : public mate::EventEmitter,
|
||||
void OnBalloonShow() override;
|
||||
void OnBalloonClicked() override;
|
||||
void OnBalloonClosed() override;
|
||||
void OnDrop() override;
|
||||
void OnDropFiles(const std::vector<std::string>& files) override;
|
||||
void OnDragEntered() override;
|
||||
void OnDragExited() override;
|
||||
void OnDragEnded() override;
|
||||
|
||||
// mate::Wrappable:
|
||||
bool IsDestroyed() const override;
|
||||
|
||||
void Destroy();
|
||||
// mate::TrackableObject:
|
||||
void Destroy() 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);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "atom/common/api/event_emitter_caller.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"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
@@ -31,6 +32,7 @@
|
||||
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||
#include "chrome/browser/printing/print_preview_message_handler.h"
|
||||
#include "content/common/view_messages.h"
|
||||
#include "content/public/browser/browser_plugin_guest_manager.h"
|
||||
#include "content/public/browser/favicon_status.h"
|
||||
#include "content/public/browser/native_web_keyboard_event.h"
|
||||
#include "content/public/browser/navigation_details.h"
|
||||
@@ -45,12 +47,14 @@
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/browser/site_instance.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/context_menu_params.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
#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 "ui/base/l10n/l10n_util.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
@@ -62,9 +66,21 @@ struct PrintSettings {
|
||||
};
|
||||
|
||||
void SetUserAgentInIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
std::string accept_lang,
|
||||
std::string user_agent) {
|
||||
getter->GetURLRequestContext()->set_http_user_agent_settings(
|
||||
new net::StaticHttpUserAgentSettings("en-us,en", user_agent));
|
||||
new net::StaticHttpUserAgentSettings(
|
||||
net::HttpUtil::GenerateAcceptLanguageHeader(accept_lang),
|
||||
user_agent));
|
||||
}
|
||||
|
||||
bool NotifyZoomLevelChanged(
|
||||
double level, content::WebContents* guest_web_contents) {
|
||||
guest_web_contents->SendToAllFrames(
|
||||
new AtomViewMsg_SetZoomLevel(MSG_ROUTING_NONE, level));
|
||||
|
||||
// Return false to iterate over all guests.
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -133,7 +149,6 @@ struct Converter<net::HttpResponseHeaders*> {
|
||||
std::string value;
|
||||
while (headers->EnumerateHeaderLines(&iter, &key, &value)) {
|
||||
key = base::StringToLowerASCII(key);
|
||||
value = base::StringToLowerASCII(value);
|
||||
if (response_headers.HasKey(key)) {
|
||||
base::ListValue* values = nullptr;
|
||||
if (response_headers.GetList(key, &values))
|
||||
@@ -149,6 +164,27 @@ struct Converter<net::HttpResponseHeaders*> {
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<content::SavePageType> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
content::SavePageType* out) {
|
||||
std::string save_type;
|
||||
if (!ConvertFromV8(isolate, val, &save_type))
|
||||
return false;
|
||||
save_type = base::StringToLowerASCII(save_type);
|
||||
if (save_type == "htmlonly") {
|
||||
*out = content::SAVE_PAGE_TYPE_AS_ONLY_HTML;
|
||||
} else if (save_type == "htmlcomplete") {
|
||||
*out = content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML;
|
||||
} else if (save_type == "mhtml") {
|
||||
*out = content::SAVE_PAGE_TYPE_AS_MHTML;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
|
||||
@@ -233,9 +269,7 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
managed_web_contents()->GetView()->SetDelegate(this);
|
||||
|
||||
// Save the preferences in C++.
|
||||
base::DictionaryValue web_preferences;
|
||||
mate::ConvertFromV8(isolate, options.GetHandle(), &web_preferences);
|
||||
new WebContentsPreferences(web_contents, &web_preferences);
|
||||
new WebContentsPreferences(web_contents, options);
|
||||
|
||||
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
|
||||
|
||||
@@ -371,6 +405,15 @@ void WebContents::RendererResponsive(content::WebContents* source) {
|
||||
owner_window()->RendererResponsive(source);
|
||||
}
|
||||
|
||||
bool WebContents::HandleContextMenu(const content::ContextMenuParams& params) {
|
||||
if (!params.custom_context.is_pepper_menu)
|
||||
return false;
|
||||
|
||||
Emit("pepper-context-menu", std::make_pair(params, web_contents()));
|
||||
web_contents()->NotifyContextMenuClosed(params.custom_context);
|
||||
return true;
|
||||
}
|
||||
|
||||
void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
|
||||
// Do nothing, we override this method just to avoid compilation error since
|
||||
// there are two virtual functions named BeforeUnloadFired.
|
||||
@@ -528,6 +571,7 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
||||
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
|
||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync,
|
||||
OnRendererMessageSync)
|
||||
IPC_MESSAGE_HANDLER(AtomViewHostMsg_ZoomLevelChanged, OnZoomLevelChanged)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
|
||||
@@ -560,10 +604,6 @@ void WebContents::Destroy() {
|
||||
}
|
||||
}
|
||||
|
||||
bool WebContents::IsAlive() const {
|
||||
return web_contents() != NULL;
|
||||
}
|
||||
|
||||
int WebContents::GetID() const {
|
||||
return web_contents()->GetRenderProcessHost()->GetID();
|
||||
}
|
||||
@@ -584,6 +624,10 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
|
||||
if (options.Get("userAgent", &user_agent))
|
||||
SetUserAgent(user_agent);
|
||||
|
||||
std::string extra_headers;
|
||||
if (options.Get("extraHeaders", &extra_headers))
|
||||
params.extra_headers = extra_headers;
|
||||
|
||||
params.transition_type = ui::PAGE_TRANSITION_TYPED;
|
||||
params.should_clear_history_list = true;
|
||||
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
|
||||
@@ -610,10 +654,6 @@ void WebContents::Stop() {
|
||||
web_contents()->Stop();
|
||||
}
|
||||
|
||||
void WebContents::ReloadIgnoringCache() {
|
||||
web_contents()->GetController().ReloadIgnoringCache(false);
|
||||
}
|
||||
|
||||
void WebContents::GoBack() {
|
||||
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
|
||||
web_contents()->GetController().GoBack();
|
||||
@@ -637,8 +677,10 @@ void WebContents::SetUserAgent(const std::string& user_agent) {
|
||||
web_contents()->SetUserAgentOverride(user_agent);
|
||||
scoped_refptr<net::URLRequestContextGetter> getter =
|
||||
web_contents()->GetBrowserContext()->GetRequestContext();
|
||||
|
||||
auto accept_lang = l10n_util::GetApplicationLocale("");
|
||||
getter->GetNetworkTaskRunner()->PostTask(FROM_HERE,
|
||||
base::Bind(&SetUserAgentInIO, getter, user_agent));
|
||||
base::Bind(&SetUserAgentInIO, getter, accept_lang, user_agent));
|
||||
}
|
||||
|
||||
std::string WebContents::GetUserAgent() {
|
||||
@@ -649,6 +691,13 @@ void WebContents::InsertCSS(const std::string& css) {
|
||||
web_contents()->InsertCSS(css);
|
||||
}
|
||||
|
||||
bool WebContents::SavePage(const base::FilePath& full_file_path,
|
||||
const content::SavePageType& save_type,
|
||||
const SavePageHandler::SavePageCallback& callback) {
|
||||
auto handler = new SavePageHandler(web_contents(), callback);
|
||||
return handler->Handle(full_file_path, save_type);
|
||||
}
|
||||
|
||||
void WebContents::ExecuteJavaScript(const base::string16& code,
|
||||
bool has_user_gesture) {
|
||||
Send(new AtomViewMsg_ExecuteJavaScript(routing_id(), code, has_user_gesture));
|
||||
@@ -943,16 +992,15 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||
if (template_.IsEmpty())
|
||||
template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("destroy", &WebContents::Destroy, true)
|
||||
.SetMethod("isAlive", &WebContents::IsAlive, true)
|
||||
.SetMethod("isDestroyed", &WebContents::IsDestroyed, true)
|
||||
.SetMethod("getId", &WebContents::GetID)
|
||||
.SetMethod("equal", &WebContents::Equal)
|
||||
.SetMethod("_loadUrl", &WebContents::LoadURL)
|
||||
.SetMethod("_getUrl", &WebContents::GetURL)
|
||||
.SetMethod("_loadURL", &WebContents::LoadURL)
|
||||
.SetMethod("_getURL", &WebContents::GetURL)
|
||||
.SetMethod("getTitle", &WebContents::GetTitle)
|
||||
.SetMethod("isLoading", &WebContents::IsLoading)
|
||||
.SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse)
|
||||
.SetMethod("_stop", &WebContents::Stop)
|
||||
.SetMethod("_reloadIgnoringCache", &WebContents::ReloadIgnoringCache)
|
||||
.SetMethod("_goBack", &WebContents::GoBack)
|
||||
.SetMethod("_goForward", &WebContents::GoForward)
|
||||
.SetMethod("_goToOffset", &WebContents::GoToOffset)
|
||||
@@ -960,6 +1008,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||
.SetMethod("setUserAgent", &WebContents::SetUserAgent)
|
||||
.SetMethod("getUserAgent", &WebContents::GetUserAgent)
|
||||
.SetMethod("insertCSS", &WebContents::InsertCSS)
|
||||
.SetMethod("savePage", &WebContents::SavePage)
|
||||
.SetMethod("_executeJavaScript", &WebContents::ExecuteJavaScript)
|
||||
.SetMethod("openDevTools", &WebContents::OpenDevTools)
|
||||
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
|
||||
@@ -1013,7 +1062,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||
}
|
||||
|
||||
bool WebContents::IsDestroyed() const {
|
||||
return !IsAlive();
|
||||
return !web_contents();
|
||||
}
|
||||
|
||||
AtomBrowserContext* WebContents::GetBrowserContext() const {
|
||||
@@ -1033,6 +1082,15 @@ void WebContents::OnRendererMessageSync(const base::string16& channel,
|
||||
EmitWithSender(base::UTF16ToUTF8(channel), web_contents(), message, args);
|
||||
}
|
||||
|
||||
void WebContents::OnZoomLevelChanged(double level) {
|
||||
auto manager = web_contents()->GetBrowserContext()->GetGuestManager();
|
||||
if (!manager)
|
||||
return;
|
||||
manager->ForEachGuest(web_contents(),
|
||||
base::Bind(&NotifyZoomLevelChanged,
|
||||
level));
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<WebContents> WebContents::CreateFrom(
|
||||
v8::Isolate* isolate, content::WebContents* web_contents) {
|
||||
@@ -1055,14 +1113,18 @@ mate::Handle<WebContents> WebContents::Create(
|
||||
return handle;
|
||||
}
|
||||
|
||||
void SetWrapWebContents(const WrapWebContentsCallback& callback) {
|
||||
g_wrap_web_contents = callback;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
} // namespace atom
|
||||
@@ -1076,7 +1138,6 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.SetMethod("create", &atom::api::WebContents::Create);
|
||||
dict.SetMethod("_setWrapWebContents", &atom::api::SetWrapWebContents);
|
||||
dict.SetMethod("_clearWrapWebContents", &atom::api::ClearWrapWebContents);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/frame_subscriber.h"
|
||||
#include "atom/browser/api/save_page_handler.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
@@ -56,7 +57,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// mate::TrackableObject:
|
||||
void Destroy() override;
|
||||
|
||||
bool IsAlive() const;
|
||||
int GetID() const;
|
||||
bool Equal(const WebContents* web_contents) const;
|
||||
void LoadURL(const GURL& url, const mate::Dictionary& options);
|
||||
@@ -73,6 +73,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void SetUserAgent(const std::string& user_agent);
|
||||
std::string GetUserAgent();
|
||||
void InsertCSS(const std::string& css);
|
||||
bool SavePage(const base::FilePath& full_file_path,
|
||||
const content::SavePageType& save_type,
|
||||
const SavePageHandler::SavePageCallback& callback);
|
||||
void ExecuteJavaScript(const base::string16& code,
|
||||
bool has_user_gesture);
|
||||
void OpenDevTools(mate::Arguments* args);
|
||||
@@ -185,6 +188,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void ExitFullscreenModeForTab(content::WebContents* source) override;
|
||||
void RendererUnresponsive(content::WebContents* source) override;
|
||||
void RendererResponsive(content::WebContents* source) override;
|
||||
bool HandleContextMenu(const content::ContextMenuParams& params) override;
|
||||
|
||||
// content::WebContentsObserver:
|
||||
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
|
||||
@@ -247,6 +251,10 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
const base::ListValue& args,
|
||||
IPC::Message* message);
|
||||
|
||||
// Called when guests need to be notified of
|
||||
// embedders' zoom level change.
|
||||
void OnZoomLevelChanged(double level);
|
||||
|
||||
v8::Global<v8::Value> session_;
|
||||
v8::Global<v8::Value> devtools_web_contents_;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_window.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
@@ -60,22 +61,82 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Converts binary data to Buffer.
|
||||
v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
|
||||
auto buffer = node::Buffer::New(isolate, static_cast<char*>(val), size);
|
||||
if (buffer.IsEmpty())
|
||||
return v8::Null(isolate);
|
||||
else
|
||||
return buffer.ToLocalChecked();
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
|
||||
// Use options['web-preferences'] to create WebContents.
|
||||
// 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(switches::kWebPreferences, &web_preferences);
|
||||
options.Get(options::kWebPreferences, &web_preferences);
|
||||
|
||||
// Be compatible with old options which are now in web_preferences.
|
||||
v8::Local<v8::Value> value;
|
||||
if (options.Get(switches::kNodeIntegration, &value))
|
||||
web_preferences.Set(switches::kNodeIntegration, value);
|
||||
if (options.Get(switches::kPreloadScript, &value))
|
||||
web_preferences.Set(switches::kPreloadScript, value);
|
||||
if (options.Get(switches::kZoomFactor, &value))
|
||||
web_preferences.Set(switches::kZoomFactor, 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);
|
||||
|
||||
// Creates the WebContents used by BrowserWindow.
|
||||
auto web_contents = WebContents::Create(isolate, web_preferences);
|
||||
@@ -189,6 +250,16 @@ void Window::OnExecuteWindowsCommand(const std::string& command_name) {
|
||||
Emit("app-command", command_name);
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void Window::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {
|
||||
if (IsWindowMessageHooked(message)) {
|
||||
messages_callback_map_[message].Run(
|
||||
ToBuffer(isolate(), static_cast<void*>(&w_param), sizeof(WPARAM)),
|
||||
ToBuffer(isolate(), static_cast<void*>(&l_param), sizeof(LPARAM)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
mate::Wrappable* Window::New(v8::Isolate* isolate,
|
||||
const mate::Dictionary& options) {
|
||||
@@ -213,10 +284,6 @@ void Window::Close() {
|
||||
window_->Close();
|
||||
}
|
||||
|
||||
bool Window::IsClosed() {
|
||||
return window_->IsClosed();
|
||||
}
|
||||
|
||||
void Window::Focus() {
|
||||
window_->Focus(true);
|
||||
}
|
||||
@@ -385,6 +452,10 @@ bool Window::IsKiosk() {
|
||||
return window_->IsKiosk();
|
||||
}
|
||||
|
||||
void Window::SetBackgroundColor(const std::string& color_name) {
|
||||
window_->SetBackgroundColor(color_name);
|
||||
}
|
||||
|
||||
void Window::FocusOnWebView() {
|
||||
window_->FocusOnWebView();
|
||||
}
|
||||
@@ -488,6 +559,29 @@ bool Window::IsMenuBarVisible() {
|
||||
return window_->IsMenuBarVisible();
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool Window::HookWindowMessage(UINT message,
|
||||
const MessageCallback& callback) {
|
||||
messages_callback_map_[message] = callback;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Window::UnhookWindowMessage(UINT message) {
|
||||
if (!ContainsKey(messages_callback_map_, message))
|
||||
return;
|
||||
|
||||
messages_callback_map_.erase(message);
|
||||
}
|
||||
|
||||
bool Window::IsWindowMessageHooked(UINT message) {
|
||||
return ContainsKey(messages_callback_map_, message);
|
||||
}
|
||||
|
||||
void Window::UnhookAllWindowMessages() {
|
||||
messages_callback_map_.clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void Window::ShowDefinitionForSelection() {
|
||||
window_->ShowDefinitionForSelection();
|
||||
@@ -524,8 +618,8 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("destroy", &Window::Destroy, true)
|
||||
.SetMethod("isDestroyed", &Window::IsDestroyed, true)
|
||||
.SetMethod("close", &Window::Close)
|
||||
.SetMethod("isClosed", &Window::IsClosed)
|
||||
.SetMethod("focus", &Window::Focus)
|
||||
.SetMethod("isFocused", &Window::IsFocused)
|
||||
.SetMethod("show", &Window::Show)
|
||||
@@ -564,6 +658,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setSkipTaskbar", &Window::SetSkipTaskbar)
|
||||
.SetMethod("setKiosk", &Window::SetKiosk)
|
||||
.SetMethod("isKiosk", &Window::IsKiosk)
|
||||
.SetMethod("setBackgroundColor", &Window::SetBackgroundColor)
|
||||
.SetMethod("setRepresentedFilename", &Window::SetRepresentedFilename)
|
||||
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
|
||||
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
|
||||
@@ -585,6 +680,12 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
&Window::SetVisibleOnAllWorkspaces)
|
||||
.SetMethod("isVisibleOnAllWorkspaces",
|
||||
&Window::IsVisibleOnAllWorkspaces)
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("hookWindowMessage", &Window::HookWindowMessage)
|
||||
.SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked)
|
||||
.SetMethod("unhookWindowMessage", &Window::UnhookWindowMessage)
|
||||
.SetMethod("unhookAllWindowMessages", &Window::UnhookAllWindowMessages)
|
||||
#endif
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("showDefinitionForSelection",
|
||||
&Window::ShowDefinitionForSelection)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_WINDOW_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_WINDOW_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -75,6 +76,10 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void OnRendererResponsive() override;
|
||||
void OnExecuteWindowsCommand(const std::string& command_name) override;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) override;
|
||||
#endif
|
||||
|
||||
// mate::Wrappable:
|
||||
bool IsDestroyed() const override;
|
||||
|
||||
@@ -84,7 +89,6 @@ class Window : public mate::TrackableObject<Window>,
|
||||
|
||||
// APIs for NativeWindow.
|
||||
void Close();
|
||||
bool IsClosed();
|
||||
void Focus();
|
||||
bool IsFocused();
|
||||
void Show();
|
||||
@@ -122,6 +126,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void SetSkipTaskbar(bool skip);
|
||||
void SetKiosk(bool kiosk);
|
||||
bool IsKiosk();
|
||||
void SetBackgroundColor(const std::string& color_name);
|
||||
void FocusOnWebView();
|
||||
void BlurWebView();
|
||||
bool IsWebViewFocused();
|
||||
@@ -142,6 +147,16 @@ class Window : public mate::TrackableObject<Window>,
|
||||
bool IsMenuBarVisible();
|
||||
void SetAspectRatio(double aspect_ratio, mate::Arguments* args);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
typedef base::Callback<void(v8::Local<v8::Value>,
|
||||
v8::Local<v8::Value>)> MessageCallback;
|
||||
|
||||
bool HookWindowMessage(UINT message, const MessageCallback& callback);
|
||||
bool IsWindowMessageHooked(UINT message);
|
||||
void UnhookWindowMessage(UINT message);
|
||||
void UnhookAllWindowMessages();
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void ShowDefinitionForSelection();
|
||||
#endif
|
||||
@@ -152,6 +167,11 @@ class Window : public mate::TrackableObject<Window>,
|
||||
int32_t ID() const;
|
||||
v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
typedef std::map<UINT, MessageCallback> MessageCallbackMap;
|
||||
MessageCallbackMap messages_callback_map_;
|
||||
#endif
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
v8::Global<v8::Value> menu_;
|
||||
|
||||
|
||||
@@ -38,6 +38,9 @@ void FrameSubscriber::OnFrameDelivered(
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
v8::Locker locker(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
|
||||
gfx::Rect rect = frame->visible_rect();
|
||||
size_t rgb_arr_size = rect.width() * rect.height() * 4;
|
||||
v8::MaybeLocal<v8::Object> buffer = node::Buffer::New(isolate_, rgb_arr_size);
|
||||
@@ -56,8 +59,6 @@ void FrameSubscriber::OnFrameDelivered(
|
||||
rect.width() * 4,
|
||||
media::YV12);
|
||||
|
||||
v8::Locker locker(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
callback_.Run(buffer.ToLocalChecked());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,30 +1,17 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
{deprecate, session, Menu} = require 'electron'
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
bindings = process.atomBinding 'app'
|
||||
sessionBindings = process.atomBinding 'session'
|
||||
downloadItemBindings = process.atomBinding 'download_item'
|
||||
|
||||
app = bindings.app
|
||||
app.__proto__ = EventEmitter.prototype
|
||||
|
||||
wrapSession = (session) ->
|
||||
# session is an Event Emitter.
|
||||
session.__proto__ = EventEmitter.prototype
|
||||
|
||||
wrapDownloadItem = (download_item) ->
|
||||
# download_item is an Event Emitter.
|
||||
download_item.__proto__ = EventEmitter.prototype
|
||||
# Be compatible with old APIs.
|
||||
download_item.url = download_item.getUrl()
|
||||
download_item.filename = download_item.getFilename()
|
||||
download_item.mimeType = download_item.getMimeType()
|
||||
download_item.hasUserGesture = download_item.hasUserGesture()
|
||||
|
||||
app.setApplicationMenu = (menu) ->
|
||||
require('menu').setApplicationMenu menu
|
||||
Menu.setApplicationMenu menu
|
||||
|
||||
app.getApplicationMenu = ->
|
||||
require('menu').getApplicationMenu()
|
||||
Menu.getApplicationMenu()
|
||||
|
||||
app.commandLine =
|
||||
appendSwitch: bindings.appendSwitch,
|
||||
@@ -47,22 +34,40 @@ app.setAppPath = (path) ->
|
||||
app.getAppPath = ->
|
||||
appPath
|
||||
|
||||
# Be compatible with old API.
|
||||
app.once 'ready', -> @emit 'finish-launching'
|
||||
app.terminate = app.quit
|
||||
app.exit = process.exit
|
||||
app.getHomeDir = -> @getPath 'home'
|
||||
app.getDataPath = -> @getPath 'userData'
|
||||
app.setDataPath = (path) -> @setPath 'userData', path
|
||||
app.resolveProxy = -> @defaultSession.resolveProxy.apply @defaultSession, arguments
|
||||
app.on 'activate', (event, hasVisibleWindows) -> @emit 'activate-with-no-open-windows' if not hasVisibleWindows
|
||||
# Routes the events to webContents.
|
||||
for name in ['login', 'certificate-error', 'select-client-certificate']
|
||||
do (name) ->
|
||||
app.on name, (event, webContents, args...) ->
|
||||
webContents.emit name, event, args...
|
||||
|
||||
# Session wrapper.
|
||||
sessionBindings._setWrapSession wrapSession
|
||||
process.once 'exit', sessionBindings._clearWrapSession
|
||||
# Deprecated.
|
||||
app.getHomeDir = deprecate 'app.getHomeDir', 'app.getPath', ->
|
||||
@getPath 'home'
|
||||
app.getDataPath = deprecate 'app.getDataPath', 'app.getPath', ->
|
||||
@getPath 'userData'
|
||||
app.setDataPath = deprecate 'app.setDataPath', 'app.setPath', (path) ->
|
||||
@setPath 'userData', path
|
||||
app.resolveProxy = deprecate 'app.resolveProxy', 'session.defaultSession.resolveProxy', (url, callback) ->
|
||||
session.defaultSession.resolveProxy url, callback
|
||||
deprecate.rename app, 'terminate', 'quit'
|
||||
deprecate.event app, 'finish-launching', 'ready', ->
|
||||
setImmediate => # give default app a chance to setup default menu.
|
||||
@emit 'finish-launching'
|
||||
deprecate.event app, 'activate-with-no-open-windows', 'activate', (event, hasVisibleWindows) ->
|
||||
@emit 'activate-with-no-open-windows' if not hasVisibleWindows
|
||||
deprecate.event app, 'select-certificate', 'select-client-certificate'
|
||||
|
||||
# Wrappers for native classes.
|
||||
wrapDownloadItem = (downloadItem) ->
|
||||
# downloadItem is an EventEmitter.
|
||||
downloadItem.__proto__ = EventEmitter.prototype
|
||||
# Deprecated.
|
||||
deprecate.property downloadItem, 'url', 'getURL'
|
||||
deprecate.property downloadItem, 'filename', 'getFilename'
|
||||
deprecate.property downloadItem, 'mimeType', 'getMimeType'
|
||||
deprecate.property downloadItem, 'hasUserGesture', 'hasUserGesture'
|
||||
deprecate.rename downloadItem, 'getUrl', 'getURL'
|
||||
downloadItemBindings._setWrapDownloadItem wrapDownloadItem
|
||||
process.once 'exit', downloadItemBindings._clearWrapDownloadItem
|
||||
|
||||
# Only one App object pemitted.
|
||||
module.exports = app
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
module.exports =
|
||||
browserMainParts:
|
||||
preMainMessageLoopRun: ->
|
||||
|
||||
setImmediate ->
|
||||
module.exports.browserMainParts.preMainMessageLoopRun()
|
||||
@@ -1,24 +1,12 @@
|
||||
autoUpdater = process.atomBinding('auto_updater').autoUpdater
|
||||
EventEmitter = require('events').EventEmitter
|
||||
{deprecate} = require 'electron'
|
||||
|
||||
autoUpdater.__proto__ = EventEmitter.prototype
|
||||
autoUpdater =
|
||||
if process.platform is 'win32'
|
||||
require './auto-updater/auto-updater-win'
|
||||
else
|
||||
require './auto-updater/auto-updater-native'
|
||||
|
||||
autoUpdater.on 'update-downloaded-raw', (args...) ->
|
||||
args[3] = new Date(args[3]) # releaseDate
|
||||
@emit 'update-downloaded', args..., => @quitAndInstall()
|
||||
|
||||
autoUpdater.quitAndInstall = ->
|
||||
# If we don't have any window then quitAndInstall immediately.
|
||||
BrowserWindow = require 'browser-window'
|
||||
windows = BrowserWindow.getAllWindows()
|
||||
if windows.length is 0
|
||||
@_quitAndInstall()
|
||||
return
|
||||
|
||||
# Do the restart after all windows have been closed.
|
||||
app = require 'app'
|
||||
app.removeAllListeners 'window-all-closed'
|
||||
app.once 'window-all-closed', @_quitAndInstall.bind(this)
|
||||
win.close() for win in windows
|
||||
# Deprecated.
|
||||
deprecate.rename autoUpdater, 'setFeedUrl', 'setFeedURL'
|
||||
|
||||
module.exports = autoUpdater
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{EventEmitter} = require 'events'
|
||||
{autoUpdater} = process.atomBinding 'auto_updater'
|
||||
|
||||
autoUpdater.__proto__ = EventEmitter.prototype
|
||||
|
||||
module.exports = autoUpdater
|
||||
42
atom/browser/api/lib/auto-updater/auto-updater-win.coffee
Normal file
42
atom/browser/api/lib/auto-updater/auto-updater-win.coffee
Normal file
@@ -0,0 +1,42 @@
|
||||
{app} = require 'electron'
|
||||
{EventEmitter} = require 'events'
|
||||
url = require 'url'
|
||||
|
||||
squirrelUpdate = require './squirrel-update-win'
|
||||
|
||||
class AutoUpdater extends EventEmitter
|
||||
quitAndInstall: ->
|
||||
squirrelUpdate.processStart()
|
||||
app.quit()
|
||||
|
||||
setFeedURL: (updateURL) ->
|
||||
@updateURL = updateURL
|
||||
|
||||
checkForUpdates: ->
|
||||
return @emitError 'Update URL is not set' unless @updateURL
|
||||
return @emitError 'Can not find Squirrel' unless squirrelUpdate.supported()
|
||||
|
||||
@emit 'checking-for-update'
|
||||
|
||||
squirrelUpdate.download @updateURL, (error, update) =>
|
||||
return @emitError error if error?
|
||||
return @emit 'update-not-available' unless update?
|
||||
|
||||
@emit 'update-available'
|
||||
|
||||
squirrelUpdate.update @updateURL, (error) =>
|
||||
return @emitError error if error?
|
||||
|
||||
{releaseNotes, version} = update
|
||||
# Following information is not available on Windows, so fake them.
|
||||
date = new Date
|
||||
url = @updateURL
|
||||
|
||||
@emit 'update-downloaded', {}, releaseNotes, version, date, url, => @quitAndInstall()
|
||||
|
||||
# Private: Emit both error object and message, this is to keep compatibility
|
||||
# with Old APIs.
|
||||
emitError: (message) ->
|
||||
@emit 'error', new Error(message), message
|
||||
|
||||
module.exports = new AutoUpdater
|
||||
67
atom/browser/api/lib/auto-updater/squirrel-update-win.coffee
Normal file
67
atom/browser/api/lib/auto-updater/squirrel-update-win.coffee
Normal file
@@ -0,0 +1,67 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
{spawn} = require 'child_process'
|
||||
|
||||
appFolder = path.dirname process.execPath # i.e. my-app/app-0.1.13/
|
||||
updateExe = path.resolve appFolder, '..', 'Update.exe' # i.e. my-app/Update.exe
|
||||
exeName = path.basename process.execPath
|
||||
|
||||
# Spawn a command and invoke the callback when it completes with an error
|
||||
# and the output from standard out.
|
||||
spawnUpdate = (args, detached, callback) ->
|
||||
try
|
||||
spawnedProcess = spawn updateExe, args, {detached}
|
||||
catch error
|
||||
# Shouldn't happen, but still guard it.
|
||||
process.nextTick -> callback error
|
||||
return
|
||||
|
||||
stdout = ''
|
||||
stderr = ''
|
||||
spawnedProcess.stdout.on 'data', (data) -> stdout += data
|
||||
spawnedProcess.stderr.on 'data', (data) -> stderr += data
|
||||
|
||||
errorEmitted = false
|
||||
spawnedProcess.on 'error', (error) ->
|
||||
errorEmitted = true
|
||||
callback error
|
||||
spawnedProcess.on 'exit', (code, signal) ->
|
||||
# We may have already emitted an error.
|
||||
return if errorEmitted
|
||||
|
||||
# Process terminated with error.
|
||||
if code isnt 0
|
||||
return callback "Command failed: #{signal ? code}\n#{stderr}"
|
||||
|
||||
# Success.
|
||||
callback null, stdout
|
||||
|
||||
# Start an instance of the installed app.
|
||||
exports.processStart = (callback) ->
|
||||
spawnUpdate ['--processStart', exeName], true, ->
|
||||
|
||||
# Download the releases specified by the URL and write new results to stdout.
|
||||
exports.download = (updateURL, callback) ->
|
||||
spawnUpdate ['--download', updateURL], false, (error, stdout) ->
|
||||
return callback(error) if error?
|
||||
|
||||
try
|
||||
# Last line of output is the JSON details about the releases
|
||||
json = stdout.trim().split('\n').pop()
|
||||
update = JSON.parse(json)?.releasesToApply?.pop?()
|
||||
catch
|
||||
return callback "Invalid result:\n#{stdout}"
|
||||
|
||||
callback null, update
|
||||
|
||||
# Update the application to the latest remote version specified by URL.
|
||||
exports.update = (updateURL, callback) ->
|
||||
spawnUpdate ['--update', updateURL], false, callback
|
||||
|
||||
# Is the Update.exe installed with the current application?
|
||||
exports.supported = ->
|
||||
try
|
||||
fs.accessSync updateExe, fs.R_OK
|
||||
return true
|
||||
catch
|
||||
return false
|
||||
@@ -1,11 +1,12 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
app = require 'app'
|
||||
ipc = require 'ipc'
|
||||
{ipcMain, deprecate} = require 'electron'
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
BrowserWindow = process.atomBinding('window').BrowserWindow
|
||||
{BrowserWindow} = process.atomBinding 'window'
|
||||
BrowserWindow::__proto__ = EventEmitter.prototype
|
||||
|
||||
BrowserWindow::_init = ->
|
||||
{app} = require 'electron' # avoid recursive require.
|
||||
|
||||
# Simulate the application menu on platforms other than OS X.
|
||||
if process.platform isnt 'darwin'
|
||||
menu = app.getApplicationMenu()
|
||||
@@ -14,7 +15,7 @@ BrowserWindow::_init = ->
|
||||
# Make new windows requested by links behave like "window.open"
|
||||
@webContents.on '-new-window', (event, url, frameName) ->
|
||||
options = show: true, width: 800, height: 600
|
||||
ipc.emit 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, options
|
||||
ipcMain.emit 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, options
|
||||
|
||||
# window.resizeTo(...)
|
||||
# window.moveTo(...)
|
||||
@@ -70,33 +71,35 @@ BrowserWindow.fromDevToolsWebContents = (webContents) ->
|
||||
return window for window in windows when window.devToolsWebContents?.equal webContents
|
||||
|
||||
# Helpers.
|
||||
BrowserWindow::loadUrl = -> @webContents.loadUrl.apply @webContents, arguments
|
||||
BrowserWindow::send = -> @webContents.send.apply @webContents, arguments
|
||||
|
||||
# Be compatible with old API.
|
||||
BrowserWindow::undo = -> @webContents.undo()
|
||||
BrowserWindow::redo = -> @webContents.redo()
|
||||
BrowserWindow::cut = -> @webContents.cut()
|
||||
BrowserWindow::copy = -> @webContents.copy()
|
||||
BrowserWindow::paste = -> @webContents.paste()
|
||||
BrowserWindow::selectAll = -> @webContents.selectAll()
|
||||
BrowserWindow::restart = -> @webContents.reload()
|
||||
BrowserWindow::getUrl = -> @webContents.getUrl()
|
||||
BrowserWindow::loadURL = -> @webContents.loadURL.apply @webContents, arguments
|
||||
BrowserWindow::getURL = -> @webContents.getURL()
|
||||
BrowserWindow::reload = -> @webContents.reload.apply @webContents, arguments
|
||||
BrowserWindow::reloadIgnoringCache = -> @webContents.reloadIgnoringCache.apply @webContents, arguments
|
||||
BrowserWindow::getPageTitle = -> @webContents.getTitle()
|
||||
BrowserWindow::isLoading = -> @webContents.isLoading()
|
||||
BrowserWindow::isWaitingForResponse = -> @webContents.isWaitingForResponse()
|
||||
BrowserWindow::stop = -> @webContents.stop()
|
||||
BrowserWindow::isCrashed = -> @webContents.isCrashed()
|
||||
BrowserWindow::executeJavaScriptInDevTools = (code) -> @devToolsWebContents?.executeJavaScript code
|
||||
BrowserWindow::send = -> @webContents.send.apply @webContents, arguments
|
||||
BrowserWindow::openDevTools = -> @webContents.openDevTools.apply @webContents, arguments
|
||||
BrowserWindow::closeDevTools = -> @webContents.closeDevTools()
|
||||
BrowserWindow::isDevToolsOpened = -> @webContents.isDevToolsOpened()
|
||||
BrowserWindow::toggleDevTools = -> @webContents.toggleDevTools()
|
||||
BrowserWindow::inspectElement = -> @webContents.inspectElement.apply @webContents, arguments
|
||||
BrowserWindow::inspectServiceWorker = -> @webContents.inspectServiceWorker()
|
||||
BrowserWindow::print = -> @webContents.print.apply @webContents, arguments
|
||||
BrowserWindow::printToPDF = -> @webContents.printToPDF.apply @webContents, arguments
|
||||
|
||||
# Deprecated.
|
||||
deprecate.member BrowserWindow, 'undo', 'webContents'
|
||||
deprecate.member BrowserWindow, 'redo', 'webContents'
|
||||
deprecate.member BrowserWindow, 'cut', 'webContents'
|
||||
deprecate.member BrowserWindow, 'copy', 'webContents'
|
||||
deprecate.member BrowserWindow, 'paste', 'webContents'
|
||||
deprecate.member BrowserWindow, 'selectAll', 'webContents'
|
||||
deprecate.member BrowserWindow, 'reloadIgnoringCache', 'webContents'
|
||||
deprecate.member BrowserWindow, 'getPageTitle', 'webContents'
|
||||
deprecate.member BrowserWindow, 'isLoading', 'webContents'
|
||||
deprecate.member BrowserWindow, 'isWaitingForResponse', 'webContents'
|
||||
deprecate.member BrowserWindow, 'stop', 'webContents'
|
||||
deprecate.member BrowserWindow, 'isCrashed', 'webContents'
|
||||
deprecate.member BrowserWindow, 'executeJavaScriptInDevTools', 'webContents'
|
||||
deprecate.member BrowserWindow, 'print', 'webContents'
|
||||
deprecate.member BrowserWindow, 'printToPDF', 'webContents'
|
||||
deprecate.rename BrowserWindow, 'restart', 'reload'
|
||||
deprecate.rename BrowserWindow, 'loadUrl', 'loadURL'
|
||||
deprecate.rename BrowserWindow, 'getUrl', 'getURL'
|
||||
|
||||
module.exports = BrowserWindow
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{app, BrowserWindow} = require 'electron'
|
||||
|
||||
binding = process.atomBinding 'dialog'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
app = require 'app'
|
||||
BrowserWindow = require 'browser-window'
|
||||
|
||||
fileDialogProperties =
|
||||
openFile: 1 << 0
|
||||
|
||||
55
atom/browser/api/lib/exports/electron.coffee
Normal file
55
atom/browser/api/lib/exports/electron.coffee
Normal file
@@ -0,0 +1,55 @@
|
||||
# Import common modules.
|
||||
module.exports = require '../../../../common/api/lib/exports/electron'
|
||||
|
||||
Object.defineProperties module.exports,
|
||||
# Browser side modules, please sort with alphabet order.
|
||||
app:
|
||||
enumerable: true
|
||||
get: -> require '../app'
|
||||
autoUpdater:
|
||||
enumerable: true
|
||||
get: -> require '../auto-updater'
|
||||
BrowserWindow:
|
||||
enumerable: true
|
||||
get: -> require '../browser-window'
|
||||
contentTracing:
|
||||
enumerable: true
|
||||
get: -> require '../content-tracing'
|
||||
dialog:
|
||||
enumerable: true
|
||||
get: -> require '../dialog'
|
||||
ipcMain:
|
||||
enumerable: true
|
||||
get: -> require '../ipc-main'
|
||||
globalShortcut:
|
||||
enumerable: true
|
||||
get: -> require '../global-shortcut'
|
||||
Menu:
|
||||
enumerable: true
|
||||
get: -> require '../menu'
|
||||
MenuItem:
|
||||
enumerable: true
|
||||
get: -> require '../menu-item'
|
||||
powerMonitor:
|
||||
enumerable: true
|
||||
get: -> require '../power-monitor'
|
||||
powerSaveBlocker:
|
||||
enumerable: true
|
||||
get: -> require '../power-save-blocker'
|
||||
protocol:
|
||||
enumerable: true
|
||||
get: -> require '../protocol'
|
||||
screen:
|
||||
enumerable: true
|
||||
get: -> require '../screen'
|
||||
session:
|
||||
enumerable: true
|
||||
get: -> require '../session'
|
||||
Tray:
|
||||
enumerable: true
|
||||
get: -> require '../tray'
|
||||
# The internal modules, invisible unless you know their names.
|
||||
NavigationController:
|
||||
get: -> require '../navigation-controller'
|
||||
webContents:
|
||||
get: -> require '../web-contents'
|
||||
@@ -1,5 +1,3 @@
|
||||
bindings = process.atomBinding 'global_shortcut'
|
||||
|
||||
globalShortcut = bindings.globalShortcut
|
||||
{globalShortcut} = process.atomBinding 'global_shortcut'
|
||||
|
||||
module.exports = globalShortcut
|
||||
|
||||
3
atom/browser/api/lib/ipc-main.coffee
Normal file
3
atom/browser/api/lib/ipc-main.coffee
Normal file
@@ -0,0 +1,3 @@
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
module.exports = new EventEmitter
|
||||
@@ -1,3 +1,6 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
{deprecate, ipcMain} = require 'electron'
|
||||
|
||||
module.exports = new EventEmitter
|
||||
# This module is deprecated, we mirror everything from ipcMain.
|
||||
deprecate.warn 'ipc module', 'ipcMain module'
|
||||
|
||||
module.exports = ipcMain
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
BrowserWindow = require 'browser-window'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
|
||||
nextCommandId = 0
|
||||
@@ -18,7 +17,7 @@ class MenuItem
|
||||
@types = ['normal', 'separator', 'submenu', 'checkbox', 'radio']
|
||||
|
||||
constructor: (options) ->
|
||||
Menu = require 'menu'
|
||||
{Menu} = require 'electron'
|
||||
|
||||
{click, @selector, @type, @role, @label, @sublabel, @accelerator, @icon, @enabled, @visible, @checked, @submenu} = options
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
BrowserWindow = require 'browser-window'
|
||||
EventEmitter = require('events').EventEmitter
|
||||
MenuItem = require 'menu-item'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
{BrowserWindow, MenuItem} = require 'electron'
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
bindings = process.atomBinding 'menu'
|
||||
|
||||
# Automatically generated radio menu item's group id.
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
ipc = require 'ipc'
|
||||
{ipcMain} = require 'electron'
|
||||
|
||||
# The history operation in renderer is redirected to browser.
|
||||
ipc.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) ->
|
||||
ipcMain.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) ->
|
||||
event.sender[method] args...
|
||||
|
||||
ipc.on 'ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', (event, method, args...) ->
|
||||
ipcMain.on 'ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', (event, method, args...) ->
|
||||
event.returnValue = event.sender[method] args...
|
||||
|
||||
# JavaScript implementation of Chromium's NavigationController.
|
||||
# Instead of relying on Chromium for history control, we compeletely do history
|
||||
# control on user land, and only rely on WebContents.loadUrl for navigation.
|
||||
# control on user land, and only rely on WebContents.loadURL for navigation.
|
||||
# This helps us avoid Chromium's various optimizations so we can ensure renderer
|
||||
# process is restarted everytime.
|
||||
class NavigationController
|
||||
@@ -17,9 +17,9 @@ class NavigationController
|
||||
@clearHistory()
|
||||
|
||||
# webContents may have already navigated to a page.
|
||||
if @webContents._getUrl()
|
||||
if @webContents._getURL()
|
||||
@currentIndex++
|
||||
@history.push @webContents._getUrl()
|
||||
@history.push @webContents._getURL()
|
||||
|
||||
@webContents.on 'navigation-entry-commited', (event, url, inPage, replaceEntry) =>
|
||||
if @inPageIndex > -1 and not inPage
|
||||
@@ -42,12 +42,12 @@ class NavigationController
|
||||
@currentIndex++
|
||||
@history.push url
|
||||
|
||||
loadUrl: (url, options={}) ->
|
||||
loadURL: (url, options={}) ->
|
||||
@pendingIndex = -1
|
||||
@webContents._loadUrl url, options
|
||||
@webContents._loadURL url, options
|
||||
@webContents.emit 'load-url', url, options
|
||||
|
||||
getUrl: ->
|
||||
getURL: ->
|
||||
if @currentIndex is -1
|
||||
''
|
||||
else
|
||||
@@ -59,11 +59,11 @@ class NavigationController
|
||||
|
||||
reload: ->
|
||||
@pendingIndex = @currentIndex
|
||||
@webContents._loadUrl @getUrl(), {}
|
||||
@webContents._loadURL @getURL(), {}
|
||||
|
||||
reloadIgnoringCache: ->
|
||||
@webContents._reloadIgnoringCache() # Rely on WebContents to clear cache.
|
||||
@reload()
|
||||
@pendingIndex = @currentIndex
|
||||
@webContents._loadURL @getURL(), {extraHeaders: "pragma: no-cache\n"}
|
||||
|
||||
canGoBack: ->
|
||||
@getActiveIndex() > 0
|
||||
@@ -89,7 +89,7 @@ class NavigationController
|
||||
if @inPageIndex > -1 and @pendingIndex >= @inPageIndex
|
||||
@webContents._goBack()
|
||||
else
|
||||
@webContents._loadUrl @history[@pendingIndex], {}
|
||||
@webContents._loadURL @history[@pendingIndex], {}
|
||||
|
||||
goForward: ->
|
||||
return unless @canGoForward()
|
||||
@@ -97,12 +97,12 @@ class NavigationController
|
||||
if @inPageIndex > -1 and @pendingIndex >= @inPageIndex
|
||||
@webContents._goForward()
|
||||
else
|
||||
@webContents._loadUrl @history[@pendingIndex], {}
|
||||
@webContents._loadURL @history[@pendingIndex], {}
|
||||
|
||||
goToIndex: (index) ->
|
||||
return unless @canGoToIndex index
|
||||
@pendingIndex = index
|
||||
@webContents._loadUrl @history[@pendingIndex], {}
|
||||
@webContents._loadURL @history[@pendingIndex], {}
|
||||
|
||||
goToOffset: (offset) ->
|
||||
return unless @canGoToOffset offset
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
powerMonitor = process.atomBinding('power_monitor').powerMonitor
|
||||
EventEmitter = require('events').EventEmitter
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
{powerMonitor} = process.atomBinding 'power_monitor'
|
||||
|
||||
powerMonitor.__proto__ = EventEmitter.prototype
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
bindings = process.atomBinding 'power_save_blocker'
|
||||
{powerSaveBlocker} = process.atomBinding 'power_save_blocker'
|
||||
|
||||
module.exports = bindings.powerSaveBlocker
|
||||
module.exports = powerSaveBlocker
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
app = require 'app'
|
||||
{app} = require 'electron'
|
||||
|
||||
throw new Error('Can not initialize protocol module before app is ready') unless app.isReady()
|
||||
|
||||
protocol = process.atomBinding('protocol').protocol
|
||||
{protocol} = process.atomBinding 'protocol'
|
||||
|
||||
# Warn about removed APIs.
|
||||
logAndThrow = (callback, message) ->
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
{EventEmitter} = require 'events'
|
||||
{screen} = process.atomBinding 'screen'
|
||||
|
||||
screen = process.atomBinding('screen').screen
|
||||
screen.__proto__ = EventEmitter.prototype
|
||||
|
||||
module.exports = screen
|
||||
|
||||
23
atom/browser/api/lib/session.coffee
Normal file
23
atom/browser/api/lib/session.coffee
Normal file
@@ -0,0 +1,23 @@
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
bindings = process.atomBinding 'session'
|
||||
|
||||
PERSIST_PERFIX = 'persist:'
|
||||
|
||||
# Returns the Session from |partition| string.
|
||||
exports.fromPartition = (partition='') ->
|
||||
if partition.startsWith PERSIST_PERFIX
|
||||
bindings.fromPartition partition.substr(PERSIST_PERFIX.length), false
|
||||
else
|
||||
bindings.fromPartition partition, true
|
||||
|
||||
# Returns the default session.
|
||||
Object.defineProperty exports, 'defaultSession',
|
||||
enumerable: true
|
||||
get: -> exports.fromPartition ''
|
||||
|
||||
wrapSession = (session) ->
|
||||
# session is an EventEmitter.
|
||||
session.__proto__ = EventEmitter.prototype
|
||||
|
||||
bindings._setWrapSession wrapSession
|
||||
@@ -1,14 +1,19 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
bindings = process.atomBinding 'tray'
|
||||
{deprecate} = require 'electron'
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
Tray = bindings.Tray
|
||||
{Tray} = process.atomBinding 'tray'
|
||||
Tray::__proto__ = EventEmitter.prototype
|
||||
|
||||
Tray::_init = ->
|
||||
# Deprecated.
|
||||
deprecate.rename this, 'popContextMenu', 'popUpContextMenu'
|
||||
deprecate.event this, 'clicked', 'click'
|
||||
deprecate.event this, 'double-clicked', 'double-click'
|
||||
deprecate.event this, 'right-clicked', 'right-click'
|
||||
deprecate.event this, 'balloon-clicked', 'balloon-click'
|
||||
|
||||
Tray::setContextMenu = (menu) ->
|
||||
@_setContextMenu menu
|
||||
@menu = menu # Keep a strong reference of menu.
|
||||
|
||||
# Keep compatibility with old APIs.
|
||||
Tray::popContextMenu = Tray::popUpContextMenu
|
||||
|
||||
module.exports = Tray
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
NavigationController = require './navigation-controller'
|
||||
{EventEmitter} = require 'events'
|
||||
{deprecate, ipcMain, session, NavigationController, Menu} = require 'electron'
|
||||
|
||||
binding = process.atomBinding 'web_contents'
|
||||
ipc = require 'ipc'
|
||||
|
||||
nextId = 0
|
||||
getNextId = -> ++nextId
|
||||
@@ -45,7 +45,7 @@ wrapWebContents = (webContents) ->
|
||||
# Make sure webContents.executeJavaScript would run the code only when the
|
||||
# web contents has been loaded.
|
||||
webContents.executeJavaScript = (code, hasUserGesture=false) ->
|
||||
if @getUrl() and not @isLoading()
|
||||
if @getURL() and not @isLoading()
|
||||
@_executeJavaScript code, hasUserGesture
|
||||
else
|
||||
webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code, hasUserGesture)
|
||||
@@ -59,11 +59,20 @@ wrapWebContents = (webContents) ->
|
||||
# Dispatch IPC messages to the ipc module.
|
||||
webContents.on 'ipc-message', (event, packed) ->
|
||||
[channel, args...] = packed
|
||||
ipc.emit channel, event, args...
|
||||
ipcMain.emit channel, event, args...
|
||||
webContents.on 'ipc-message-sync', (event, packed) ->
|
||||
[channel, args...] = packed
|
||||
Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value)
|
||||
ipc.emit channel, event, args...
|
||||
ipcMain.emit channel, event, args...
|
||||
|
||||
# Handle context menu action request from pepper plugin.
|
||||
webContents.on 'pepper-context-menu', (event, params) ->
|
||||
menu = Menu.buildFromTemplate params.menu
|
||||
menu.popup params.x, params.y
|
||||
|
||||
# Deprecated.
|
||||
deprecate.rename webContents, 'loadUrl', 'loadURL'
|
||||
deprecate.rename webContents, 'getUrl', 'getURL'
|
||||
|
||||
webContents.printToPDF = (options, callback) ->
|
||||
printingSetting =
|
||||
@@ -106,7 +115,6 @@ wrapWebContents = (webContents) ->
|
||||
@_printToPDF printingSetting, callback
|
||||
|
||||
binding._setWrapWebContents wrapWebContents
|
||||
process.once 'exit', binding._clearWrapWebContents
|
||||
|
||||
module.exports.create = (options={}) ->
|
||||
binding.create(options)
|
||||
|
||||
83
atom/browser/api/save_page_handler.cc
Normal file
83
atom/browser/api/save_page_handler.cc
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright (c) 2015 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/save_page_handler.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
SavePageHandler::SavePageHandler(content::WebContents* web_contents,
|
||||
const SavePageCallback& callback)
|
||||
: web_contents_(web_contents),
|
||||
callback_(callback) {
|
||||
}
|
||||
|
||||
SavePageHandler::~SavePageHandler() {
|
||||
}
|
||||
|
||||
void SavePageHandler::OnDownloadCreated(content::DownloadManager* manager,
|
||||
content::DownloadItem* item) {
|
||||
// OnDownloadCreated is invoked during WebContents::SavePage, so the |item|
|
||||
// here is the one stated by WebContents::SavePage.
|
||||
item->AddObserver(this);
|
||||
}
|
||||
|
||||
bool SavePageHandler::Handle(const base::FilePath& full_path,
|
||||
const content::SavePageType& save_type) {
|
||||
auto download_manager = content::BrowserContext::GetDownloadManager(
|
||||
web_contents_->GetBrowserContext());
|
||||
download_manager->AddObserver(this);
|
||||
// Chromium will create a 'foo_files' directory under the directory of saving
|
||||
// page 'foo.html' for holding other resource files of 'foo.html'.
|
||||
base::FilePath saved_main_directory_path = full_path.DirName().Append(
|
||||
full_path.RemoveExtension().BaseName().value() +
|
||||
FILE_PATH_LITERAL("_files"));
|
||||
bool result = web_contents_->SavePage(full_path,
|
||||
saved_main_directory_path,
|
||||
save_type);
|
||||
download_manager->RemoveObserver(this);
|
||||
// If initialization fails which means fail to create |DownloadItem|, we need
|
||||
// to delete the |SavePageHandler| instance to avoid memory-leak.
|
||||
if (!result)
|
||||
delete this;
|
||||
return result;
|
||||
}
|
||||
|
||||
void SavePageHandler::OnDownloadUpdated(content::DownloadItem* item) {
|
||||
if (item->IsDone()) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
if (item->GetState() == content::DownloadItem::COMPLETE) {
|
||||
callback_.Run(v8::Null(isolate));
|
||||
} else {
|
||||
v8::Local<v8::String> error_message = v8::String::NewFromUtf8(
|
||||
isolate, "Fail to save page");
|
||||
callback_.Run(v8::Exception::Error(error_message));
|
||||
}
|
||||
Destroy(item);
|
||||
}
|
||||
}
|
||||
|
||||
void SavePageHandler::Destroy(content::DownloadItem* item) {
|
||||
item->RemoveObserver(this);
|
||||
delete this;
|
||||
}
|
||||
|
||||
// static
|
||||
bool SavePageHandler::IsSavePageTypes(const std::string& type) {
|
||||
return type == "multipart/related" || type == "text/html";
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
60
atom/browser/api/save_page_handler.h
Normal file
60
atom/browser/api/save_page_handler.h
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2015 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_SAVE_PAGE_HANDLER_H_
|
||||
#define ATOM_BROWSER_API_SAVE_PAGE_HANDLER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "content/public/browser/download_item.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
#include "content/public/browser/save_page_type.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace content {
|
||||
class WebContents;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
// A self-destroyed class for handling save page request.
|
||||
class SavePageHandler : public content::DownloadManager::Observer,
|
||||
public content::DownloadItem::Observer {
|
||||
public:
|
||||
using SavePageCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
|
||||
SavePageHandler(content::WebContents* web_contents,
|
||||
const SavePageCallback& callback);
|
||||
~SavePageHandler();
|
||||
|
||||
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);
|
||||
|
||||
// content::DownloadManager::Observer:
|
||||
void OnDownloadCreated(content::DownloadManager* manager,
|
||||
content::DownloadItem* item) override;
|
||||
|
||||
// content::DownloadItem::Observer:
|
||||
void OnDownloadUpdated(content::DownloadItem* item) override;
|
||||
|
||||
content::WebContents* web_contents_; // weak
|
||||
SavePageCallback callback_;
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_SAVE_PAGE_HANDLER_H_
|
||||
@@ -18,7 +18,7 @@ namespace {
|
||||
// Notice that we just combined the api key with the url together here, because
|
||||
// if we use the standard {url: key} format Chromium would override our key with
|
||||
// the predefined one in common.gypi of libchromiumcontent, which is empty.
|
||||
const char* kGeolocationProviderUrl =
|
||||
const char* kGeolocationProviderURL =
|
||||
"https://www.googleapis.com/geolocation/v1/geolocate?key="
|
||||
GOOGLEAPIS_API_KEY;
|
||||
|
||||
@@ -35,11 +35,11 @@ void AtomAccessTokenStore::LoadAccessTokens(
|
||||
const LoadAccessTokensCallbackType& callback) {
|
||||
AccessTokenSet access_token_set;
|
||||
|
||||
// Equivelent to access_token_set[kGeolocationProviderUrl].
|
||||
// Equivelent to access_token_set[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);
|
||||
token_pair.first = GURL(kGeolocationProviderURL);
|
||||
access_token_set.insert(token_pair);
|
||||
|
||||
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "atom/browser/atom_quota_permission_context.h"
|
||||
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
|
||||
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
@@ -88,7 +87,7 @@ void AtomBrowserClient::SetCustomSchemes(
|
||||
g_custom_schemes = JoinString(schemes, ',');
|
||||
}
|
||||
|
||||
AtomBrowserClient::AtomBrowserClient() {
|
||||
AtomBrowserClient::AtomBrowserClient() : delegate_(nullptr) {
|
||||
}
|
||||
|
||||
AtomBrowserClient::~AtomBrowserClient() {
|
||||
@@ -208,6 +207,26 @@ content::QuotaPermissionContext*
|
||||
return new AtomQuotaPermissionContext;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::AllowCertificateError(
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
int cert_error,
|
||||
const net::SSLInfo& ssl_info,
|
||||
const GURL& request_url,
|
||||
content::ResourceType resource_type,
|
||||
bool overridable,
|
||||
bool strict_enforcement,
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(bool)>& callback,
|
||||
content::CertificateRequestResultType* request) {
|
||||
if (delegate_) {
|
||||
delegate_->AllowCertificateError(
|
||||
render_process_id, render_frame_id, cert_error, ssl_info, request_url,
|
||||
resource_type, overridable, strict_enforcement,
|
||||
expired_previous_decision, callback, request);
|
||||
}
|
||||
}
|
||||
|
||||
void AtomBrowserClient::SelectClientCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
@@ -222,10 +241,10 @@ void AtomBrowserClient::SelectClientCertificate(
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cert_request_info->client_certs.empty())
|
||||
Browser::Get()->ClientCertificateSelector(web_contents,
|
||||
cert_request_info,
|
||||
delegate.Pass());
|
||||
if (!cert_request_info->client_certs.empty() && delegate_) {
|
||||
delegate_->SelectClientCertificate(
|
||||
web_contents, cert_request_info, delegate.Pass());
|
||||
}
|
||||
}
|
||||
|
||||
void AtomBrowserClient::ResourceDispatcherHostCreated() {
|
||||
|
||||
@@ -31,6 +31,9 @@ class AtomBrowserClient : public brightray::BrowserClient,
|
||||
AtomBrowserClient();
|
||||
virtual ~AtomBrowserClient();
|
||||
|
||||
using Delegate = content::ContentBrowserClient;
|
||||
void set_delegate(Delegate* delegate) { delegate_ = delegate; }
|
||||
|
||||
// Don't force renderer process to restart for once.
|
||||
static void SuppressRendererProcessRestartForOnce();
|
||||
// Custom schemes to be registered to standard.
|
||||
@@ -54,6 +57,18 @@ class AtomBrowserClient : public brightray::BrowserClient,
|
||||
int child_process_id) override;
|
||||
void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override;
|
||||
content::QuotaPermissionContext* CreateQuotaPermissionContext() override;
|
||||
void AllowCertificateError(
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
int cert_error,
|
||||
const net::SSLInfo& ssl_info,
|
||||
const GURL& request_url,
|
||||
content::ResourceType resource_type,
|
||||
bool overridable,
|
||||
bool strict_enforcement,
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(bool)>& callback,
|
||||
content::CertificateRequestResultType* request) override;
|
||||
void SelectClientCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
@@ -74,6 +89,8 @@ class AtomBrowserClient : public brightray::BrowserClient,
|
||||
scoped_ptr<AtomResourceDispatcherHostDelegate>
|
||||
resource_dispatcher_host_delegate_;
|
||||
|
||||
Delegate* delegate_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
|
||||
};
|
||||
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_download_manager_delegate.h"
|
||||
#include "atom/browser/atom_ssl_config_service.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/net/atom_cert_verifier.h"
|
||||
#include "atom/browser/net/atom_ssl_config_service.h"
|
||||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
#include "atom/browser/net/asar/asar_protocol_handler.h"
|
||||
#include "atom/browser/net/http_protocol_handler.h"
|
||||
@@ -60,7 +61,9 @@ std::string RemoveWhitespace(const std::string& str) {
|
||||
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||
bool in_memory)
|
||||
: brightray::BrowserContext(partition, in_memory),
|
||||
job_factory_(new AtomURLRequestJobFactory) {
|
||||
cert_verifier_(new AtomCertVerifier),
|
||||
job_factory_(new AtomURLRequestJobFactory),
|
||||
allow_ntlm_everywhere_(false) {
|
||||
}
|
||||
|
||||
AtomBrowserContext::~AtomBrowserContext() {
|
||||
@@ -157,6 +160,10 @@ content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() {
|
||||
return guest_manager_.get();
|
||||
}
|
||||
|
||||
net::CertVerifier* AtomBrowserContext::CreateCertVerifier() {
|
||||
return cert_verifier_;
|
||||
}
|
||||
|
||||
net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() {
|
||||
return new AtomSSLConfigService;
|
||||
}
|
||||
@@ -168,6 +175,16 @@ void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
|
||||
base::FilePath());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace brightray {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace atom {
|
||||
|
||||
class AtomDownloadManagerDelegate;
|
||||
class AtomCertVerifier;
|
||||
class AtomURLRequestJobFactory;
|
||||
class WebViewManager;
|
||||
|
||||
@@ -27,7 +28,9 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
content::URLRequestInterceptorScopedVector* interceptors) override;
|
||||
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path) override;
|
||||
net::CertVerifier* CreateCertVerifier() override;
|
||||
net::SSLConfigService* CreateSSLConfigService() override;
|
||||
bool AllowNTLMCredentialsForDomain(const GURL& auth_origin) override;
|
||||
|
||||
// content::BrowserContext:
|
||||
content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
|
||||
@@ -36,6 +39,10 @@ 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_; }
|
||||
|
||||
private:
|
||||
@@ -43,8 +50,11 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
scoped_ptr<WebViewManager> guest_manager_;
|
||||
|
||||
// Managed by brightray::BrowserContext.
|
||||
AtomCertVerifier* cert_verifier_;
|
||||
AtomURLRequestJobFactory* job_factory_;
|
||||
|
||||
bool allow_ntlm_everywhere_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
|
||||
};
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL;
|
||||
|
||||
AtomBrowserMainParts::AtomBrowserMainParts()
|
||||
: fake_browser_process_(new BrowserProcess),
|
||||
exit_code_(nullptr),
|
||||
browser_(new Browser),
|
||||
node_bindings_(NodeBindings::Create(true)),
|
||||
atom_bindings_(new AtomBindings),
|
||||
@@ -47,6 +48,14 @@ AtomBrowserMainParts* AtomBrowserMainParts::Get() {
|
||||
return self_;
|
||||
}
|
||||
|
||||
bool AtomBrowserMainParts::SetExitCode(int code) {
|
||||
if (!exit_code_)
|
||||
return false;
|
||||
|
||||
*exit_code_ = code;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::RegisterDestructionCallback(
|
||||
const base::Closure& callback) {
|
||||
destruction_callbacks_.push_back(callback);
|
||||
@@ -62,17 +71,15 @@ void AtomBrowserMainParts::PreEarlyInitialization() {
|
||||
void AtomBrowserMainParts::PostEarlyInitialization() {
|
||||
brightray::BrowserMainParts::PostEarlyInitialization();
|
||||
|
||||
{
|
||||
// Temporary set the bridge_task_runner_ as current thread's task runner,
|
||||
// so we can fool gin::PerIsolateData to use it as its task runner, instead
|
||||
// of getting current message loop's task runner, which is null for now.
|
||||
bridge_task_runner_ = new BridgeTaskRunner;
|
||||
base::ThreadTaskRunnerHandle handle(bridge_task_runner_);
|
||||
// Temporary set the bridge_task_runner_ as current thread's task runner,
|
||||
// so we can fool gin::PerIsolateData to use it as its task runner, instead
|
||||
// of getting current message loop's task runner, which is null for now.
|
||||
bridge_task_runner_ = new BridgeTaskRunner;
|
||||
base::ThreadTaskRunnerHandle handle(bridge_task_runner_);
|
||||
|
||||
// The ProxyResolverV8 has setup a complete V8 environment, in order to
|
||||
// avoid conflicts we only initialize our V8 environment after that.
|
||||
js_env_.reset(new JavascriptEnvironment);
|
||||
}
|
||||
// The ProxyResolverV8 has setup a complete V8 environment, in order to
|
||||
// avoid conflicts we only initialize our V8 environment after that.
|
||||
js_env_.reset(new JavascriptEnvironment);
|
||||
|
||||
node_bindings_->Initialize();
|
||||
|
||||
@@ -107,6 +114,7 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
||||
1000));
|
||||
|
||||
brightray::BrowserMainParts::PreMainMessageLoopRun();
|
||||
BridgeTaskRunner::MessageLoopIsReady();
|
||||
|
||||
#if defined(USE_X11)
|
||||
libgtk2ui::GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());
|
||||
@@ -119,6 +127,11 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool AtomBrowserMainParts::MainMessageLoopRun(int* result_code) {
|
||||
exit_code_ = result_code;
|
||||
return brightray::BrowserMainParts::MainMessageLoopRun(result_code);
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PostMainMessageLoopStart() {
|
||||
brightray::BrowserMainParts::PostMainMessageLoopStart();
|
||||
#if defined(OS_POSIX)
|
||||
@@ -129,11 +142,23 @@ void AtomBrowserMainParts::PostMainMessageLoopStart() {
|
||||
void AtomBrowserMainParts::PostMainMessageLoopRun() {
|
||||
brightray::BrowserMainParts::PostMainMessageLoopRun();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
FreeAppDelegate();
|
||||
#endif
|
||||
|
||||
// Make sure destruction callbacks are called before message loop is
|
||||
// destroyed, otherwise some objects that need to be deleted on IO thread
|
||||
// won't be freed.
|
||||
for (const auto& callback : destruction_callbacks_)
|
||||
callback.Run();
|
||||
|
||||
// Destroy JavaScript environment immediately after running destruction
|
||||
// callbacks.
|
||||
gc_timer_.Stop();
|
||||
node_debugger_.reset();
|
||||
atom_bindings_.reset();
|
||||
node_bindings_.reset();
|
||||
js_env_.reset();
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -31,6 +31,9 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||
|
||||
static AtomBrowserMainParts* Get();
|
||||
|
||||
// Sets the exit code, will fail if the the message loop is not ready.
|
||||
bool SetExitCode(int code);
|
||||
|
||||
// Register a callback that should be destroyed before JavaScript environment
|
||||
// gets destroyed.
|
||||
void RegisterDestructionCallback(const base::Closure& callback);
|
||||
@@ -42,11 +45,11 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||
void PreEarlyInitialization() override;
|
||||
void PostEarlyInitialization() override;
|
||||
void PreMainMessageLoopRun() override;
|
||||
bool MainMessageLoopRun(int* result_code) override;
|
||||
void PostMainMessageLoopStart() override;
|
||||
void PostMainMessageLoopRun() override;
|
||||
#if defined(OS_MACOSX)
|
||||
void PreMainMessageLoopStart() override;
|
||||
void PostDestroyThreads() override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
@@ -56,6 +59,10 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||
void HandleShutdownSignals();
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void FreeAppDelegate();
|
||||
#endif
|
||||
|
||||
// A fake BrowserProcess object that used to feed the source code from chrome.
|
||||
scoped_ptr<BrowserProcess> fake_browser_process_;
|
||||
|
||||
@@ -63,6 +70,9 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||
// with a task runner that will post all work to main loop.
|
||||
scoped_refptr<BridgeTaskRunner> bridge_task_runner_;
|
||||
|
||||
// Pointer to exit code.
|
||||
int* exit_code_;
|
||||
|
||||
scoped_ptr<Browser> browser_;
|
||||
scoped_ptr<JavascriptEnvironment> js_env_;
|
||||
scoped_ptr<NodeBindings> node_bindings_;
|
||||
|
||||
@@ -34,7 +34,7 @@ void AtomBrowserMainParts::PreMainMessageLoopStart() {
|
||||
setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PostDestroyThreads() {
|
||||
void AtomBrowserMainParts::FreeAppDelegate() {
|
||||
[[NSApp delegate] release];
|
||||
[NSApp setDelegate:nil];
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
|
||||
|
||||
#include "atom/browser/login_handler.h"
|
||||
#include "atom/common/platform_util.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "net/base/escape.h"
|
||||
@@ -29,4 +30,11 @@ bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol(
|
||||
return true;
|
||||
}
|
||||
|
||||
content::ResourceDispatcherHostLoginDelegate*
|
||||
AtomResourceDispatcherHostDelegate::CreateLoginDelegate(
|
||||
net::AuthChallengeInfo* auth_info,
|
||||
net::URLRequest* request) {
|
||||
return new LoginHandler(auth_info, request);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -21,6 +21,9 @@ class AtomResourceDispatcherHostDelegate
|
||||
bool is_main_frame,
|
||||
ui::PageTransition transition,
|
||||
bool has_user_gesture) override;
|
||||
content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
|
||||
net::AuthChallengeInfo* auth_info,
|
||||
net::URLRequest* request) override;
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -6,14 +6,25 @@
|
||||
|
||||
namespace auto_updater {
|
||||
|
||||
AutoUpdaterDelegate* AutoUpdater::delegate_ = NULL;
|
||||
Delegate* AutoUpdater::delegate_ = nullptr;
|
||||
|
||||
AutoUpdaterDelegate* AutoUpdater::GetDelegate() {
|
||||
Delegate* AutoUpdater::GetDelegate() {
|
||||
return delegate_;
|
||||
}
|
||||
|
||||
void AutoUpdater::SetDelegate(AutoUpdaterDelegate* delegate) {
|
||||
void AutoUpdater::SetDelegate(Delegate* delegate) {
|
||||
delegate_ = delegate;
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX) || defined(MAS_BUILD)
|
||||
void AutoUpdater::SetFeedURL(const std::string& url) {
|
||||
}
|
||||
|
||||
void AutoUpdater::CheckForUpdates() {
|
||||
}
|
||||
|
||||
void AutoUpdater::QuitAndInstall() {
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace auto_updater
|
||||
|
||||
@@ -9,21 +9,48 @@
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
namespace base {
|
||||
class Time;
|
||||
}
|
||||
|
||||
namespace auto_updater {
|
||||
|
||||
class AutoUpdaterDelegate;
|
||||
class Delegate {
|
||||
public:
|
||||
// An error happened.
|
||||
virtual void OnError(const std::string& error) {}
|
||||
|
||||
// Checking to see if there is an update
|
||||
virtual void OnCheckingForUpdate() {}
|
||||
|
||||
// There is an update available and it is being downloaded
|
||||
virtual void OnUpdateAvailable() {}
|
||||
|
||||
// There is no available update.
|
||||
virtual void OnUpdateNotAvailable() {}
|
||||
|
||||
// There is a new update which has been downloaded.
|
||||
virtual void OnUpdateDownloaded(const std::string& release_notes,
|
||||
const std::string& release_name,
|
||||
const base::Time& release_date,
|
||||
const std::string& update_url) {}
|
||||
|
||||
protected:
|
||||
virtual ~Delegate() {}
|
||||
};
|
||||
|
||||
class AutoUpdater {
|
||||
public:
|
||||
// Gets/Sets the delegate.
|
||||
static AutoUpdaterDelegate* GetDelegate();
|
||||
static void SetDelegate(AutoUpdaterDelegate* delegate);
|
||||
static Delegate* GetDelegate();
|
||||
static void SetDelegate(Delegate* delegate);
|
||||
|
||||
static void SetFeedURL(const std::string& url);
|
||||
static void CheckForUpdates();
|
||||
static void QuitAndInstall();
|
||||
|
||||
private:
|
||||
static AutoUpdaterDelegate* delegate_;
|
||||
static Delegate* delegate_;
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(AutoUpdater);
|
||||
};
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_AUTO_UPDATER_DELEGATE_H_
|
||||
#define ATOM_BROWSER_AUTO_UPDATER_DELEGATE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/callback_forward.h"
|
||||
|
||||
namespace base {
|
||||
class Time;
|
||||
}
|
||||
|
||||
namespace auto_updater {
|
||||
|
||||
class AutoUpdaterDelegate {
|
||||
public:
|
||||
// An error happened.
|
||||
virtual void OnError(const std::string& error) {}
|
||||
|
||||
// Checking to see if there is an update
|
||||
virtual void OnCheckingForUpdate() {}
|
||||
|
||||
// There is an update available and it is being downloaded
|
||||
virtual void OnUpdateAvailable() {}
|
||||
|
||||
// There is no available update.
|
||||
virtual void OnUpdateNotAvailable() {}
|
||||
|
||||
// There is a new update which has been downloaded.
|
||||
virtual void OnUpdateDownloaded(const std::string& release_notes,
|
||||
const std::string& release_name,
|
||||
const base::Time& release_date,
|
||||
const std::string& update_url,
|
||||
const base::Closure& quit_and_install) {}
|
||||
|
||||
protected:
|
||||
virtual ~AutoUpdaterDelegate() {}
|
||||
};
|
||||
|
||||
} // namespace auto_updater
|
||||
|
||||
#endif // ATOM_BROWSER_AUTO_UPDATER_DELEGATE_H_
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/auto_updater.h"
|
||||
|
||||
namespace auto_updater {
|
||||
|
||||
// static
|
||||
void AutoUpdater::SetFeedURL(const std::string& url) {
|
||||
}
|
||||
|
||||
// static
|
||||
void AutoUpdater::CheckForUpdates() {
|
||||
}
|
||||
|
||||
} // namespace auto_updater
|
||||
@@ -12,9 +12,6 @@
|
||||
#include "base/bind.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "atom/browser/auto_updater_delegate.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace auto_updater {
|
||||
|
||||
@@ -23,20 +20,12 @@ namespace {
|
||||
// The gloal SQRLUpdater object.
|
||||
SQRLUpdater* g_updater = nil;
|
||||
|
||||
void RelaunchToInstallUpdate() {
|
||||
[[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) {
|
||||
AutoUpdaterDelegate* delegate = AutoUpdater::GetDelegate();
|
||||
if (delegate)
|
||||
delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription));
|
||||
}];
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
void AutoUpdater::SetFeedURL(const std::string& feed) {
|
||||
if (g_updater == nil) {
|
||||
AutoUpdaterDelegate* delegate = GetDelegate();
|
||||
Delegate* delegate = GetDelegate();
|
||||
if (!delegate)
|
||||
return;
|
||||
|
||||
@@ -67,7 +56,7 @@ void AutoUpdater::SetFeedURL(const std::string& feed) {
|
||||
|
||||
// static
|
||||
void AutoUpdater::CheckForUpdates() {
|
||||
AutoUpdaterDelegate* delegate = GetDelegate();
|
||||
Delegate* delegate = GetDelegate();
|
||||
if (!delegate)
|
||||
return;
|
||||
|
||||
@@ -86,8 +75,7 @@ void AutoUpdater::CheckForUpdates() {
|
||||
base::SysNSStringToUTF8(update.releaseNotes),
|
||||
base::SysNSStringToUTF8(update.releaseName),
|
||||
base::Time::FromDoubleT(update.releaseDate.timeIntervalSince1970),
|
||||
base::SysNSStringToUTF8(update.updateURL.absoluteString),
|
||||
base::Bind(RelaunchToInstallUpdate));
|
||||
base::SysNSStringToUTF8(update.updateURL.absoluteString));
|
||||
} else {
|
||||
// When the completed event is sent with no update, then we know there
|
||||
// is no update available.
|
||||
@@ -100,4 +88,12 @@ void AutoUpdater::CheckForUpdates() {
|
||||
}];
|
||||
}
|
||||
|
||||
void AutoUpdater::QuitAndInstall() {
|
||||
[[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) {
|
||||
Delegate* delegate = AutoUpdater::GetDelegate();
|
||||
if (delegate)
|
||||
delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription));
|
||||
}];
|
||||
}
|
||||
|
||||
} // namespace auto_updater
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/auto_updater.h"
|
||||
|
||||
namespace auto_updater {
|
||||
|
||||
// static
|
||||
void AutoUpdater::SetFeedURL(const std::string& url) {
|
||||
}
|
||||
|
||||
// static
|
||||
void AutoUpdater::CheckForUpdates() {
|
||||
}
|
||||
|
||||
} // namespace auto_updater
|
||||
@@ -8,13 +8,33 @@
|
||||
|
||||
namespace atom {
|
||||
|
||||
// static
|
||||
std::vector<BridgeTaskRunner::TaskPair> BridgeTaskRunner::tasks_;
|
||||
std::vector<BridgeTaskRunner::TaskPair> BridgeTaskRunner::non_nestable_tasks_;
|
||||
|
||||
// static
|
||||
void BridgeTaskRunner::MessageLoopIsReady() {
|
||||
auto message_loop = base::MessageLoop::current();
|
||||
CHECK(message_loop);
|
||||
for (const TaskPair& task : tasks_) {
|
||||
message_loop->task_runner()->PostDelayedTask(
|
||||
base::get<0>(task), base::get<1>(task), base::get<2>(task));
|
||||
}
|
||||
for (const TaskPair& task : non_nestable_tasks_) {
|
||||
message_loop->task_runner()->PostNonNestableDelayedTask(
|
||||
base::get<0>(task), base::get<1>(task), base::get<2>(task));
|
||||
}
|
||||
}
|
||||
|
||||
bool BridgeTaskRunner::PostDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) {
|
||||
auto message_loop = base::MessageLoop::current();
|
||||
if (!message_loop)
|
||||
return false;
|
||||
if (!message_loop) {
|
||||
tasks_.push_back(base::MakeTuple(from_here, task, delay));
|
||||
return true;
|
||||
}
|
||||
|
||||
return message_loop->task_runner()->PostDelayedTask(from_here, task, delay);
|
||||
}
|
||||
@@ -22,7 +42,7 @@ bool BridgeTaskRunner::PostDelayedTask(
|
||||
bool BridgeTaskRunner::RunsTasksOnCurrentThread() const {
|
||||
auto message_loop = base::MessageLoop::current();
|
||||
if (!message_loop)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
return message_loop->task_runner()->RunsTasksOnCurrentThread();
|
||||
}
|
||||
@@ -32,8 +52,10 @@ bool BridgeTaskRunner::PostNonNestableDelayedTask(
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) {
|
||||
auto message_loop = base::MessageLoop::current();
|
||||
if (!message_loop)
|
||||
return false;
|
||||
if (!message_loop) {
|
||||
non_nestable_tasks_.push_back(base::MakeTuple(from_here, task, delay));
|
||||
return true;
|
||||
}
|
||||
|
||||
return message_loop->task_runner()->PostNonNestableDelayedTask(
|
||||
from_here, task, delay);
|
||||
|
||||
@@ -5,17 +5,23 @@
|
||||
#ifndef ATOM_BROWSER_BRIDGE_TASK_RUNNER_H_
|
||||
#define ATOM_BROWSER_BRIDGE_TASK_RUNNER_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/single_thread_task_runner.h"
|
||||
#include "base/tuple.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
// Post all tasks to the current message loop's task runner if available,
|
||||
// otherwise fail silently.
|
||||
// otherwise delay the work until message loop is ready.
|
||||
class BridgeTaskRunner : public base::SingleThreadTaskRunner {
|
||||
public:
|
||||
BridgeTaskRunner() {}
|
||||
~BridgeTaskRunner() override {}
|
||||
|
||||
// Called when message loop is ready.
|
||||
static void MessageLoopIsReady();
|
||||
|
||||
// base::SingleThreadTaskRunner:
|
||||
bool PostDelayedTask(const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
@@ -27,6 +33,11 @@ class BridgeTaskRunner : public base::SingleThreadTaskRunner {
|
||||
base::TimeDelta delay) override;
|
||||
|
||||
private:
|
||||
using TaskPair = base::Tuple<
|
||||
tracked_objects::Location, base::Closure, base::TimeDelta>;
|
||||
static std::vector<TaskPair> tasks_;
|
||||
static std::vector<TaskPair> non_nestable_tasks_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BridgeTaskRunner);
|
||||
};
|
||||
|
||||
|
||||
@@ -7,10 +7,9 @@
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "content/public/browser/client_certificate_delegate.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -45,6 +44,27 @@ void Browser::Quit() {
|
||||
window_list->CloseAllWindows();
|
||||
}
|
||||
|
||||
void Browser::Exit(int code) {
|
||||
if (!AtomBrowserMainParts::Get()->SetExitCode(code)) {
|
||||
// Message loop is not ready, quit directly.
|
||||
exit(code);
|
||||
} else {
|
||||
// Prepare to quit when all windows have been closed..
|
||||
is_quiting_ = true;
|
||||
|
||||
// Must destroy windows before quitting, otherwise bad things can happen.
|
||||
atom::WindowList* window_list = atom::WindowList::GetInstance();
|
||||
if (window_list->size() == 0) {
|
||||
NotifyAndShutdown();
|
||||
} else {
|
||||
// Unlike Quit(), we do not ask to close window, but destroy the window
|
||||
// without asking.
|
||||
for (NativeWindow* window : *window_list)
|
||||
window->CloseContents(nullptr); // e.g. Destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Browser::Shutdown() {
|
||||
if (is_shutdown_)
|
||||
return;
|
||||
@@ -53,8 +73,14 @@ void Browser::Shutdown() {
|
||||
is_quiting_ = true;
|
||||
|
||||
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnQuit());
|
||||
base::MessageLoop::current()->PostTask(
|
||||
FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
|
||||
|
||||
if (base::MessageLoop::current()) {
|
||||
base::MessageLoop::current()->PostTask(
|
||||
FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
|
||||
} else {
|
||||
// There is no message loop available so we are in early stage.
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Browser::GetVersion() const {
|
||||
@@ -83,10 +109,6 @@ std::string Browser::GetName() const {
|
||||
|
||||
void Browser::SetName(const std::string& name) {
|
||||
name_override_ = name;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
SetAppUserModelID(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Browser::OpenFile(const std::string& file_path) {
|
||||
@@ -117,15 +139,8 @@ void Browser::DidFinishLaunching() {
|
||||
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching());
|
||||
}
|
||||
|
||||
void Browser::ClientCertificateSelector(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
scoped_ptr<content::ClientCertificateDelegate> delegate) {
|
||||
FOR_EACH_OBSERVER(BrowserObserver,
|
||||
observers_,
|
||||
OnSelectCertificate(web_contents,
|
||||
cert_request_info,
|
||||
delegate.Pass()));
|
||||
void Browser::RequestLogin(LoginHandler* login_handler) {
|
||||
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnLogin(login_handler));
|
||||
}
|
||||
|
||||
void Browser::NotifyAndShutdown() {
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
#include "base/basictypes.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/observer_list.h"
|
||||
#include "base/strings/string16.h"
|
||||
#include "atom/browser/browser_observer.h"
|
||||
#include "atom/browser/window_list_observer.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/strings/string16.h"
|
||||
#endif
|
||||
|
||||
namespace base {
|
||||
@@ -29,6 +29,8 @@ class MenuModel;
|
||||
|
||||
namespace atom {
|
||||
|
||||
class LoginHandler;
|
||||
|
||||
// This class is used for control application-wide operations.
|
||||
class Browser : public WindowListObserver {
|
||||
public:
|
||||
@@ -40,6 +42,9 @@ class Browser : public WindowListObserver {
|
||||
// Try to close all windows and quit the application.
|
||||
void Quit();
|
||||
|
||||
// Exit the application immediately and set exit code.
|
||||
void Exit(int code);
|
||||
|
||||
// Cleanup everything and shutdown the application gracefully.
|
||||
void Shutdown();
|
||||
|
||||
@@ -64,6 +69,9 @@ class Browser : public WindowListObserver {
|
||||
// Clear the recent documents list.
|
||||
void ClearRecentDocuments();
|
||||
|
||||
// Set the application user model ID.
|
||||
void SetAppUserModelID(const base::string16& name);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// Bounce the dock icon.
|
||||
enum BounceType {
|
||||
@@ -98,8 +106,10 @@ class Browser : public WindowListObserver {
|
||||
// Add a custom task to jump list.
|
||||
void SetUserTasks(const std::vector<UserTask>& tasks);
|
||||
|
||||
// Set the application user model ID, called when "SetName" is called.
|
||||
void SetAppUserModelID(const std::string& name);
|
||||
// Returns the application user model ID, if there isn't one, then create
|
||||
// one from app's name.
|
||||
// The returned string managed by Browser, and should not be modified.
|
||||
PCWSTR GetAppUserModelID();
|
||||
#endif
|
||||
|
||||
// Tell the application to open a file.
|
||||
@@ -116,11 +126,8 @@ class Browser : public WindowListObserver {
|
||||
void WillFinishLaunching();
|
||||
void DidFinishLaunching();
|
||||
|
||||
// Called when client certificate is required.
|
||||
void ClientCertificateSelector(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
scoped_ptr<content::ClientCertificateDelegate> delegate);
|
||||
// Request basic auth login.
|
||||
void RequestLogin(LoginHandler* login_handler);
|
||||
|
||||
void AddObserver(BrowserObserver* obs) {
|
||||
observers_.AddObserver(obs);
|
||||
@@ -130,6 +137,7 @@ class Browser : public WindowListObserver {
|
||||
observers_.RemoveObserver(obs);
|
||||
}
|
||||
|
||||
bool is_shutting_down() const { return is_shutdown_; }
|
||||
bool is_quiting() const { return is_quiting_; }
|
||||
bool is_ready() const { return is_ready_; }
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@ void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||
void Browser::ClearRecentDocuments() {
|
||||
}
|
||||
|
||||
void Browser::SetAppUserModelID(const base::string16& name) {
|
||||
}
|
||||
|
||||
std::string Browser::GetExecutableFileVersion() const {
|
||||
return brightray::GetApplicationVersion();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||
void Browser::ClearRecentDocuments() {
|
||||
}
|
||||
|
||||
void Browser::SetAppUserModelID(const base::string16& name) {
|
||||
}
|
||||
|
||||
std::string Browser::GetExecutableFileVersion() const {
|
||||
return brightray::GetApplicationVersion();
|
||||
}
|
||||
|
||||
@@ -7,19 +7,10 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "content/public/browser/client_certificate_delegate.h"
|
||||
|
||||
namespace content {
|
||||
class WebContents;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class SSLCertRequestInfo;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class LoginHandler;
|
||||
|
||||
class BrowserObserver {
|
||||
public:
|
||||
// The browser is about to close all windows.
|
||||
@@ -51,11 +42,8 @@ class BrowserObserver {
|
||||
virtual void OnWillFinishLaunching() {}
|
||||
virtual void OnFinishLaunching() {}
|
||||
|
||||
// The browser requires client certificate.
|
||||
virtual void OnSelectCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
scoped_ptr<content::ClientCertificateDelegate> delegate) {}
|
||||
// The browser requests HTTP login.
|
||||
virtual void OnLogin(LoginHandler* login_handler) {}
|
||||
|
||||
protected:
|
||||
virtual ~BrowserObserver() {}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/win/win_util.h"
|
||||
@@ -25,6 +26,8 @@ namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
const wchar_t kAppUserModelIDFormat[] = L"electron.app.$1";
|
||||
|
||||
BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) {
|
||||
DWORD target_process_id = *reinterpret_cast<DWORD*>(param);
|
||||
DWORD process_id = 0;
|
||||
@@ -56,7 +59,7 @@ void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||
if (SUCCEEDED(hr)) {
|
||||
SHARDAPPIDINFO info;
|
||||
info.psi = item;
|
||||
info.pszAppID = app_user_model_id_.c_str();
|
||||
info.pszAppID = GetAppUserModelID();
|
||||
SHAddToRecentDocs(SHARD_APPIDINFO, &info);
|
||||
}
|
||||
}
|
||||
@@ -66,16 +69,21 @@ void Browser::ClearRecentDocuments() {
|
||||
if (FAILED(destinations.CoCreateInstance(CLSID_ApplicationDestinations,
|
||||
NULL, CLSCTX_INPROC_SERVER)))
|
||||
return;
|
||||
if (FAILED(destinations->SetAppID(app_user_model_id_.c_str())))
|
||||
if (FAILED(destinations->SetAppID(GetAppUserModelID())))
|
||||
return;
|
||||
destinations->RemoveAllDestinations();
|
||||
}
|
||||
|
||||
void Browser::SetAppUserModelID(const base::string16& name) {
|
||||
app_user_model_id_ = name;
|
||||
SetCurrentProcessExplicitAppUserModelID(app_user_model_id_.c_str());
|
||||
}
|
||||
|
||||
void Browser::SetUserTasks(const std::vector<UserTask>& tasks) {
|
||||
CComPtr<ICustomDestinationList> destinations;
|
||||
if (FAILED(destinations.CoCreateInstance(CLSID_DestinationList)))
|
||||
return;
|
||||
if (FAILED(destinations->SetAppID(app_user_model_id_.c_str())))
|
||||
if (FAILED(destinations->SetAppID(GetAppUserModelID())))
|
||||
return;
|
||||
|
||||
// Start a transaction that updates the JumpList of this application.
|
||||
@@ -117,10 +125,13 @@ void Browser::SetUserTasks(const std::vector<UserTask>& tasks) {
|
||||
destinations->CommitList();
|
||||
}
|
||||
|
||||
void Browser::SetAppUserModelID(const std::string& name) {
|
||||
app_user_model_id_ = base::string16(L"electron.app.");
|
||||
app_user_model_id_ += base::UTF8ToUTF16(name);
|
||||
SetCurrentProcessExplicitAppUserModelID(app_user_model_id_.c_str());
|
||||
PCWSTR Browser::GetAppUserModelID() {
|
||||
if (app_user_model_id_.empty()) {
|
||||
SetAppUserModelID(ReplaceStringPlaceholders(
|
||||
kAppUserModelIDFormat, base::UTF8ToUTF16(GetName()), nullptr));
|
||||
}
|
||||
|
||||
return app_user_model_id_.c_str();
|
||||
}
|
||||
|
||||
std::string Browser::GetExecutableFileVersion() const {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
var app = require('app');
|
||||
var BrowserWindow = require('browser-window');
|
||||
const electron = require('electron');
|
||||
const app = electron.app;
|
||||
const BrowserWindow = electron.BrowserWindow;
|
||||
|
||||
var mainWindow = null;
|
||||
|
||||
@@ -12,9 +13,9 @@ app.on('ready', function() {
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
'auto-hide-menu-bar': true,
|
||||
'use-content-size': true,
|
||||
autoHideMenuBar: true,
|
||||
useContentSize: true,
|
||||
});
|
||||
mainWindow.loadUrl('file://' + __dirname + '/index.html');
|
||||
mainWindow.loadURL('file://' + __dirname + '/index.html');
|
||||
mainWindow.focus();
|
||||
});
|
||||
|
||||
@@ -57,13 +57,17 @@
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var execPath = require('remote').process.execPath;
|
||||
const electron = require('electron');
|
||||
const remote = electron.remote;
|
||||
const shell = electron.shell;
|
||||
|
||||
var execPath = remote.process.execPath;
|
||||
var command = execPath + ' path-to-your-app';
|
||||
|
||||
document.onclick = function(e) {
|
||||
e.preventDefault();
|
||||
if (e.target.tagName == 'A')
|
||||
require('shell').openExternal(e.target.href);
|
||||
shell.openExternal(e.target.href);
|
||||
return false;
|
||||
};
|
||||
document.ondragover = document.ondrop = function(e) {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
var app = require('app');
|
||||
var dialog = require('dialog');
|
||||
const electron = require('electron');
|
||||
const app = electron.app;
|
||||
const dialog = electron.dialog;
|
||||
const shell = electron.shell;
|
||||
const Menu = electron.Menu;
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var Menu = require('menu');
|
||||
var BrowserWindow = require('browser-window');
|
||||
|
||||
// Quit when all windows are closed and no other one is listening to this.
|
||||
app.on('window-all-closed', function() {
|
||||
@@ -18,6 +20,9 @@ for (var i = 0; i < argv.length; i++) {
|
||||
if (argv[i] == '--version' || argv[i] == '-v') {
|
||||
option.version = true;
|
||||
break;
|
||||
} else if (argv[i].match(/^--app=/)) {
|
||||
option.file = argv[i].split('=')[1];
|
||||
break;
|
||||
} else if (argv[i] == '--help' || argv[i] == '-h') {
|
||||
option.help = true;
|
||||
break;
|
||||
@@ -139,19 +144,19 @@ app.once('ready', function() {
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click: function() { require('shell').openExternal('http://electron.atom.io') }
|
||||
click: function() { shell.openExternal('http://electron.atom.io') }
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') }
|
||||
click: function() { shell.openExternal('https://github.com/atom/electron/tree/master/docs#readme') }
|
||||
},
|
||||
{
|
||||
label: 'Community Discussions',
|
||||
click: function() { require('shell').openExternal('https://discuss.atom.io/c/electron') }
|
||||
click: function() { shell.openExternal('https://discuss.atom.io/c/electron') }
|
||||
},
|
||||
{
|
||||
label: 'Search Issues',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') }
|
||||
click: function() { shell.openExternal('https://github.com/atom/electron/issues') }
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -260,11 +265,11 @@ if (option.file && !option.webdriver) {
|
||||
helpMessage += "A path to an Electron application may be specified. The path must be to \n";
|
||||
helpMessage += "an index.js file or to a folder containing a package.json or index.js file.\n\n";
|
||||
helpMessage += "Options:\n";
|
||||
helpMessage += " -r, --require Module to preload (option can be repeated)";
|
||||
helpMessage += " -r, --require Module to preload (option can be repeated)\n";
|
||||
helpMessage += " -h, --help Print this usage message.\n";
|
||||
helpMessage += " -v, --version Print the version.";
|
||||
console.log(helpMessage);
|
||||
process.exit(0);
|
||||
} else {
|
||||
require('./default_app.js');
|
||||
require('./default_app');
|
||||
}
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
|
||||
#include "atom/browser/javascript_environment.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "gin/array_buffer.h"
|
||||
#include "gin/v8_initializer.h"
|
||||
|
||||
@@ -20,7 +24,18 @@ JavascriptEnvironment::JavascriptEnvironment()
|
||||
}
|
||||
|
||||
bool JavascriptEnvironment::Initialize() {
|
||||
gin::V8Initializer::LoadV8Snapshot();
|
||||
auto cmd = base::CommandLine::ForCurrentProcess();
|
||||
if (cmd->HasSwitch("debug-brk")) {
|
||||
// Need to be called before v8::Initialize().
|
||||
const char expose_debug_as[] = "--expose_debug_as=v8debug";
|
||||
v8::V8::SetFlagsFromString(expose_debug_as, sizeof(expose_debug_as) - 1);
|
||||
}
|
||||
|
||||
// --js-flags.
|
||||
std::string js_flags = cmd->GetSwitchValueASCII(switches::kJavaScriptFlags);
|
||||
if (!js_flags.empty())
|
||||
v8::V8::SetFlagsFromString(js_flags.c_str(), js_flags.size());
|
||||
|
||||
gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
|
||||
gin::ArrayBufferAllocator::SharedInstance());
|
||||
return true;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
app = require 'app'
|
||||
electron = require 'electron'
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
url = require 'url'
|
||||
@@ -40,6 +40,7 @@ loadedExtensions = null
|
||||
loadedExtensionsPath = null
|
||||
|
||||
# Persistent loaded extensions.
|
||||
{app} = electron
|
||||
app.on 'will-quit', ->
|
||||
try
|
||||
loadedExtensions = Object.keys(extensionInfoMap).map (key) -> extensionInfoMap[key].srcDirectory
|
||||
@@ -51,11 +52,10 @@ app.on 'will-quit', ->
|
||||
|
||||
# We can not use protocol or BrowserWindow until app is ready.
|
||||
app.once 'ready', ->
|
||||
protocol = require 'protocol'
|
||||
BrowserWindow = require 'browser-window'
|
||||
{protocol, BrowserWindow} = electron
|
||||
|
||||
# Load persistented extensions.
|
||||
loadedExtensionsPath = path.join app.getDataPath(), 'DevTools Extensions'
|
||||
loadedExtensionsPath = path.join app.getPath('userData'), 'DevTools Extensions'
|
||||
|
||||
try
|
||||
loadedExtensions = JSON.parse fs.readFileSync(loadedExtensionsPath)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
ipc = require 'ipc'
|
||||
webContents = require 'web-contents'
|
||||
{ipcMain, webContents} = require 'electron'
|
||||
|
||||
webViewManager = null # Doesn't exist in early initialization.
|
||||
|
||||
supportedWebViewEvents = [
|
||||
@@ -79,7 +79,7 @@ createGuest = (embedder, params) ->
|
||||
opts = {}
|
||||
opts.httpReferrer = params.httpreferrer if params.httpreferrer
|
||||
opts.userAgent = params.useragent if params.useragent
|
||||
@loadUrl params.src, opts
|
||||
@loadURL params.src, opts
|
||||
|
||||
if params.allowtransparency?
|
||||
@setAllowTransparency params.allowtransparency
|
||||
@@ -118,11 +118,11 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) ->
|
||||
destroyGuest embedder, oldGuestInstanceId
|
||||
|
||||
webPreferences =
|
||||
'guest-instance-id': guestInstanceId
|
||||
'node-integration': params.nodeintegration ? false
|
||||
'plugins': params.plugins
|
||||
'web-security': !params.disablewebsecurity
|
||||
webPreferences['preload-url'] = params.preload if params.preload
|
||||
guestInstanceId: guestInstanceId
|
||||
nodeIntegration: params.nodeintegration ? false
|
||||
plugins: params.plugins
|
||||
webSecurity: !params.disablewebsecurity
|
||||
webPreferences.preloadURL = params.preload if params.preload
|
||||
webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest, webPreferences
|
||||
|
||||
guest.attachParams = params
|
||||
@@ -140,19 +140,19 @@ destroyGuest = (embedder, id) ->
|
||||
delete reverseEmbedderElementsMap[id]
|
||||
delete embedderElementsMap[key]
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, params, requestId) ->
|
||||
ipcMain.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, params, requestId) ->
|
||||
event.sender.send "ATOM_SHELL_RESPONSE_#{requestId}", createGuest(event.sender, params)
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId, guestInstanceId, params) ->
|
||||
ipcMain.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId, guestInstanceId, params) ->
|
||||
attachGuest event.sender, elementInstanceId, guestInstanceId, params
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, id) ->
|
||||
ipcMain.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, id) ->
|
||||
destroyGuest event.sender, id
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', (event, id, params) ->
|
||||
ipcMain.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', (event, id, params) ->
|
||||
guestInstances[id]?.guest.setSize params
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', (event, id, allowtransparency) ->
|
||||
ipcMain.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', (event, id, allowtransparency) ->
|
||||
guestInstances[id]?.guest.setAllowTransparency allowtransparency
|
||||
|
||||
# Returns WebContents from its guest id.
|
||||
|
||||
@@ -1,29 +1,37 @@
|
||||
ipc = require 'ipc'
|
||||
{ipcMain, BrowserWindow} = require 'electron'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
BrowserWindow = require 'browser-window'
|
||||
|
||||
frameToGuest = {}
|
||||
|
||||
# Copy attribute of |parent| to |child| if it is not defined in |child|.
|
||||
mergeOptions = (child, parent) ->
|
||||
for own key, value of parent when key not in child
|
||||
if typeof value is 'object'
|
||||
child[key] = mergeOptions {}, value
|
||||
else
|
||||
child[key] = value
|
||||
child
|
||||
|
||||
# Merge |options| with the |embedder|'s window's options.
|
||||
mergeBrowserWindowOptions = (embedder, options) ->
|
||||
if embedder.browserWindowOptions?
|
||||
# Inherit the original options if it is a BrowserWindow.
|
||||
options.__proto__ = embedder.browserWindowOptions
|
||||
mergeOptions options, embedder.browserWindowOptions
|
||||
else
|
||||
# Or only inherit web-preferences if it is a webview.
|
||||
options['web-preferences'] ?= {}
|
||||
options['web-preferences'].__proto__ = embedder.getWebPreferences()
|
||||
options.webPreferences ?= {}
|
||||
mergeOptions options.webPreferences, embedder.getWebPreferences()
|
||||
options
|
||||
|
||||
# Create a new guest created by |embedder| with |options|.
|
||||
createGuest = (embedder, url, frameName, options) ->
|
||||
guest = frameToGuest[frameName]
|
||||
if frameName and guest?
|
||||
guest.loadUrl url
|
||||
guest.loadURL url
|
||||
return guest.id
|
||||
|
||||
guest = new BrowserWindow(options)
|
||||
guest.loadUrl url
|
||||
guest.loadURL url
|
||||
|
||||
# Remember the embedder, will be used by window.opener methods.
|
||||
v8Util.setHiddenValue guest.webContents, 'embedder', embedder
|
||||
@@ -49,7 +57,7 @@ createGuest = (embedder, url, frameName, options) ->
|
||||
guest.id
|
||||
|
||||
# Routed window.open messages.
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, args...) ->
|
||||
ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, args...) ->
|
||||
[url, frameName, options] = args
|
||||
options = mergeBrowserWindowOptions event.sender, options
|
||||
event.sender.emit 'new-window', event, url, frameName, 'new-window', options
|
||||
@@ -58,26 +66,26 @@ ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, args...) ->
|
||||
else
|
||||
event.returnValue = createGuest event.sender, url, frameName, options
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', (event, guestId) ->
|
||||
ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', (event, guestId) ->
|
||||
BrowserWindow.fromId(guestId)?.destroy()
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestId, method, args...) ->
|
||||
ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestId, method, args...) ->
|
||||
BrowserWindow.fromId(guestId)?[method] args...
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestId, message, targetOrigin) ->
|
||||
ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestId, message, targetOrigin) ->
|
||||
guestContents = BrowserWindow.fromId(guestId)?.webContents
|
||||
if guestContents?.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*'
|
||||
guestContents.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', message, targetOrigin
|
||||
if guestContents?.getURL().indexOf(targetOrigin) is 0 or targetOrigin is '*'
|
||||
guestContents.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', guestId, message, targetOrigin
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, guestId, message, targetOrigin, sourceOrigin) ->
|
||||
ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, guestId, message, targetOrigin, sourceOrigin) ->
|
||||
embedder = v8Util.getHiddenValue event.sender, 'embedder'
|
||||
if embedder?.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*'
|
||||
if embedder?.getURL().indexOf(targetOrigin) is 0 or targetOrigin is '*'
|
||||
embedder.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', guestId, message, sourceOrigin
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestId, method, args...) ->
|
||||
ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestId, method, args...) ->
|
||||
BrowserWindow.fromId(guestId)?.webContents?[method] args...
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_GET_GUEST_ID', (event) ->
|
||||
ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_GET_GUEST_ID', (event) ->
|
||||
embedder = v8Util.getHiddenValue event.sender, 'embedder'
|
||||
if embedder?
|
||||
guest = BrowserWindow.fromWebContents event.sender
|
||||
|
||||
@@ -13,18 +13,25 @@ require path.resolve(__dirname, '..', '..', 'common', 'lib', 'reset-search-paths
|
||||
# Import common settings.
|
||||
require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init')
|
||||
|
||||
# Add browser/api/lib to module search paths, which contains javascript part of
|
||||
# Electron's built-in libraries.
|
||||
globalPaths = Module.globalPaths
|
||||
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
|
||||
unless process.env.ELECTRON_HIDE_INTERNAL_MODULES
|
||||
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
|
||||
|
||||
# Expose public APIs.
|
||||
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib', 'exports')
|
||||
|
||||
if process.platform is 'win32'
|
||||
# Redirect node's console to use our own implementations, since node can not
|
||||
# handle console output when running as GUI program.
|
||||
print = (args...) ->
|
||||
process.log util.format(args...)
|
||||
console.log = console.error = console.warn = print
|
||||
process.stdout.write = process.stderr.write = print
|
||||
consoleLog = (args...) ->
|
||||
process.log util.format(args...) + "\n"
|
||||
streamWrite = (chunk, encoding, callback) ->
|
||||
chunk = chunk.toString(encoding) if Buffer.isBuffer chunk
|
||||
process.log chunk
|
||||
callback() if callback
|
||||
true
|
||||
console.log = console.error = console.warn = consoleLog
|
||||
process.stdout.write = process.stderr.write = streamWrite
|
||||
|
||||
# Always returns EOF for stdin stream.
|
||||
Readable = require('stream').Readable
|
||||
@@ -39,15 +46,19 @@ process.on 'uncaughtException', (error) ->
|
||||
return
|
||||
|
||||
# Show error in GUI.
|
||||
{dialog} = require 'electron'
|
||||
stack = error.stack ? "#{error.name}: #{error.message}"
|
||||
message = "Uncaught Exception:\n#{stack}"
|
||||
require('dialog').showErrorBox 'A JavaScript error occurred in the main process', message
|
||||
dialog.showErrorBox 'A JavaScript error occurred in the main process', message
|
||||
|
||||
# Emit 'exit' event on quit.
|
||||
app = require 'app'
|
||||
{app} = require 'electron'
|
||||
app.on 'quit', ->
|
||||
process.emit 'exit'
|
||||
|
||||
# Map process.exit to app.exit, which quits gracefully.
|
||||
process.exit = app.exit
|
||||
|
||||
# Load the RPC server.
|
||||
require './rpc-server'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
{EventEmitter} = require 'events'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
|
||||
class ObjectsRegistry extends EventEmitter
|
||||
@@ -34,6 +34,7 @@ class ObjectsRegistry extends EventEmitter
|
||||
@dereference id, 1
|
||||
# Also reduce the count in owner.
|
||||
pointer = @owners[webContentsId]
|
||||
return unless pointer?
|
||||
--pointer[id]
|
||||
delete pointer[id] if pointer[id] is 0
|
||||
|
||||
@@ -57,6 +58,7 @@ class ObjectsRegistry extends EventEmitter
|
||||
# Private: Dereference the object from store.
|
||||
dereference: (id, count) ->
|
||||
pointer = @storage[id]
|
||||
return unless pointer?
|
||||
pointer.count -= count
|
||||
if pointer.count is 0
|
||||
v8Util.deleteHiddenValue pointer.object, 'atomId'
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
ipc = require 'ipc'
|
||||
path = require 'path'
|
||||
objectsRegistry = require './objects-registry.js'
|
||||
|
||||
electron = require 'electron'
|
||||
{ipcMain} = electron
|
||||
objectsRegistry = require './objects-registry'
|
||||
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
{IDWeakMap} = process.atomBinding 'id_weak_map'
|
||||
|
||||
# Convert a real value into meta data.
|
||||
valueToMeta = (sender, value, optimizeSimpleObject=false) ->
|
||||
@@ -10,7 +14,9 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) ->
|
||||
meta.type = 'buffer' if Buffer.isBuffer value
|
||||
meta.type = 'value' if value is null
|
||||
meta.type = 'array' if Array.isArray value
|
||||
meta.type = 'promise' if value? and value.constructor.name is 'Promise'
|
||||
meta.type = 'error' if value instanceof Error
|
||||
meta.type = 'date' if value instanceof Date
|
||||
meta.type = 'promise' if value?.constructor.name is 'Promise'
|
||||
|
||||
# Treat simple objects as value.
|
||||
if optimizeSimpleObject and meta.type is 'object' and v8Util.getHiddenValue value, 'simple'
|
||||
@@ -30,21 +36,28 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) ->
|
||||
# it.
|
||||
meta.id = objectsRegistry.add sender.getId(), value
|
||||
|
||||
meta.members = []
|
||||
meta.members.push {name: prop, type: typeof field} for prop, field of value
|
||||
meta.members = ({name, type: typeof field} for name, field of value)
|
||||
else if meta.type is 'buffer'
|
||||
meta.value = Array::slice.call value, 0
|
||||
else if meta.type is 'promise'
|
||||
meta.then = valueToMeta(sender, value.then.bind(value))
|
||||
meta.then = valueToMeta sender, value.then.bind(value)
|
||||
else if meta.type is 'error'
|
||||
meta.members = plainObjectToMeta value
|
||||
else if meta.type is 'date'
|
||||
meta.value = value.getTime()
|
||||
else
|
||||
meta.type = 'value'
|
||||
meta.value = value
|
||||
|
||||
meta
|
||||
|
||||
# Convert object to meta by value.
|
||||
plainObjectToMeta = (obj) ->
|
||||
Object.getOwnPropertyNames(obj).map (name) -> {name, value: obj[name]}
|
||||
|
||||
# Convert Error into meta data.
|
||||
errorToMeta = (error) ->
|
||||
type: 'error', message: error.message, stack: (error.stack || error)
|
||||
exceptionToMeta = (error) ->
|
||||
type: 'exception', message: error.message, stack: (error.stack || error)
|
||||
|
||||
# Convert array of meta data from renderer into array of real values.
|
||||
unwrapArgs = (sender, args) ->
|
||||
@@ -64,16 +77,27 @@ unwrapArgs = (sender, args) ->
|
||||
returnValue = metaToValue meta.value
|
||||
-> returnValue
|
||||
when 'function'
|
||||
# Cache the callbacks in renderer.
|
||||
unless sender.callbacks
|
||||
sender.callbacks = new IDWeakMap
|
||||
sender.on 'render-view-deleted', ->
|
||||
sender.callbacks.clear()
|
||||
return sender.callbacks.get meta.id if sender.callbacks.has meta.id
|
||||
|
||||
rendererReleased = false
|
||||
objectsRegistry.once "clear-#{sender.getId()}", ->
|
||||
rendererReleased = true
|
||||
|
||||
ret = ->
|
||||
throw new Error('Calling a callback of released renderer view') if rendererReleased
|
||||
if rendererReleased
|
||||
throw new Error("Attempting to call a function in a renderer window
|
||||
that has been closed or released. Function provided here: #{meta.location}.")
|
||||
sender.send 'ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, arguments)
|
||||
v8Util.setDestructor ret, ->
|
||||
return if rendererReleased
|
||||
sender.callbacks.remove meta.id
|
||||
sender.send 'ATOM_RENDERER_RELEASE_CALLBACK', meta.id
|
||||
sender.callbacks.set meta.id, ret
|
||||
ret
|
||||
else throw new TypeError("Unknown type: #{meta.type}")
|
||||
|
||||
@@ -82,40 +106,58 @@ unwrapArgs = (sender, args) ->
|
||||
# Call a function and send reply asynchronously if it's a an asynchronous
|
||||
# style function and the caller didn't pass a callback.
|
||||
callFunction = (event, func, caller, args) ->
|
||||
if v8Util.getHiddenValue(func, 'asynchronous') and typeof args[args.length - 1] isnt 'function'
|
||||
args.push (ret) ->
|
||||
funcMarkedAsync = v8Util.getHiddenValue(func, 'asynchronous')
|
||||
funcPassedCallback = args[args.length - 1] is 'function'
|
||||
|
||||
try
|
||||
if funcMarkedAsync and not funcPassedCallback
|
||||
args.push (ret) ->
|
||||
event.returnValue = valueToMeta event.sender, ret, true
|
||||
func.apply caller, args
|
||||
else
|
||||
ret = func.apply caller, args
|
||||
event.returnValue = valueToMeta event.sender, ret, true
|
||||
func.apply caller, args
|
||||
else
|
||||
ret = func.apply caller, args
|
||||
event.returnValue = valueToMeta event.sender, ret, true
|
||||
catch e
|
||||
# Catch functions thrown further down in function invocation and wrap
|
||||
# them with the function name so it's easier to trace things like
|
||||
# `Error processing argument -1.`
|
||||
funcName = func.name ? "anonymous"
|
||||
throw new Error("Could not call remote function `#{funcName}`.
|
||||
Check that the function signature is correct.
|
||||
Underlying error: #{e.message}")
|
||||
|
||||
# Send by BrowserWindow when its render view is deleted.
|
||||
process.on 'ATOM_BROWSER_RELEASE_RENDER_VIEW', (id) ->
|
||||
objectsRegistry.clear id
|
||||
|
||||
ipc.on 'ATOM_BROWSER_REQUIRE', (event, module) ->
|
||||
ipcMain.on 'ATOM_BROWSER_REQUIRE', (event, module) ->
|
||||
try
|
||||
event.returnValue = valueToMeta event.sender, process.mainModule.require(module)
|
||||
catch e
|
||||
event.returnValue = errorToMeta e
|
||||
event.returnValue = exceptionToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_GLOBAL', (event, name) ->
|
||||
ipcMain.on 'ATOM_BROWSER_GET_BUILTIN', (event, module) ->
|
||||
try
|
||||
event.returnValue = valueToMeta event.sender, electron[module]
|
||||
catch e
|
||||
event.returnValue = exceptionToMeta e
|
||||
|
||||
ipcMain.on 'ATOM_BROWSER_GLOBAL', (event, name) ->
|
||||
try
|
||||
event.returnValue = valueToMeta event.sender, global[name]
|
||||
catch e
|
||||
event.returnValue = errorToMeta e
|
||||
event.returnValue = exceptionToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event) ->
|
||||
ipcMain.on 'ATOM_BROWSER_CURRENT_WINDOW', (event) ->
|
||||
try
|
||||
event.returnValue = valueToMeta event.sender, event.sender.getOwnerBrowserWindow()
|
||||
catch e
|
||||
event.returnValue = errorToMeta e
|
||||
event.returnValue = exceptionToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_CURRENT_WEB_CONTENTS', (event) ->
|
||||
ipcMain.on 'ATOM_BROWSER_CURRENT_WEB_CONTENTS', (event) ->
|
||||
event.returnValue = valueToMeta event.sender, event.sender
|
||||
|
||||
ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, id, args) ->
|
||||
ipcMain.on 'ATOM_BROWSER_CONSTRUCTOR', (event, id, args) ->
|
||||
try
|
||||
args = unwrapArgs event.sender, args
|
||||
constructor = objectsRegistry.get id
|
||||
@@ -124,17 +166,17 @@ ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, id, args) ->
|
||||
obj = new (Function::bind.apply(constructor, [null].concat(args)))
|
||||
event.returnValue = valueToMeta event.sender, obj
|
||||
catch e
|
||||
event.returnValue = errorToMeta e
|
||||
event.returnValue = exceptionToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_FUNCTION_CALL', (event, id, args) ->
|
||||
ipcMain.on 'ATOM_BROWSER_FUNCTION_CALL', (event, id, args) ->
|
||||
try
|
||||
args = unwrapArgs event.sender, args
|
||||
func = objectsRegistry.get id
|
||||
callFunction event, func, global, args
|
||||
catch e
|
||||
event.returnValue = errorToMeta e
|
||||
event.returnValue = exceptionToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, id, method, args) ->
|
||||
ipcMain.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, id, method, args) ->
|
||||
try
|
||||
args = unwrapArgs event.sender, args
|
||||
constructor = objectsRegistry.get(id)[method]
|
||||
@@ -142,37 +184,40 @@ ipc.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, id, method, args) ->
|
||||
obj = new (Function::bind.apply(constructor, [null].concat(args)))
|
||||
event.returnValue = valueToMeta event.sender, obj
|
||||
catch e
|
||||
event.returnValue = errorToMeta e
|
||||
event.returnValue = exceptionToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_MEMBER_CALL', (event, id, method, args) ->
|
||||
ipcMain.on 'ATOM_BROWSER_MEMBER_CALL', (event, id, method, args) ->
|
||||
try
|
||||
args = unwrapArgs event.sender, args
|
||||
obj = objectsRegistry.get id
|
||||
callFunction event, obj[method], obj, args
|
||||
catch e
|
||||
event.returnValue = errorToMeta e
|
||||
event.returnValue = exceptionToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_MEMBER_SET', (event, id, name, value) ->
|
||||
ipcMain.on 'ATOM_BROWSER_MEMBER_SET', (event, id, name, value) ->
|
||||
try
|
||||
obj = objectsRegistry.get id
|
||||
obj[name] = value
|
||||
event.returnValue = null
|
||||
catch e
|
||||
event.returnValue = errorToMeta e
|
||||
event.returnValue = exceptionToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_MEMBER_GET', (event, id, name) ->
|
||||
ipcMain.on 'ATOM_BROWSER_MEMBER_GET', (event, id, name) ->
|
||||
try
|
||||
obj = objectsRegistry.get id
|
||||
event.returnValue = valueToMeta event.sender, obj[name]
|
||||
catch e
|
||||
event.returnValue = errorToMeta e
|
||||
event.returnValue = exceptionToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_DEREFERENCE', (event, id) ->
|
||||
ipcMain.on 'ATOM_BROWSER_DEREFERENCE', (event, id) ->
|
||||
objectsRegistry.remove event.sender.getId(), id
|
||||
|
||||
ipc.on 'ATOM_BROWSER_GUEST_WEB_CONTENTS', (event, guestInstanceId) ->
|
||||
ipcMain.on 'ATOM_BROWSER_GUEST_WEB_CONTENTS', (event, guestInstanceId) ->
|
||||
try
|
||||
guestViewManager = require './guest-view-manager'
|
||||
event.returnValue = valueToMeta event.sender, guestViewManager.getGuest(guestInstanceId)
|
||||
catch e
|
||||
event.returnValue = errorToMeta e
|
||||
event.returnValue = exceptionToMeta e
|
||||
|
||||
ipcMain.on 'ATOM_BROWSER_LIST_MODULES', (event) ->
|
||||
event.returnValue = (name for name of electron)
|
||||
|
||||
109
atom/browser/login_handler.cc
Normal file
109
atom/browser/login_handler.cc
Normal file
@@ -0,0 +1,109 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/login_handler.h"
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/resource_dispatcher_host.h"
|
||||
#include "content/public/browser/resource_request_info.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "net/base/auth.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
// Helper to remove the ref from an net::URLRequest to the LoginHandler.
|
||||
// Should only be called from the IO thread, since it accesses an
|
||||
// net::URLRequest.
|
||||
void ResetLoginHandlerForRequest(net::URLRequest* request) {
|
||||
content::ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
LoginHandler::LoginHandler(net::AuthChallengeInfo* auth_info,
|
||||
net::URLRequest* request)
|
||||
: handled_auth_(false),
|
||||
auth_info_(auth_info),
|
||||
request_(request),
|
||||
render_process_host_id_(0),
|
||||
render_frame_id_(0) {
|
||||
content::ResourceRequestInfo::ForRequest(request_)->GetAssociatedRenderFrame(
|
||||
&render_process_host_id_, &render_frame_id_);
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&Browser::RequestLogin,
|
||||
base::Unretained(Browser::Get()),
|
||||
make_scoped_refptr(this)));
|
||||
}
|
||||
|
||||
LoginHandler::~LoginHandler() {
|
||||
}
|
||||
|
||||
content::WebContents* LoginHandler::GetWebContents() const {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
content::RenderFrameHost* rfh = content::RenderFrameHost::FromID(
|
||||
render_process_host_id_, render_frame_id_);
|
||||
return content::WebContents::FromRenderFrameHost(rfh);
|
||||
}
|
||||
|
||||
void LoginHandler::Login(const base::string16& username,
|
||||
const base::string16& password) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
if (TestAndSetAuthHandled())
|
||||
return;
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&LoginHandler::DoLogin, this, username, password));
|
||||
}
|
||||
|
||||
void LoginHandler::CancelAuth() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
if (TestAndSetAuthHandled())
|
||||
return;
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&LoginHandler::DoCancelAuth, this));
|
||||
}
|
||||
|
||||
void LoginHandler::OnRequestCancelled() {
|
||||
TestAndSetAuthHandled();
|
||||
request_ = nullptr;
|
||||
}
|
||||
|
||||
// Marks authentication as handled and returns the previous handled state.
|
||||
bool LoginHandler::TestAndSetAuthHandled() {
|
||||
base::AutoLock lock(handled_auth_lock_);
|
||||
bool was_handled = handled_auth_;
|
||||
handled_auth_ = true;
|
||||
return was_handled;
|
||||
}
|
||||
|
||||
void LoginHandler::DoCancelAuth() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
if (request_) {
|
||||
request_->CancelAuth();
|
||||
// Verify that CancelAuth doesn't destroy the request via our delegate.
|
||||
DCHECK(request_ != nullptr);
|
||||
ResetLoginHandlerForRequest(request_);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginHandler::DoLogin(const base::string16& username,
|
||||
const base::string16& password) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
if (request_) {
|
||||
request_->SetAuth(net::AuthCredentials(username, password));
|
||||
ResetLoginHandlerForRequest(request_);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
76
atom/browser/login_handler.h
Normal file
76
atom/browser/login_handler.h
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_LOGIN_HANDLER_H_
|
||||
#define ATOM_BROWSER_LOGIN_HANDLER_H_
|
||||
|
||||
#include "base/strings/string16.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "content/public/browser/resource_dispatcher_host_login_delegate.h"
|
||||
|
||||
namespace content {
|
||||
class WebContents;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class AuthChallengeInfo;
|
||||
class URLRequest;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
// Handles the HTTP basic auth, must be created on IO thread.
|
||||
class LoginHandler : public content::ResourceDispatcherHostLoginDelegate {
|
||||
public:
|
||||
LoginHandler(net::AuthChallengeInfo* auth_info, net::URLRequest* request);
|
||||
|
||||
// Returns the WebContents associated with the request, must be called on UI
|
||||
// thread.
|
||||
content::WebContents* GetWebContents() const;
|
||||
|
||||
// The auth is cancelled, must be called on UI thread.
|
||||
void CancelAuth();
|
||||
|
||||
// Login with |username| and |password|, must be called on UI thread.
|
||||
void Login(const base::string16& username, const base::string16& password);
|
||||
|
||||
const net::AuthChallengeInfo* auth_info() const { return auth_info_.get(); }
|
||||
const net::URLRequest* request() const { return request_; }
|
||||
|
||||
protected:
|
||||
~LoginHandler() override;
|
||||
|
||||
// content::ResourceDispatcherHostLoginDelegate:
|
||||
void OnRequestCancelled() override;
|
||||
|
||||
private:
|
||||
// Must be called on IO thread.
|
||||
void DoCancelAuth();
|
||||
void DoLogin(const base::string16& username, const base::string16& password);
|
||||
|
||||
// Marks authentication as handled and returns the previous handled
|
||||
// state.
|
||||
bool TestAndSetAuthHandled();
|
||||
|
||||
// True if we've handled auth (Login or CancelAuth has been called).
|
||||
bool handled_auth_;
|
||||
mutable base::Lock handled_auth_lock_;
|
||||
|
||||
// Who/where/what asked for the authentication.
|
||||
scoped_refptr<net::AuthChallengeInfo> auth_info_;
|
||||
|
||||
// The request that wants login data.
|
||||
// This should only be accessed on the IO loop.
|
||||
net::URLRequest* request_;
|
||||
|
||||
// Cached from the net::URLRequest, in case it goes NULL on us.
|
||||
int render_process_host_id_;
|
||||
int render_frame_id_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(LoginHandler);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_LOGIN_HANDLER_H_
|
||||
@@ -43,11 +43,20 @@
|
||||
atom::Browser::Get()->OpenURL(base::SysNSStringToUTF8(url));
|
||||
}
|
||||
|
||||
- (bool)voiceOverEnabled {
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults addSuiteNamed:@"com.apple.universalaccess"];
|
||||
[defaults synchronize];
|
||||
|
||||
return [defaults boolForKey:@"voiceOverOnOffKey"];
|
||||
}
|
||||
|
||||
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute {
|
||||
// Undocumented attribute that VoiceOver happens to set while running.
|
||||
// Chromium uses this too, even though it's not exactly right.
|
||||
if ([attribute isEqualToString:@"AXEnhancedUserInterface"]) {
|
||||
[self updateAccessibilityEnabled:[value boolValue]];
|
||||
bool enableAccessibility = ([self voiceOverEnabled] && [value boolValue]);
|
||||
[self updateAccessibilityEnabled:enableAccessibility];
|
||||
}
|
||||
return [super accessibilitySetValue:value forAttribute:attribute];
|
||||
}
|
||||
|
||||
@@ -43,26 +43,6 @@ DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay);
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
// Convert draggable regions in raw format to SkRegion format. Caller is
|
||||
// responsible for deleting the returned SkRegion instance.
|
||||
scoped_ptr<SkRegion> DraggableRegionsToSkRegion(
|
||||
const std::vector<DraggableRegion>& regions) {
|
||||
scoped_ptr<SkRegion> sk_region(new SkRegion);
|
||||
for (const DraggableRegion& region : regions) {
|
||||
sk_region->op(
|
||||
region.bounds.x(),
|
||||
region.bounds.y(),
|
||||
region.bounds.right(),
|
||||
region.bounds.bottom(),
|
||||
region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
|
||||
}
|
||||
return sk_region.Pass();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NativeWindow::NativeWindow(
|
||||
brightray::InspectableWebContents* inspectable_web_contents,
|
||||
const mate::Dictionary& options)
|
||||
@@ -76,16 +56,16 @@ NativeWindow::NativeWindow(
|
||||
aspect_ratio_(0.0),
|
||||
inspectable_web_contents_(inspectable_web_contents),
|
||||
weak_factory_(this) {
|
||||
options.Get(switches::kFrame, &has_frame_);
|
||||
options.Get(switches::kTransparent, &transparent_);
|
||||
options.Get(switches::kEnableLargerThanScreen, &enable_larger_than_screen_);
|
||||
options.Get(options::kFrame, &has_frame_);
|
||||
options.Get(options::kTransparent, &transparent_);
|
||||
options.Get(options::kEnableLargerThanScreen, &enable_larger_than_screen_);
|
||||
|
||||
// Tell the content module to initialize renderer widget with transparent
|
||||
// mode.
|
||||
ui::GpuSwitchingManager::SetTransparent(transparent_);
|
||||
|
||||
// Read icon before window is created.
|
||||
options.Get(switches::kIcon, &icon_);
|
||||
options.Get(options::kIcon, &icon_);
|
||||
|
||||
WindowList::AddWindow(this);
|
||||
}
|
||||
@@ -111,53 +91,65 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
|
||||
// Setup window from options.
|
||||
int x = -1, y = -1;
|
||||
bool center;
|
||||
if (options.Get(switches::kX, &x) && options.Get(switches::kY, &y)) {
|
||||
int width = -1, height = -1;
|
||||
options.Get(switches::kWidth, &width);
|
||||
options.Get(switches::kHeight, &height);
|
||||
SetBounds(gfx::Rect(x, y, width, height));
|
||||
} else if (options.Get(switches::kCenter, ¢er) && center) {
|
||||
if (options.Get(options::kX, &x) && options.Get(options::kY, &y)) {
|
||||
SetPosition(gfx::Point(x, y));
|
||||
} else if (options.Get(options::kCenter, ¢er) && center) {
|
||||
Center();
|
||||
}
|
||||
// On Linux and Window we may already have maximum size defined.
|
||||
extensions::SizeConstraints size_constraints(GetContentSizeConstraints());
|
||||
int min_height = 0, min_width = 0;
|
||||
if (options.Get(switches::kMinHeight, &min_height) |
|
||||
options.Get(switches::kMinWidth, &min_width)) {
|
||||
SetMinimumSize(gfx::Size(min_width, min_height));
|
||||
if (options.Get(options::kMinHeight, &min_height) |
|
||||
options.Get(options::kMinWidth, &min_width)) {
|
||||
size_constraints.set_minimum_size(gfx::Size(min_width, min_height));
|
||||
}
|
||||
int max_height = INT_MAX, max_width = INT_MAX;
|
||||
if (options.Get(switches::kMaxHeight, &max_height) |
|
||||
options.Get(switches::kMaxWidth, &max_width)) {
|
||||
SetMaximumSize(gfx::Size(max_width, max_height));
|
||||
if (options.Get(options::kMaxHeight, &max_height) |
|
||||
options.Get(options::kMaxWidth, &max_width)) {
|
||||
size_constraints.set_maximum_size(gfx::Size(max_width, max_height));
|
||||
}
|
||||
bool use_content_size = false;
|
||||
options.Get(options::kUseContentSize, &use_content_size);
|
||||
if (use_content_size) {
|
||||
SetContentSizeConstraints(size_constraints);
|
||||
} else {
|
||||
SetSizeConstraints(size_constraints);
|
||||
}
|
||||
#if defined(OS_WIN) || defined(USE_X11)
|
||||
bool resizable;
|
||||
if (options.Get(switches::kResizable, &resizable)) {
|
||||
if (options.Get(options::kResizable, &resizable)) {
|
||||
SetResizable(resizable);
|
||||
}
|
||||
#endif
|
||||
bool top;
|
||||
if (options.Get(switches::kAlwaysOnTop, &top) && top) {
|
||||
if (options.Get(options::kAlwaysOnTop, &top) && top) {
|
||||
SetAlwaysOnTop(true);
|
||||
}
|
||||
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||
bool fullscreen;
|
||||
if (options.Get(switches::kFullscreen, &fullscreen) && fullscreen) {
|
||||
if (options.Get(options::kFullscreen, &fullscreen) && fullscreen) {
|
||||
SetFullScreen(true);
|
||||
}
|
||||
#endif
|
||||
bool skip;
|
||||
if (options.Get(switches::kSkipTaskbar, &skip) && skip) {
|
||||
if (options.Get(options::kSkipTaskbar, &skip) && skip) {
|
||||
SetSkipTaskbar(skip);
|
||||
}
|
||||
bool kiosk;
|
||||
if (options.Get(switches::kKiosk, &kiosk) && kiosk) {
|
||||
if (options.Get(options::kKiosk, &kiosk) && kiosk) {
|
||||
SetKiosk(kiosk);
|
||||
}
|
||||
std::string color;
|
||||
if (options.Get(options::kBackgroundColor, &color)) {
|
||||
SetBackgroundColor(color);
|
||||
}
|
||||
std::string title("Electron");
|
||||
options.Get(switches::kTitle, &title);
|
||||
options.Get(options::kTitle, &title);
|
||||
SetTitle(title);
|
||||
|
||||
// Then show it.
|
||||
bool show = true;
|
||||
options.Get(switches::kShow, &show);
|
||||
options.Get(options::kShow, &show);
|
||||
if (show)
|
||||
Show();
|
||||
}
|
||||
@@ -178,6 +170,67 @@ gfx::Point NativeWindow::GetPosition() {
|
||||
return GetBounds().origin();
|
||||
}
|
||||
|
||||
void NativeWindow::SetContentSize(const gfx::Size& size) {
|
||||
SetSize(ContentSizeToWindowSize(size));
|
||||
}
|
||||
|
||||
gfx::Size NativeWindow::GetContentSize() {
|
||||
return WindowSizeToContentSize(GetSize());
|
||||
}
|
||||
|
||||
void NativeWindow::SetSizeConstraints(
|
||||
const extensions::SizeConstraints& window_constraints) {
|
||||
extensions::SizeConstraints content_constraints;
|
||||
if (window_constraints.HasMaximumSize())
|
||||
content_constraints.set_maximum_size(
|
||||
WindowSizeToContentSize(window_constraints.GetMaximumSize()));
|
||||
if (window_constraints.HasMinimumSize())
|
||||
content_constraints.set_minimum_size(
|
||||
WindowSizeToContentSize(window_constraints.GetMinimumSize()));
|
||||
SetContentSizeConstraints(content_constraints);
|
||||
}
|
||||
|
||||
extensions::SizeConstraints NativeWindow::GetSizeConstraints() {
|
||||
extensions::SizeConstraints content_constraints = GetContentSizeConstraints();
|
||||
extensions::SizeConstraints window_constraints;
|
||||
if (content_constraints.HasMaximumSize())
|
||||
window_constraints.set_maximum_size(
|
||||
ContentSizeToWindowSize(content_constraints.GetMaximumSize()));
|
||||
if (content_constraints.HasMinimumSize())
|
||||
window_constraints.set_minimum_size(
|
||||
ContentSizeToWindowSize(content_constraints.GetMinimumSize()));
|
||||
return window_constraints;
|
||||
}
|
||||
|
||||
void NativeWindow::SetContentSizeConstraints(
|
||||
const extensions::SizeConstraints& size_constraints) {
|
||||
size_constraints_ = size_constraints;
|
||||
}
|
||||
|
||||
extensions::SizeConstraints NativeWindow::GetContentSizeConstraints() {
|
||||
return size_constraints_;
|
||||
}
|
||||
|
||||
void NativeWindow::SetMinimumSize(const gfx::Size& size) {
|
||||
extensions::SizeConstraints size_constraints;
|
||||
size_constraints.set_minimum_size(size);
|
||||
SetSizeConstraints(size_constraints);
|
||||
}
|
||||
|
||||
gfx::Size NativeWindow::GetMinimumSize() {
|
||||
return GetSizeConstraints().GetMinimumSize();
|
||||
}
|
||||
|
||||
void NativeWindow::SetMaximumSize(const gfx::Size& size) {
|
||||
extensions::SizeConstraints size_constraints;
|
||||
size_constraints.set_maximum_size(size);
|
||||
SetSizeConstraints(size_constraints);
|
||||
}
|
||||
|
||||
gfx::Size NativeWindow::GetMaximumSize() {
|
||||
return GetSizeConstraints().GetMaximumSize();
|
||||
}
|
||||
|
||||
void NativeWindow::SetRepresentedFilename(const std::string& filename) {
|
||||
}
|
||||
|
||||
@@ -411,6 +464,28 @@ void NativeWindow::NotifyWindowExecuteWindowsCommand(
|
||||
OnExecuteWindowsCommand(command));
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void NativeWindow::NotifyWindowMessage(
|
||||
UINT message, WPARAM w_param, LPARAM l_param) {
|
||||
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
|
||||
OnWindowMessage(message, w_param, l_param));
|
||||
}
|
||||
#endif
|
||||
|
||||
scoped_ptr<SkRegion> NativeWindow::DraggableRegionsToSkRegion(
|
||||
const std::vector<DraggableRegion>& regions) {
|
||||
scoped_ptr<SkRegion> sk_region(new SkRegion);
|
||||
for (const DraggableRegion& region : regions) {
|
||||
sk_region->op(
|
||||
region.bounds.x(),
|
||||
region.bounds.y(),
|
||||
region.bounds.right(),
|
||||
region.bounds.bottom(),
|
||||
region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
|
||||
}
|
||||
return sk_region.Pass();
|
||||
}
|
||||
|
||||
void NativeWindow::RenderViewCreated(
|
||||
content::RenderViewHost* render_view_host) {
|
||||
if (!transparent_)
|
||||
@@ -437,7 +512,7 @@ void NativeWindow::TitleWasSet(content::NavigationEntry* entry,
|
||||
FOR_EACH_OBSERVER(NativeWindowObserver,
|
||||
observers_,
|
||||
OnPageTitleUpdated(&prevent_default, text));
|
||||
if (!prevent_default)
|
||||
if (!prevent_default && !is_closed_)
|
||||
SetTitle(text);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user