mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
2384 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b8a6aea74 | ||
|
|
16e224bb86 | ||
|
|
459d389e03 | ||
|
|
8e4581a3c0 | ||
|
|
c97c3fb9a1 | ||
|
|
7ce8156691 | ||
|
|
0e6a70c556 | ||
|
|
b68d559329 | ||
|
|
18fcd6990b | ||
|
|
5fe130a684 | ||
|
|
d367af3fa4 | ||
|
|
549ec51bce | ||
|
|
b4674923c9 | ||
|
|
71598e15bf | ||
|
|
cd3c061448 | ||
|
|
163790d107 | ||
|
|
2fdc5780ff | ||
|
|
b76642bd10 | ||
|
|
209e24bf0f | ||
|
|
731773765e | ||
|
|
333fe87490 | ||
|
|
36f0ef703a | ||
|
|
605722c397 | ||
|
|
132c13a11b | ||
|
|
04d24f61fe | ||
|
|
8eb5e651a2 | ||
|
|
5cd0fc4d52 | ||
|
|
d12697c657 | ||
|
|
0819176cb1 | ||
|
|
7d1f6dae6f | ||
|
|
5c2bb42d49 | ||
|
|
db9615f5cd | ||
|
|
09c5da7147 | ||
|
|
4b12a95d37 | ||
|
|
200a19dad9 | ||
|
|
2ee6e43fb3 | ||
|
|
0fef09281b | ||
|
|
f91a81fe77 | ||
|
|
78eff673ec | ||
|
|
51dc8ad70a | ||
|
|
d8cd9b71b0 | ||
|
|
c78a3ff714 | ||
|
|
4642630674 | ||
|
|
a6a5d50c3f | ||
|
|
b4790a7531 | ||
|
|
9199d0df0a | ||
|
|
a84e6227ef | ||
|
|
35dcdfc492 | ||
|
|
2f4333b852 | ||
|
|
bd1fd9680f | ||
|
|
cf79f439ce | ||
|
|
e829a28947 | ||
|
|
6d756d9d13 | ||
|
|
29abfa68e9 | ||
|
|
ab98dcd7cf | ||
|
|
6494ed6b13 | ||
|
|
8893c9502a | ||
|
|
13b6ed6dc5 | ||
|
|
8aa815e6d1 | ||
|
|
719f68a44b | ||
|
|
4c48f0cd36 | ||
|
|
8ef3351846 | ||
|
|
9f0ac13edc | ||
|
|
5459137d3d | ||
|
|
52b2c0d27f | ||
|
|
89087d402d | ||
|
|
64e84b8f6a | ||
|
|
24586c1330 | ||
|
|
f8c6056eec | ||
|
|
03ab9b2686 | ||
|
|
f1a8c5a1ca | ||
|
|
488801e244 | ||
|
|
bf1765f941 | ||
|
|
994be9cdab | ||
|
|
d4e4c6ca15 | ||
|
|
47cb06e201 | ||
|
|
cac97cca0d | ||
|
|
16c08e7e37 | ||
|
|
2de5f9de6c | ||
|
|
06a3875726 | ||
|
|
1ae8bed96a | ||
|
|
2ec74b5958 | ||
|
|
72ebb2c9fe | ||
|
|
52166d2999 | ||
|
|
676cfa03a1 | ||
|
|
64a89fe755 | ||
|
|
2bd03f6eda | ||
|
|
eeaee1a0b7 | ||
|
|
fed9ef0687 | ||
|
|
75448ad7ed | ||
|
|
25db6e0bd8 | ||
|
|
cefe540ec0 | ||
|
|
8363a39a56 | ||
|
|
57ef6adbbd | ||
|
|
5ae9c633ca | ||
|
|
b6a5e927e0 | ||
|
|
625c17fa24 | ||
|
|
f776932718 | ||
|
|
55c07cec68 | ||
|
|
161dc45ec8 | ||
|
|
29827fa66b | ||
|
|
40b6a1a37c | ||
|
|
e4ae579b16 | ||
|
|
582a42f97c | ||
|
|
9a0a10e766 | ||
|
|
cd1c331112 | ||
|
|
8a2b665097 | ||
|
|
690513db7f | ||
|
|
13c1b078f9 | ||
|
|
4da7578dab | ||
|
|
c821a06e2f | ||
|
|
cd7b3dd291 | ||
|
|
bb42c2c7b6 | ||
|
|
af62b7b5c9 | ||
|
|
8f9a109fa6 | ||
|
|
05468cc3fa | ||
|
|
94d69777fa | ||
|
|
67144aaf2a | ||
|
|
d9efc3b4bf | ||
|
|
c32aac0a56 | ||
|
|
92b15c81e9 | ||
|
|
19d742de37 | ||
|
|
e8f33f51fb | ||
|
|
7f7cdbf775 | ||
|
|
7f42c0fa21 | ||
|
|
8306dc427a | ||
|
|
66b3972fbc | ||
|
|
ed244648d0 | ||
|
|
790fba598e | ||
|
|
129159c895 | ||
|
|
f4c696b922 | ||
|
|
f54506acc0 | ||
|
|
4466082592 | ||
|
|
a8256a62e0 | ||
|
|
683917ae67 | ||
|
|
a22b9be681 | ||
|
|
3b20f2aced | ||
|
|
5d23b7468e | ||
|
|
d5b47d1059 | ||
|
|
47e9deeb9a | ||
|
|
6d6e75795f | ||
|
|
cc3066e746 | ||
|
|
0fcc0f3e0a | ||
|
|
da83ba6c06 | ||
|
|
3c186946eb | ||
|
|
31beee9599 | ||
|
|
912ed2ca10 | ||
|
|
c2352d3499 | ||
|
|
3a3b05b2f0 | ||
|
|
95a8f3fc70 | ||
|
|
34cd1435b4 | ||
|
|
d4be2da70e | ||
|
|
e5c4e34ac4 | ||
|
|
6dfa7b5383 | ||
|
|
94382cbaa2 | ||
|
|
981908c336 | ||
|
|
3ee054e316 | ||
|
|
f22d4bf0c0 | ||
|
|
d46e986e80 | ||
|
|
bd6d41bd87 | ||
|
|
4457edb1d3 | ||
|
|
e920ce3e24 | ||
|
|
ce8aa073ee | ||
|
|
2396b51cb6 | ||
|
|
317406f26d | ||
|
|
67a9931b55 | ||
|
|
ad851547e0 | ||
|
|
c4cbb5ecdb | ||
|
|
b97c22d4d7 | ||
|
|
fe631e6eeb | ||
|
|
1314b7c7e5 | ||
|
|
c026863d48 | ||
|
|
51d5ef9d86 | ||
|
|
16fb847009 | ||
|
|
cd8ceec62e | ||
|
|
98a9d8a9e3 | ||
|
|
4e2f242ad0 | ||
|
|
02bdace366 | ||
|
|
6ed538b952 | ||
|
|
dfbe158ca9 | ||
|
|
fb37b5720d | ||
|
|
57ab704300 | ||
|
|
4a310ad630 | ||
|
|
a9ad783bca | ||
|
|
b5c9fe78f1 | ||
|
|
e4bb456964 | ||
|
|
b45ed8d9a2 | ||
|
|
bdf73fcd4c | ||
|
|
3e720bd611 | ||
|
|
ad89a923e9 | ||
|
|
725115e0b5 | ||
|
|
419a14a63f | ||
|
|
d9102efff7 | ||
|
|
895ab49857 | ||
|
|
ebbb974aca | ||
|
|
8a6ba7c49f | ||
|
|
f98da217e1 | ||
|
|
2060acd914 | ||
|
|
014d80c359 | ||
|
|
9b7ad675c6 | ||
|
|
6ee8f6e4f2 | ||
|
|
4d56281972 | ||
|
|
5584e3fd49 | ||
|
|
4a376694b4 | ||
|
|
fbdea15649 | ||
|
|
f961f0617f | ||
|
|
1c60575dc0 | ||
|
|
abf8ffd3a2 | ||
|
|
935cd92ef3 | ||
|
|
172a5a71fc | ||
|
|
c244e83e10 | ||
|
|
291604515f | ||
|
|
904b75ab4a | ||
|
|
2de0b025f1 | ||
|
|
5f52ca918f | ||
|
|
16a95a42ff | ||
|
|
4282ed6a3c | ||
|
|
a642782a00 | ||
|
|
0bb4e0e44a | ||
|
|
d91ddc6177 | ||
|
|
2b9826404a | ||
|
|
4d5790dc09 | ||
|
|
c22b138b67 | ||
|
|
fdad5892d9 | ||
|
|
c3791bba78 | ||
|
|
bf5f85645e | ||
|
|
f1f801b7a2 | ||
|
|
5ede62459c | ||
|
|
abd97a7513 | ||
|
|
30d815e28f | ||
|
|
e233eab4f2 | ||
|
|
b202bba2e6 | ||
|
|
d78efe7c22 | ||
|
|
b169ac016e | ||
|
|
d1685f79a2 | ||
|
|
01e891652f | ||
|
|
c82d21b39f | ||
|
|
63c2a7f1a9 | ||
|
|
9a60fde59b | ||
|
|
f46fcd158a | ||
|
|
1b1735bca9 | ||
|
|
3a5977e09f | ||
|
|
d34800bb0a | ||
|
|
662261f84f | ||
|
|
33a926c5d3 | ||
|
|
c372dcb462 | ||
|
|
9a768dd4f0 | ||
|
|
82377cbfd5 | ||
|
|
83ba21f622 | ||
|
|
f31bfab127 | ||
|
|
466fc9a2fa | ||
|
|
fd41f1e8bc | ||
|
|
32b2ef3539 | ||
|
|
cde6b41a05 | ||
|
|
3ecfadf367 | ||
|
|
27c3727ddb | ||
|
|
ea147c588f | ||
|
|
e8a02316ce | ||
|
|
0dcf061dc1 | ||
|
|
f2d91bc53c | ||
|
|
ddda8e4197 | ||
|
|
4fe294ed04 | ||
|
|
be57151037 | ||
|
|
71ee864d1d | ||
|
|
427b9567ca | ||
|
|
5e7d6f89e8 | ||
|
|
7644799790 | ||
|
|
dbecc8d5f5 | ||
|
|
4ae1998d09 | ||
|
|
bbd8f091e0 | ||
|
|
6f806190b6 | ||
|
|
e80e4ae02c | ||
|
|
04b797ff0c | ||
|
|
f960c2dc63 | ||
|
|
9b445c27a2 | ||
|
|
97a2889fd9 | ||
|
|
c548b9c87e | ||
|
|
097d4d9870 | ||
|
|
b238ac5981 | ||
|
|
fe19e63fbc | ||
|
|
efd8a8a624 | ||
|
|
fa169ee7ff | ||
|
|
0e7bc6b8ec | ||
|
|
f8185296f4 | ||
|
|
4129d45d21 | ||
|
|
361505661f | ||
|
|
b558485394 | ||
|
|
a9a331938e | ||
|
|
7c69c2846b | ||
|
|
cda8b119e2 | ||
|
|
975978b414 | ||
|
|
5ee0ff9ee9 | ||
|
|
ca63ea0882 | ||
|
|
50c913fe92 | ||
|
|
22f51372f5 | ||
|
|
e4d90f747f | ||
|
|
4a8d7c1819 | ||
|
|
3a81a5224d | ||
|
|
3993161a63 | ||
|
|
25019de690 | ||
|
|
8fea373758 | ||
|
|
b0e8cafa00 | ||
|
|
1a8c0230a7 | ||
|
|
6980982e32 | ||
|
|
ec5d05e226 | ||
|
|
3387459be2 | ||
|
|
9963ddc485 | ||
|
|
46d80e8f05 | ||
|
|
ef30adcaef | ||
|
|
36c376b1ec | ||
|
|
dcbc6a127b | ||
|
|
e4415f0021 | ||
|
|
b4403fa9ec | ||
|
|
a725a49759 | ||
|
|
76f1e6d526 | ||
|
|
d19ae50cad | ||
|
|
9f461aed68 | ||
|
|
3913e18447 | ||
|
|
90fb7bc52d | ||
|
|
76d33c37d7 | ||
|
|
033f9bcced | ||
|
|
1c97fc79ad | ||
|
|
0097f89adb | ||
|
|
32ba219146 | ||
|
|
add7f8a4aa | ||
|
|
2785a4cc48 | ||
|
|
827741a9c6 | ||
|
|
ca623f16bf | ||
|
|
3bd54b7920 | ||
|
|
613a51f5fb | ||
|
|
e5d30636c2 | ||
|
|
e1beeb95e3 | ||
|
|
4ca8039104 | ||
|
|
e817192df3 | ||
|
|
2bb7497312 | ||
|
|
82ffa4d2b1 | ||
|
|
707503ac40 | ||
|
|
7fee639edf | ||
|
|
d1545a64ae | ||
|
|
40631edb70 | ||
|
|
4d1cd7e15f | ||
|
|
4c10925694 | ||
|
|
fc2bc20572 | ||
|
|
4a195e6283 | ||
|
|
24bcd3b21e | ||
|
|
9ab53b0e4b | ||
|
|
e5380fd671 | ||
|
|
d9c769fa69 | ||
|
|
d8d7e5b9bb | ||
|
|
f8e1dfbbc6 | ||
|
|
f02cae1b0a | ||
|
|
fa7f900b2b | ||
|
|
75e5695317 | ||
|
|
66ef52197a | ||
|
|
9e3f108fad | ||
|
|
1571c3537d | ||
|
|
18780487c2 | ||
|
|
ce042d0524 | ||
|
|
312b8c95ba | ||
|
|
6e8bc6a597 | ||
|
|
d9c90be1de | ||
|
|
ed023a560e | ||
|
|
15ae6b8d36 | ||
|
|
853ce0bbd7 | ||
|
|
1c190388e5 | ||
|
|
3fdc4543b8 | ||
|
|
be06a3d562 | ||
|
|
95e72c24cc | ||
|
|
c8d0ef05a6 | ||
|
|
85119db81a | ||
|
|
4d9470c24e | ||
|
|
2b1894f356 | ||
|
|
dca872d987 | ||
|
|
4660d3c265 | ||
|
|
f2bf8d6db3 | ||
|
|
ae8ac97f32 | ||
|
|
2b82e523bf | ||
|
|
9d54092f41 | ||
|
|
5f357d39b2 | ||
|
|
1817ddc18a | ||
|
|
102fb66461 | ||
|
|
0f67b1866a | ||
|
|
f2853a0b89 | ||
|
|
6c5429c7f0 | ||
|
|
a6ba0cd107 | ||
|
|
57e6b75871 | ||
|
|
904505bb21 | ||
|
|
56afe4dd5d | ||
|
|
2d190b9952 | ||
|
|
298d3a0144 | ||
|
|
22c50d0800 | ||
|
|
06834b723b | ||
|
|
a04222f398 | ||
|
|
0d4d2080ca | ||
|
|
7142cae041 | ||
|
|
921e7e0f91 | ||
|
|
f2fdc556a4 | ||
|
|
1835d90bb7 | ||
|
|
f5cf3556b1 | ||
|
|
a53b1f7edf | ||
|
|
f64dbbea3e | ||
|
|
6842ac98c3 | ||
|
|
294dbac869 | ||
|
|
5f27bb597f | ||
|
|
4c145f44a4 | ||
|
|
abe63ebd84 | ||
|
|
4f67415607 | ||
|
|
e2ec50173f | ||
|
|
d2ab8322b7 | ||
|
|
9ae59e8ac7 | ||
|
|
6d7d068e49 | ||
|
|
ae6a1b409f | ||
|
|
4608f5e9cd | ||
|
|
9300859983 | ||
|
|
52240750a1 | ||
|
|
d76bd4a103 | ||
|
|
bfac7f7a17 | ||
|
|
36d2512ff8 | ||
|
|
ca7e2c4d96 | ||
|
|
817dfbdc27 | ||
|
|
5fa7ae7d72 | ||
|
|
c54eca8dff | ||
|
|
72f5381c31 | ||
|
|
7ca2363d78 | ||
|
|
dec7c40fd8 | ||
|
|
a8846e0432 | ||
|
|
ff87592722 | ||
|
|
8c5f171a93 | ||
|
|
ea74e825c9 | ||
|
|
2b3ef714bd | ||
|
|
23afffa46d | ||
|
|
129cdb7680 | ||
|
|
8d3404d26c | ||
|
|
05e0564426 | ||
|
|
d8be645d5a | ||
|
|
3f499f69ff | ||
|
|
75b24c7d76 | ||
|
|
c6cf91d11f | ||
|
|
3a50c9e48c | ||
|
|
7c2b1468c8 | ||
|
|
fb6c80d12e | ||
|
|
d826e1e5fb | ||
|
|
04a0aaa35f | ||
|
|
f5fbd52dbd | ||
|
|
5575d17d0e | ||
|
|
0e7970fec5 | ||
|
|
fdfd8807a0 | ||
|
|
da07e72f20 | ||
|
|
f4a27f699a | ||
|
|
e3c21424de | ||
|
|
b5aa2a31a1 | ||
|
|
05ae1960d1 | ||
|
|
dde791d475 | ||
|
|
16b2f08cd3 | ||
|
|
0143a45488 | ||
|
|
2f1683445b | ||
|
|
4c78f98da6 | ||
|
|
3ff2959f0c | ||
|
|
36c4b1705d | ||
|
|
d8adbc0875 | ||
|
|
b527846ee4 | ||
|
|
ee45f0e8bc | ||
|
|
ca5ee0fc81 | ||
|
|
ecf29f72bc | ||
|
|
c811beb1e2 | ||
|
|
0c091428d3 | ||
|
|
858198a2bd | ||
|
|
1649d8f900 | ||
|
|
eb42fdbbc6 | ||
|
|
6cc571bdfe | ||
|
|
da648511b3 | ||
|
|
18b3dfa350 | ||
|
|
05be71e9bc | ||
|
|
36819e2638 | ||
|
|
9b585458c1 | ||
|
|
c424d0e9f3 | ||
|
|
81783b255e | ||
|
|
80c8ab4c39 | ||
|
|
826a4e0e48 | ||
|
|
7917748b21 | ||
|
|
b7f974f469 | ||
|
|
5c5fd377f7 | ||
|
|
0a995c3731 | ||
|
|
47b754e914 | ||
|
|
00ef99826d | ||
|
|
45943302ee | ||
|
|
2157f898bb | ||
|
|
132c7aba2d | ||
|
|
1ae88f0f0f | ||
|
|
c0f0fcba7b | ||
|
|
cdb1711fe1 | ||
|
|
20b4cae980 | ||
|
|
67bc4afe88 | ||
|
|
fb78169396 | ||
|
|
ba7e26539f | ||
|
|
500d15f53a | ||
|
|
fad977e27d | ||
|
|
4983ef77bd | ||
|
|
4a6066c69e | ||
|
|
1690df9bcf | ||
|
|
5c94f7ccd4 | ||
|
|
494c3f3255 | ||
|
|
ec4d596189 | ||
|
|
bc04e951cf | ||
|
|
e3109c9f1f | ||
|
|
6fc6aae62d | ||
|
|
b44c66b5c2 | ||
|
|
20c1530278 | ||
|
|
a213a8639f | ||
|
|
38583ca721 | ||
|
|
5126f02184 | ||
|
|
c910686b01 | ||
|
|
23833cf7f4 | ||
|
|
b37c73436b | ||
|
|
32f0ae5b50 | ||
|
|
87809e65aa | ||
|
|
916fa4b9a8 | ||
|
|
217e8f4078 | ||
|
|
21f05fc363 | ||
|
|
51b5e953f4 | ||
|
|
5bdb4b9aa1 | ||
|
|
bcfe243b3c | ||
|
|
2814dc316a | ||
|
|
fc3026dcfe | ||
|
|
1f580cbb67 | ||
|
|
237b7bedaa | ||
|
|
c34c5965c5 | ||
|
|
8f611687f1 | ||
|
|
a6ad824ccb | ||
|
|
c1737e5c16 | ||
|
|
1d148fe2fb | ||
|
|
88a1c7973c | ||
|
|
7a52a4cff1 | ||
|
|
ee08d98d2e | ||
|
|
9cf4156928 | ||
|
|
45f022b9db | ||
|
|
0d3cc8aaa7 | ||
|
|
5b69421625 | ||
|
|
397a503da3 | ||
|
|
51cadc6e90 | ||
|
|
3971249868 | ||
|
|
96c886a8f0 | ||
|
|
0033240c1f | ||
|
|
d0d6512330 | ||
|
|
d535305ff1 | ||
|
|
cd0aa4a956 | ||
|
|
0bab50ed80 | ||
|
|
eb6fa46041 | ||
|
|
b0b6747456 | ||
|
|
2f9de5a0e9 | ||
|
|
95250f4940 | ||
|
|
1f1cb12d46 | ||
|
|
d2682233fd | ||
|
|
d878bd33d7 | ||
|
|
3a850b94f5 | ||
|
|
a179e48e3b | ||
|
|
2de9123cfd | ||
|
|
378e56e254 | ||
|
|
0d3aaaf0af | ||
|
|
76316e5e65 | ||
|
|
14e05c6d68 | ||
|
|
49c82b3b93 | ||
|
|
c7468278df | ||
|
|
e04c58f398 | ||
|
|
1200d641b8 | ||
|
|
2d8d328f02 | ||
|
|
c6c305a827 | ||
|
|
b86f149512 | ||
|
|
ecc14dd023 | ||
|
|
c20dc06c96 | ||
|
|
a72c7b38a5 | ||
|
|
4353c6d402 | ||
|
|
29338e2fa4 | ||
|
|
c10b9ea511 | ||
|
|
fc7bddf0d9 | ||
|
|
e28fc190f2 | ||
|
|
eddb23d56b | ||
|
|
a3f630e55c | ||
|
|
175f397173 | ||
|
|
a4c01b2336 | ||
|
|
64f9f7e906 | ||
|
|
91c9f590dd | ||
|
|
f11988a354 | ||
|
|
6137c2317d | ||
|
|
7a97488023 | ||
|
|
ddfd2bc4be | ||
|
|
74be99de31 | ||
|
|
7255962bd3 | ||
|
|
b413acddb8 | ||
|
|
6ba57dcfa3 | ||
|
|
f8d64ef1e4 | ||
|
|
af37af3e1c | ||
|
|
4e7ed50162 | ||
|
|
43fe82e1e5 | ||
|
|
159e013ce5 | ||
|
|
61100c9c0b | ||
|
|
1027fe9991 | ||
|
|
f979847e06 | ||
|
|
26ac617692 | ||
|
|
d0f2da944f | ||
|
|
64aaa2bcb1 | ||
|
|
847ae5abe4 | ||
|
|
d19a1063d5 | ||
|
|
a724d6d684 | ||
|
|
b53123d5e7 | ||
|
|
e5a7921873 | ||
|
|
b9b7928e7d | ||
|
|
6b1dd0d413 | ||
|
|
aa835ad38a | ||
|
|
6b1f2215b2 | ||
|
|
f64a3dd349 | ||
|
|
8a418ba347 | ||
|
|
c30d806837 | ||
|
|
fabaa2af94 | ||
|
|
03bdd8814e | ||
|
|
b5450801d0 | ||
|
|
9e7c2a6fe4 | ||
|
|
aa07d5e557 | ||
|
|
f32cd5a35e | ||
|
|
6175380bc0 | ||
|
|
de016e72a5 | ||
|
|
1a6832d849 | ||
|
|
ca50cbb5ff | ||
|
|
252ac465c5 | ||
|
|
8e9e05f062 | ||
|
|
3a59cd3b72 | ||
|
|
f997dbb01d | ||
|
|
4defde0b61 | ||
|
|
ab94c3f49e | ||
|
|
21ca4de1af | ||
|
|
dfa6fedaed | ||
|
|
88b6a60c29 | ||
|
|
a13343800a | ||
|
|
1f66006c93 | ||
|
|
3a5bb588e5 | ||
|
|
8894cfab50 | ||
|
|
8500a53c23 | ||
|
|
5f2fe27b65 | ||
|
|
a400bb5997 | ||
|
|
ae9d90eaa6 | ||
|
|
dcae08c128 | ||
|
|
2d6b6e4578 | ||
|
|
97c76c19c4 | ||
|
|
78ed9b1b23 | ||
|
|
52b875f199 | ||
|
|
b947cb5057 | ||
|
|
b6af1cf93c | ||
|
|
0a56f34d04 | ||
|
|
596f14eca5 | ||
|
|
44d0bceff4 | ||
|
|
b8e38ad14e | ||
|
|
6615ef1054 | ||
|
|
6ca4623ae1 | ||
|
|
0bc5d6438e | ||
|
|
42dafd47fd | ||
|
|
4bb0ac271b | ||
|
|
15a648a879 | ||
|
|
565065ed6b | ||
|
|
f5e6c62418 | ||
|
|
c3f8ef06b6 | ||
|
|
c2852b5b8c | ||
|
|
c5b85b23eb | ||
|
|
555e06573a | ||
|
|
1b3b2cd402 | ||
|
|
efd294d69d | ||
|
|
f9b5156c2c | ||
|
|
5467476173 | ||
|
|
d8fbfe6885 | ||
|
|
4ce3b407ab | ||
|
|
d763984b77 | ||
|
|
8bd711ea66 | ||
|
|
1a36770286 | ||
|
|
c8a3c14a8c | ||
|
|
105aec4ea9 | ||
|
|
0cc36377a5 | ||
|
|
9a458785b6 | ||
|
|
21014614fc | ||
|
|
0890ea716f | ||
|
|
2351c11da4 | ||
|
|
0f97bf03fa | ||
|
|
2f5090d667 | ||
|
|
f169772031 | ||
|
|
fb00c28026 | ||
|
|
54bb072ae0 | ||
|
|
54f2b3248d | ||
|
|
e95ab2ddb8 | ||
|
|
3ae604ca4e | ||
|
|
1d97c2c8f2 | ||
|
|
e334e6e822 | ||
|
|
0dffa0f4bb | ||
|
|
938069a389 | ||
|
|
c98774b3df | ||
|
|
e64101e31f | ||
|
|
5ffa22812f | ||
|
|
87af6f9c80 | ||
|
|
8e8c5e1846 | ||
|
|
0de623693d | ||
|
|
bb7217a58c | ||
|
|
40c85f2042 | ||
|
|
d3abf64bd2 | ||
|
|
8b7d875e40 | ||
|
|
8a91000083 | ||
|
|
dab9e9be67 | ||
|
|
ca161e29ce | ||
|
|
3aefa5f549 | ||
|
|
736afb32a0 | ||
|
|
14de7ddea8 | ||
|
|
5ff9588b48 | ||
|
|
219a461f78 | ||
|
|
e2000c4418 | ||
|
|
0a99140b2a | ||
|
|
95528f9207 | ||
|
|
211e386c89 | ||
|
|
2915774644 | ||
|
|
cc443f730c | ||
|
|
80c9f864be | ||
|
|
7e49645998 | ||
|
|
761aa0e95c | ||
|
|
2980adfd79 | ||
|
|
da71175968 | ||
|
|
8de1ccb2c0 | ||
|
|
953060e17c | ||
|
|
2612e8fe8e | ||
|
|
430a6c2915 | ||
|
|
acd6797a5f | ||
|
|
5460b84c60 | ||
|
|
ce3d9f44ff | ||
|
|
c5c686fe8c | ||
|
|
59c95f6a7d | ||
|
|
a53bed567e | ||
|
|
9b68777b4b | ||
|
|
3b1be743ef | ||
|
|
b987656f1f | ||
|
|
e0d0e7651f | ||
|
|
922def8ce0 | ||
|
|
d9c22396ea | ||
|
|
9f30933d3a | ||
|
|
8482575d1f | ||
|
|
286ad19771 | ||
|
|
27d2dbf375 | ||
|
|
657b1cf63a | ||
|
|
0477c01fae | ||
|
|
fdc07dea17 | ||
|
|
85838fbf1a | ||
|
|
0342854e25 | ||
|
|
8a62f62e50 | ||
|
|
bedea89dcf | ||
|
|
399f47ef0f | ||
|
|
8aae7c4440 | ||
|
|
4663fdb446 | ||
|
|
4a508e0e41 | ||
|
|
21a09d3ae8 | ||
|
|
2505f8b8b2 | ||
|
|
32cd068427 | ||
|
|
b52771e729 | ||
|
|
69d958b94e | ||
|
|
b77c03357c | ||
|
|
c677a44688 | ||
|
|
b6875ad49b | ||
|
|
296d5c4515 | ||
|
|
2cdfef286a | ||
|
|
83024ea509 | ||
|
|
0611f9156f | ||
|
|
e2bdbae262 | ||
|
|
b54e786b09 | ||
|
|
b5bc8c9811 | ||
|
|
476b61322f | ||
|
|
6f082b630d | ||
|
|
0bb7abd7a4 | ||
|
|
ae5586408f | ||
|
|
a4342fd5ba | ||
|
|
1a6677bdc3 | ||
|
|
6eee6c181d | ||
|
|
5c8f2d4e69 | ||
|
|
15f59b54dd | ||
|
|
e87041bcfc | ||
|
|
1804466334 | ||
|
|
a9301ea1d0 | ||
|
|
a0770580e9 | ||
|
|
ee71b2044e | ||
|
|
665363b356 | ||
|
|
b68eccf784 | ||
|
|
62f9c3def0 | ||
|
|
a360ef7c8d | ||
|
|
9f9f772ff5 | ||
|
|
c4b240170d | ||
|
|
7006a14031 | ||
|
|
d46c64f64b | ||
|
|
5bd3cfc4f6 | ||
|
|
2e172a1053 | ||
|
|
2f5345e10d | ||
|
|
2a4b04bac6 | ||
|
|
30e931f10b | ||
|
|
266fadcb96 | ||
|
|
475f624113 | ||
|
|
de76ab97fb | ||
|
|
414c91a637 | ||
|
|
adce07785a | ||
|
|
1479f73612 | ||
|
|
5e8c478b2c | ||
|
|
db056f8730 | ||
|
|
f5dc8fc80d | ||
|
|
fa011c3d97 | ||
|
|
fdc10e4e5f | ||
|
|
73ce16fc52 | ||
|
|
b5a8cfb704 | ||
|
|
dc82553fc3 | ||
|
|
1df033dce8 | ||
|
|
2c0b50a7e9 | ||
|
|
9bae54f917 | ||
|
|
9eac8ef266 | ||
|
|
24d615d428 | ||
|
|
99410217b9 | ||
|
|
46cb6e68f6 | ||
|
|
8b88dc6a94 | ||
|
|
d6b36bb487 | ||
|
|
b8d918d24f | ||
|
|
b19cfba98e | ||
|
|
c497eef3b3 | ||
|
|
57812616b9 | ||
|
|
b43386b273 | ||
|
|
f8f7ca1d57 | ||
|
|
105ad369ab | ||
|
|
ff724634f2 | ||
|
|
0b8eb6ad90 | ||
|
|
66292a2787 | ||
|
|
12d5474077 | ||
|
|
8328bce3f6 | ||
|
|
c62c943bdb | ||
|
|
ceccf1b48a | ||
|
|
6af7388ac0 | ||
|
|
d16d5b290a | ||
|
|
fbd9501c61 | ||
|
|
578b24ae8a | ||
|
|
5b2c0110dc | ||
|
|
98fbe5127b | ||
|
|
8e2fdc178b | ||
|
|
757df39941 | ||
|
|
dfad907530 | ||
|
|
04d1075db5 | ||
|
|
8a138fafd4 | ||
|
|
819ab5cd0c | ||
|
|
dead7caab2 | ||
|
|
14542f4fc8 | ||
|
|
8a52374951 | ||
|
|
cfc615a6c1 | ||
|
|
af0690fb88 | ||
|
|
c80aaa2980 | ||
|
|
521f61d7db | ||
|
|
2d1f70c1cf | ||
|
|
327c7bc3cc | ||
|
|
9e2842c9ca | ||
|
|
7457eccdee | ||
|
|
2942eae9f2 | ||
|
|
87cb2ece80 | ||
|
|
042074cab1 | ||
|
|
bd81b24b99 | ||
|
|
bb2f3a82d9 | ||
|
|
cda129b073 | ||
|
|
adb130cefa | ||
|
|
860b15ef8a | ||
|
|
1679115302 | ||
|
|
8395745cc1 | ||
|
|
dd706ea6e2 | ||
|
|
6856d203c5 | ||
|
|
29471ff8b5 | ||
|
|
2495583b5e | ||
|
|
0b780def24 | ||
|
|
5a50ce4157 | ||
|
|
4b9f78e375 | ||
|
|
c9b549ae69 | ||
|
|
bb0e68e563 | ||
|
|
0663b9dae2 | ||
|
|
2ce42af6e4 | ||
|
|
47463ae5cb | ||
|
|
d813537e38 | ||
|
|
7148f6d144 | ||
|
|
52d596e576 | ||
|
|
1f849ec7b0 | ||
|
|
610ab0c0a5 | ||
|
|
4e93b567e2 | ||
|
|
2d6dd9f4d2 | ||
|
|
eb31df2940 | ||
|
|
99f6bf045f | ||
|
|
fac9ea3356 | ||
|
|
246d6cbcf7 | ||
|
|
29c6d1e46f | ||
|
|
92c76bac2b | ||
|
|
dbbc35bd13 | ||
|
|
dab9dad9db | ||
|
|
4176d542a5 | ||
|
|
e19c50223b | ||
|
|
5bdc200376 | ||
|
|
f2c8ea085b | ||
|
|
d8d0f15ca8 | ||
|
|
38a871aa4b | ||
|
|
e8d648bcba | ||
|
|
c7562dbfd0 | ||
|
|
54c948409e | ||
|
|
70a83ad069 | ||
|
|
e98953a5a5 | ||
|
|
78b856268e | ||
|
|
1d1db66abd | ||
|
|
b6787a9b34 | ||
|
|
7eecb84898 | ||
|
|
0c99f3baa6 | ||
|
|
72d6a13e9e | ||
|
|
43e44f8c35 | ||
|
|
4e82f4c672 | ||
|
|
7fa1296a17 | ||
|
|
f1ad8836d1 | ||
|
|
4834eed520 | ||
|
|
0f15dd04af | ||
|
|
0b8efc434d | ||
|
|
3f3e66916a | ||
|
|
fd9a8f4b91 | ||
|
|
ac6c2ce69a | ||
|
|
e81baf759a | ||
|
|
b28a241dbf | ||
|
|
afd4052bde | ||
|
|
a8c227d5f5 | ||
|
|
9646c28a41 | ||
|
|
3678f13dfb | ||
|
|
98a7f08be2 | ||
|
|
3b3a025ed4 | ||
|
|
64622ceae3 | ||
|
|
06d681c66a | ||
|
|
c8738a88a4 | ||
|
|
faf40457c5 | ||
|
|
353b485202 | ||
|
|
8e94856cc8 | ||
|
|
b9f6d6dffc | ||
|
|
8093300a43 | ||
|
|
da407200d2 | ||
|
|
443a4b8f2f | ||
|
|
509ce0d5cb | ||
|
|
903ff0b61a | ||
|
|
2ca6be69e2 | ||
|
|
054b6a9817 | ||
|
|
6556602bdc | ||
|
|
2876f15063 | ||
|
|
85f5ef2ab1 | ||
|
|
53fca43d89 | ||
|
|
549df36f00 | ||
|
|
aae576b484 | ||
|
|
b76615f3e7 | ||
|
|
878d25e91e | ||
|
|
ab315e502f | ||
|
|
564c0b41df | ||
|
|
382a00493b | ||
|
|
f0924df68a | ||
|
|
6b37f30bd6 | ||
|
|
86de75deef | ||
|
|
bedd0a11ba | ||
|
|
778078973b | ||
|
|
a26976a161 | ||
|
|
8a7acfc6c0 | ||
|
|
03a88883b6 | ||
|
|
59a8be53c2 | ||
|
|
f55379ed5b | ||
|
|
ef869fb2ff | ||
|
|
1b9649b481 | ||
|
|
fa6d499a4e | ||
|
|
0afac1e05a | ||
|
|
66f2d18d8b | ||
|
|
b75bfe0e92 | ||
|
|
1cae81c0d6 | ||
|
|
92ab227397 | ||
|
|
076535bc06 | ||
|
|
071a55974a | ||
|
|
c21c89c0ce | ||
|
|
8e6e1610a4 | ||
|
|
0b694dffd8 | ||
|
|
7c8bed7bfc | ||
|
|
209840871c | ||
|
|
ea99037f3b | ||
|
|
331d0481bb | ||
|
|
2c61070b36 | ||
|
|
502c0f0df7 | ||
|
|
aa49e4790f | ||
|
|
3490ce507a | ||
|
|
c1f3d22910 | ||
|
|
f1bca5dd0f | ||
|
|
7861eec426 | ||
|
|
a02707f998 | ||
|
|
f214e88784 | ||
|
|
45e2dd2ab5 | ||
|
|
f905bb64f6 | ||
|
|
8612ad0459 | ||
|
|
3bbcc1efd8 | ||
|
|
6dac8da91f | ||
|
|
137f3b8439 | ||
|
|
b77ed51594 | ||
|
|
d17e6a3857 | ||
|
|
a2c38ed48c | ||
|
|
93a24ec672 | ||
|
|
11cb777e35 | ||
|
|
27011ad0c8 | ||
|
|
c6fabf8613 | ||
|
|
6e469df90e | ||
|
|
0c0a6bd939 | ||
|
|
3f8ad3bf75 | ||
|
|
afd6f41e08 | ||
|
|
0a393eaa1c | ||
|
|
b1bb7bd8f3 | ||
|
|
45bfbb7cf6 | ||
|
|
5083a7505d | ||
|
|
fd2b2003b4 | ||
|
|
23b5c1f782 | ||
|
|
37d278de34 | ||
|
|
24b5faf8df | ||
|
|
8b712bac8d | ||
|
|
a1f26c4c93 | ||
|
|
13c887d4c9 | ||
|
|
2ed7d58ac4 | ||
|
|
b51e2f6453 | ||
|
|
17c191201c | ||
|
|
4217b70331 | ||
|
|
8947d54cc9 | ||
|
|
f829f2eb0c | ||
|
|
0087f8da27 | ||
|
|
dd606684c7 | ||
|
|
12998399f8 | ||
|
|
c09ba6efdb | ||
|
|
7df1957ac7 | ||
|
|
241e410a07 | ||
|
|
68cfe80369 | ||
|
|
88d7ad95f6 | ||
|
|
02c04cbf68 | ||
|
|
5523938a47 | ||
|
|
fbe1abddf4 | ||
|
|
9a14d2bd0e | ||
|
|
86644543ed | ||
|
|
a9c720969f | ||
|
|
3dd9e4cdf8 | ||
|
|
9a5698807f | ||
|
|
92142ee372 | ||
|
|
715ac35672 | ||
|
|
750db6aed8 | ||
|
|
5c78ecfe40 | ||
|
|
43421aedcf | ||
|
|
13ed038082 | ||
|
|
de151cef8e | ||
|
|
5bfe644c3e | ||
|
|
20431f4f2f | ||
|
|
ad16e9ea49 | ||
|
|
a10782cdea | ||
|
|
c14c6a3521 | ||
|
|
6c62895898 | ||
|
|
134aa32612 | ||
|
|
0a59384003 | ||
|
|
c2b109f7fc | ||
|
|
a755edebfa | ||
|
|
76fc62808c | ||
|
|
54ab6744f1 | ||
|
|
2d262d2dbd | ||
|
|
de99c38fb6 | ||
|
|
91320a9e55 | ||
|
|
0bcc9b7713 | ||
|
|
33b6876cc1 | ||
|
|
81b370ee9f | ||
|
|
fe81e5b32d | ||
|
|
4ba3e101f6 | ||
|
|
7210f6e64d | ||
|
|
ef15b670a9 | ||
|
|
706f547287 | ||
|
|
f142f572c3 | ||
|
|
7e33e26465 | ||
|
|
5e58915bdd | ||
|
|
854c59df5c | ||
|
|
f6db9bc84c | ||
|
|
b8d0c5b3fe | ||
|
|
23760058e9 | ||
|
|
7b621262ea | ||
|
|
62756a79df | ||
|
|
87cd762eb3 | ||
|
|
74566375b5 | ||
|
|
5d9b538513 | ||
|
|
7c0f414881 | ||
|
|
62d2b90e18 | ||
|
|
69092eee15 | ||
|
|
96f24b88ea | ||
|
|
3d858bee95 | ||
|
|
0933a7d1b2 | ||
|
|
fe78c17ea6 | ||
|
|
79a233436b | ||
|
|
3da347a783 | ||
|
|
ff856e679d | ||
|
|
7fbf4246ac | ||
|
|
42077999e9 | ||
|
|
e75950cb89 | ||
|
|
4604c9bb0e | ||
|
|
8aa5b97c61 | ||
|
|
ce52a87477 | ||
|
|
9a04f67c0a | ||
|
|
3d398458a8 | ||
|
|
dec3e37683 | ||
|
|
a988b48016 | ||
|
|
d31df439c3 | ||
|
|
06da5f254a | ||
|
|
2d1afbf51b | ||
|
|
45c26e0e5a | ||
|
|
c6fb645f6b | ||
|
|
e8f1f6819c | ||
|
|
c59bd82f6f | ||
|
|
b2be9373b0 | ||
|
|
f81df9a5d3 | ||
|
|
51c03c3a71 | ||
|
|
4f6ee31a28 | ||
|
|
1746518cdf | ||
|
|
b3c3556286 | ||
|
|
50b96ca7ef | ||
|
|
7749484628 | ||
|
|
b5898d3355 | ||
|
|
809c995c0b | ||
|
|
551c39e241 | ||
|
|
97070246b7 | ||
|
|
029ee9aa1e | ||
|
|
509294b228 | ||
|
|
ab9e1dd650 | ||
|
|
0ac2443eb0 | ||
|
|
136b3da458 | ||
|
|
9f5ed14f24 | ||
|
|
482c740e61 | ||
|
|
1a1cf57097 | ||
|
|
f6f5ff4330 | ||
|
|
6a11eccc3e | ||
|
|
2d6dc9c527 | ||
|
|
65d2540807 | ||
|
|
834d28f528 | ||
|
|
b4ba4a908e | ||
|
|
bda3711815 | ||
|
|
b4cdb546fe | ||
|
|
7ab5db1adb | ||
|
|
1926c2cd01 | ||
|
|
21ba5b867d | ||
|
|
1a80bc786d | ||
|
|
6a532292c4 | ||
|
|
c8ed581e5c | ||
|
|
c0f0f4cdc6 | ||
|
|
b83f042363 | ||
|
|
bce8a3f835 | ||
|
|
2d5b17552a | ||
|
|
19d6d171b1 | ||
|
|
09acb9032a | ||
|
|
3dfc496243 | ||
|
|
506237f5d6 | ||
|
|
609e3ec3ff | ||
|
|
640c8f88ff | ||
|
|
d0ed681643 | ||
|
|
5656714b27 | ||
|
|
ecb9e93394 | ||
|
|
708e738521 | ||
|
|
8457090b18 | ||
|
|
513052de87 | ||
|
|
d65919d896 | ||
|
|
895ccf69a7 | ||
|
|
3063b5189a | ||
|
|
335cd79b37 | ||
|
|
e3bad233e9 | ||
|
|
7abb08cc25 | ||
|
|
31bdfc2281 | ||
|
|
bf14f67cb8 | ||
|
|
ef7a60807b | ||
|
|
f17673be9c | ||
|
|
079f81b304 | ||
|
|
ab83b21fa6 | ||
|
|
3d7da455bc | ||
|
|
ac8a9afada | ||
|
|
8faab22f5e | ||
|
|
40679ae82c | ||
|
|
f972c38bc8 | ||
|
|
e1f0f02da9 | ||
|
|
b4d9c92705 | ||
|
|
44b932f90b | ||
|
|
c5411c3291 | ||
|
|
7dc8ede90f | ||
|
|
b94375c794 | ||
|
|
45c2cda6bb | ||
|
|
5c65f037b0 | ||
|
|
de55d8c292 | ||
|
|
a9d67e9715 | ||
|
|
9bd517e623 | ||
|
|
22d5d40a66 | ||
|
|
3f307ea8a6 | ||
|
|
ded58b8e65 | ||
|
|
6939567cb4 | ||
|
|
1a34e09a45 | ||
|
|
85685feff4 | ||
|
|
4ca0458b37 | ||
|
|
effcf18d56 | ||
|
|
5b312e8f64 | ||
|
|
8506725b54 | ||
|
|
45c41fe880 | ||
|
|
4fc73117c4 | ||
|
|
9593c71f52 | ||
|
|
a23218c51d | ||
|
|
70225009af | ||
|
|
80bea0766e | ||
|
|
54933f992a | ||
|
|
c0bf2facca | ||
|
|
d642fe6075 | ||
|
|
e7dfd48b1c | ||
|
|
90b2d12371 | ||
|
|
f6c66e7ece | ||
|
|
c6a18b1b59 | ||
|
|
6cdc8e4b96 | ||
|
|
598060dfd8 | ||
|
|
b801a93dc5 | ||
|
|
dc9329ff43 | ||
|
|
a61331a083 | ||
|
|
f1fbc5c701 | ||
|
|
896077222d | ||
|
|
47d7a355f2 | ||
|
|
a1ae399d10 | ||
|
|
48b0d85f54 | ||
|
|
423d269187 | ||
|
|
da54ac5f55 | ||
|
|
a26091e485 | ||
|
|
40ab21d9df | ||
|
|
947e6aca9b | ||
|
|
c92d2531b5 | ||
|
|
6d168b89ef | ||
|
|
55c8206bda | ||
|
|
c01e3cf9aa | ||
|
|
040049f9e7 | ||
|
|
2fc1e2a4e6 | ||
|
|
eaacf0a6ef | ||
|
|
c2975d2bcc | ||
|
|
60df32aab5 | ||
|
|
fd596d4a65 | ||
|
|
5142b7858b | ||
|
|
a8f5a4e2d4 | ||
|
|
d46300587a | ||
|
|
64a41b65bb | ||
|
|
275ac2c4b6 | ||
|
|
c0285747a2 | ||
|
|
95793e410d | ||
|
|
31d606220e | ||
|
|
4fc14959a8 | ||
|
|
95dd73bd1d | ||
|
|
5bed184014 | ||
|
|
4fa7e8e914 | ||
|
|
63e83a7ef8 | ||
|
|
c20e1e9d82 | ||
|
|
253bacdf1d | ||
|
|
98127ba13c | ||
|
|
cb911b19dd | ||
|
|
d50eeb04d5 | ||
|
|
1641caf353 | ||
|
|
23951e6ef3 | ||
|
|
c9a5c6515c | ||
|
|
0ab32bfe17 | ||
|
|
3d30e6ddc4 | ||
|
|
ffdf2f7fcf | ||
|
|
974415f8a1 | ||
|
|
3105092130 | ||
|
|
85b0885af7 | ||
|
|
11cd301127 | ||
|
|
654d21100f | ||
|
|
5bd924a52d | ||
|
|
186d34c33a | ||
|
|
b0a414ea83 | ||
|
|
099eb53d3c | ||
|
|
e3ccb18696 | ||
|
|
e38614ce31 | ||
|
|
290dd4ccd8 | ||
|
|
1bebf1cc2c | ||
|
|
d8d9dea792 | ||
|
|
7457f81283 | ||
|
|
158d8efb8e | ||
|
|
0b668b8e17 | ||
|
|
5437470b4e | ||
|
|
409f2b4d0f | ||
|
|
64edede20d | ||
|
|
6624fd9a1b | ||
|
|
1cdbb6f186 | ||
|
|
f57533fa0e | ||
|
|
2db7c84cbc | ||
|
|
cefc846e9e | ||
|
|
1853bef39a | ||
|
|
22c4911b58 | ||
|
|
e58b3ddc86 | ||
|
|
e3ba17f2d3 | ||
|
|
7d1830d014 | ||
|
|
da3a988c8c | ||
|
|
9d23cce2b6 | ||
|
|
68381e1b76 | ||
|
|
3493d2c701 | ||
|
|
9e1d3f9e27 | ||
|
|
7fdd94520e | ||
|
|
9fcb6b2cd1 | ||
|
|
cbafac774e | ||
|
|
7f5fb4e6f9 | ||
|
|
ac51207860 | ||
|
|
aa3be09ab0 | ||
|
|
4348143fd9 | ||
|
|
b6b8b936f2 | ||
|
|
2c27b953b5 | ||
|
|
d7eae69587 | ||
|
|
e0f1433c12 | ||
|
|
27710cd4f7 | ||
|
|
4d5bbbc2d7 | ||
|
|
da900b3094 | ||
|
|
0f29d9f30f | ||
|
|
b88824a70c | ||
|
|
882a08f61a | ||
|
|
a9072049ea | ||
|
|
e87876671f | ||
|
|
d0f6c89e77 | ||
|
|
8eab230fe1 | ||
|
|
7ff95ec255 | ||
|
|
20afd51a9d | ||
|
|
19bba5c18c | ||
|
|
bf4c219766 | ||
|
|
a5e1d8c97f | ||
|
|
7bc364a374 | ||
|
|
5dd73e74cb | ||
|
|
ba347f6460 | ||
|
|
85cf8f9174 | ||
|
|
2153e018a3 | ||
|
|
3f4fec0864 | ||
|
|
10823eeeaa | ||
|
|
25ea169c72 | ||
|
|
743e8331b5 | ||
|
|
d309fd5a27 | ||
|
|
091357ad8e | ||
|
|
3d4491a468 | ||
|
|
6d32db32ef | ||
|
|
357f5f9781 | ||
|
|
a0f5544a07 | ||
|
|
6c9dbe190d | ||
|
|
29b8cd8df7 | ||
|
|
f78f94d4f1 | ||
|
|
ef8b20af65 | ||
|
|
9f99209733 | ||
|
|
ee3fa67c48 | ||
|
|
a3327ac53e | ||
|
|
210c97f957 | ||
|
|
8097cb2b9e | ||
|
|
2650e34867 | ||
|
|
9f0b5a14a4 | ||
|
|
a8b4e5faec | ||
|
|
f6c66a7374 | ||
|
|
86cf5e0028 | ||
|
|
89de5b6e9a | ||
|
|
ff26c3c16f | ||
|
|
8a736abac7 | ||
|
|
0397b282c0 | ||
|
|
d50a2b810d | ||
|
|
c5de8ea7bf | ||
|
|
c06e844ef4 | ||
|
|
c6a16161d9 | ||
|
|
46e6b5ec3e | ||
|
|
0fd1f61a24 | ||
|
|
d8de9754d6 | ||
|
|
b00bbdeb81 | ||
|
|
0ab4475f24 | ||
|
|
5137e16485 | ||
|
|
bf85e61dc2 | ||
|
|
91a3e12ab0 | ||
|
|
6aa6bdebe6 | ||
|
|
1af0e0a762 | ||
|
|
03f19bea6b | ||
|
|
85a3e06718 | ||
|
|
8278d8b51a | ||
|
|
c19abed4fa | ||
|
|
cef5f06ceb | ||
|
|
a666014990 | ||
|
|
5a8678b191 | ||
|
|
271eb63083 | ||
|
|
28ca883805 | ||
|
|
3c7e5e47b8 | ||
|
|
588cc3c7ab | ||
|
|
b77e6c369a | ||
|
|
06cc27c6b3 | ||
|
|
73ee24bd98 | ||
|
|
84fcfd1fac | ||
|
|
cd5007cfa1 | ||
|
|
172c55d194 | ||
|
|
60bd20872c | ||
|
|
b2aaffa921 | ||
|
|
438d7ada49 | ||
|
|
a9b1b567fb | ||
|
|
2f530f7049 | ||
|
|
dfcad75a27 | ||
|
|
a0034521da | ||
|
|
e4d9dbcfa2 | ||
|
|
ac914e1f19 | ||
|
|
bed09839d5 | ||
|
|
8951572366 | ||
|
|
8a73d91ea1 | ||
|
|
879de42372 | ||
|
|
32b8366d30 | ||
|
|
95662d4233 | ||
|
|
2f36216cb0 | ||
|
|
2513358eb5 | ||
|
|
21fa395b61 | ||
|
|
afde383e28 | ||
|
|
ee9964c141 | ||
|
|
bf66aeb8ee | ||
|
|
f706bb45cb | ||
|
|
0b1b0940d2 | ||
|
|
0db2769781 | ||
|
|
47c18fef7f | ||
|
|
48412769df | ||
|
|
528f7bd45f | ||
|
|
78322b5231 | ||
|
|
c23ba7b504 | ||
|
|
6aa69a06c8 | ||
|
|
0e94977d42 | ||
|
|
ba4f502b1e | ||
|
|
651dabf47e | ||
|
|
af72842728 | ||
|
|
49ac363eef | ||
|
|
66bbf00b7a | ||
|
|
0398316192 | ||
|
|
b428b2eb99 | ||
|
|
ab6cb042f6 | ||
|
|
9c8b3e3c2e | ||
|
|
b27abd2011 | ||
|
|
bf1a4e12f1 | ||
|
|
20acead8be | ||
|
|
d07482c5f6 | ||
|
|
26ac34d0e0 | ||
|
|
b7816d85a1 | ||
|
|
c99b20206c | ||
|
|
d97155d7b0 | ||
|
|
10af87008d | ||
|
|
ed633b3250 | ||
|
|
e0fddcb7ce | ||
|
|
aa55e397d4 | ||
|
|
7943f7f7eb | ||
|
|
869e086a41 | ||
|
|
a96618e5cd | ||
|
|
02b2459db6 | ||
|
|
bef6909218 | ||
|
|
1ade8dcee7 | ||
|
|
e1e1c173fe | ||
|
|
5ee805e451 | ||
|
|
f2b91d5e1d | ||
|
|
1cd3918494 | ||
|
|
cb8f975528 | ||
|
|
42afc071eb | ||
|
|
79d4724a15 | ||
|
|
e699cac92c | ||
|
|
a3d2a490da | ||
|
|
58795eaa7e | ||
|
|
9f29f66768 | ||
|
|
14d01544d4 | ||
|
|
cf7cf098d8 | ||
|
|
e9636bb87b | ||
|
|
c82f5c8da8 | ||
|
|
246a145930 | ||
|
|
c9371bceec | ||
|
|
bd1f0e78a8 | ||
|
|
90c24de0f0 | ||
|
|
5cb97545fd | ||
|
|
db8361a0a9 | ||
|
|
57bfc63d23 | ||
|
|
fbd74c0e2d | ||
|
|
993c52dcd5 | ||
|
|
f5a8ec0cd3 | ||
|
|
747698fe9b | ||
|
|
e0dae4054a | ||
|
|
070d26e68e | ||
|
|
e6830e9ac8 | ||
|
|
aba3b721c5 | ||
|
|
62fd76f7e4 | ||
|
|
66e96f69fc | ||
|
|
9a825c5cbd | ||
|
|
02bcdc1c19 | ||
|
|
f13d8407ee | ||
|
|
739c432c98 | ||
|
|
94084639f2 | ||
|
|
e6f748d77f | ||
|
|
212cd67f08 | ||
|
|
90480fff4e | ||
|
|
4a1b6d76b2 | ||
|
|
6d663d1d01 | ||
|
|
e5e94ed437 | ||
|
|
621867e518 | ||
|
|
716037544a | ||
|
|
b92d5071fa | ||
|
|
ef255db069 | ||
|
|
24f8c51959 | ||
|
|
4b20ac3dc6 | ||
|
|
34521e5880 | ||
|
|
45fb3ec41d | ||
|
|
caa0634df8 | ||
|
|
15a05b3639 | ||
|
|
edcae49e52 | ||
|
|
81283db2da | ||
|
|
f56d1ea7b4 | ||
|
|
fea5559fbc | ||
|
|
b360122b35 | ||
|
|
185d3a7c02 | ||
|
|
f90fb8cc72 | ||
|
|
111dcbac25 | ||
|
|
e28bdcdd46 | ||
|
|
395b0c4224 | ||
|
|
217b1afe87 | ||
|
|
8d8bfcd120 | ||
|
|
2637cafda5 | ||
|
|
c764b7b023 | ||
|
|
522ae765ea | ||
|
|
9cf3811a56 | ||
|
|
6d2cc8aedf | ||
|
|
058046304d | ||
|
|
7ff0e0214e | ||
|
|
2be5393768 | ||
|
|
b54caccb22 | ||
|
|
c499dfbb22 | ||
|
|
f6ba308ff8 | ||
|
|
10e195a444 | ||
|
|
490a12d38a | ||
|
|
e004d53d2a | ||
|
|
4788323582 | ||
|
|
80d574482e | ||
|
|
d1724ad733 | ||
|
|
1fbe05b2d5 | ||
|
|
c5212b36f7 | ||
|
|
033212841d | ||
|
|
22c5720aa2 | ||
|
|
f29c7164f3 | ||
|
|
013593ccf8 | ||
|
|
77724345c4 | ||
|
|
4c12a4369d | ||
|
|
a3a21b5b88 | ||
|
|
48d54e8d3a | ||
|
|
4ebe58df57 | ||
|
|
accd08a2bf | ||
|
|
1731d609b7 | ||
|
|
cf9f249f07 | ||
|
|
92cfd96933 | ||
|
|
6c3f065147 | ||
|
|
45f4a25ac9 | ||
|
|
f43c227806 | ||
|
|
490efe69f4 | ||
|
|
368d23ef5b | ||
|
|
5e99c8f280 | ||
|
|
914dce6cc2 | ||
|
|
c6697f5f07 | ||
|
|
b6b6fc3bfd | ||
|
|
de49498102 | ||
|
|
14c9a2a087 | ||
|
|
a4a390b2cc | ||
|
|
0f5a058bdd | ||
|
|
7d15aa2321 | ||
|
|
9b1bcf51c6 | ||
|
|
b710cc3063 | ||
|
|
1c91b4888a | ||
|
|
996e2bdc69 | ||
|
|
9ed6ad8165 | ||
|
|
c0cd8fca80 | ||
|
|
25f69df341 | ||
|
|
35e5c2172f | ||
|
|
41b6f682d8 | ||
|
|
0c21c863d7 | ||
|
|
c71aa0995a | ||
|
|
8359c8e194 | ||
|
|
209dcd1aca | ||
|
|
eaa5e136b6 | ||
|
|
89990ec037 | ||
|
|
cc9ff77dd2 | ||
|
|
f44be28309 | ||
|
|
7f4d00fac0 | ||
|
|
bdad1d1753 | ||
|
|
64ce44d341 | ||
|
|
6f41598962 | ||
|
|
9c92f2e692 | ||
|
|
fefeb39757 | ||
|
|
389e56ce36 | ||
|
|
94818aef26 | ||
|
|
e9b344b200 | ||
|
|
fb864a8f23 | ||
|
|
cf4c2d02f3 | ||
|
|
b3dc0bc57e | ||
|
|
0839915538 | ||
|
|
9e32570dfa | ||
|
|
404e08c0e7 | ||
|
|
10a8f3c884 | ||
|
|
9f8ad36f30 | ||
|
|
8a4e0a64cf | ||
|
|
db071f8d8e | ||
|
|
24b4fcea15 | ||
|
|
e110f5c37c | ||
|
|
1a93babdbc | ||
|
|
22e3b9df44 | ||
|
|
d596a7427e | ||
|
|
81170d81b3 | ||
|
|
e7825da0f8 | ||
|
|
f629fa7b27 | ||
|
|
04f1860bf5 | ||
|
|
69bcc8e831 | ||
|
|
194ed3884c | ||
|
|
d8447524cb | ||
|
|
915a6196cc | ||
|
|
623e3ebc03 | ||
|
|
485bd7bbd3 | ||
|
|
218d69d288 | ||
|
|
d63f44cd07 | ||
|
|
2d56067819 | ||
|
|
a96cde254b | ||
|
|
e214ce6bc4 | ||
|
|
1f08d50e98 | ||
|
|
07a8a50861 | ||
|
|
46ed83a057 | ||
|
|
e95c1256a0 | ||
|
|
c0955eaa90 | ||
|
|
58a38d90b8 | ||
|
|
4ccb0cccf3 | ||
|
|
4f43c41577 | ||
|
|
6336edbe92 | ||
|
|
ce793ec86d | ||
|
|
993f66bd02 | ||
|
|
39e75574f4 | ||
|
|
2d8fe489a7 | ||
|
|
5b167e3684 | ||
|
|
dacbf7a042 | ||
|
|
81599f1535 | ||
|
|
a22a5c67bd | ||
|
|
d34cff2eef | ||
|
|
c72d769ff0 | ||
|
|
97139b7487 | ||
|
|
d26dcd5501 | ||
|
|
380de24f2e | ||
|
|
e7c7e086b1 | ||
|
|
645f81effd | ||
|
|
f39224a56b | ||
|
|
0d19e772e6 | ||
|
|
2844d3b358 | ||
|
|
fe3489b383 | ||
|
|
f6ff97cbeb | ||
|
|
779e5c2ea5 | ||
|
|
0d957cc68e | ||
|
|
4b75b10542 | ||
|
|
b09252f13e | ||
|
|
b06d59fcb2 | ||
|
|
5162275b9b | ||
|
|
f82de6528b | ||
|
|
593dce23a5 | ||
|
|
ef417cb8c2 | ||
|
|
ab652b738c | ||
|
|
53b83eba8c | ||
|
|
cbe52c58ac | ||
|
|
19c8864c32 | ||
|
|
141894aacd | ||
|
|
cb9bdbf247 | ||
|
|
4b5dd2ed4b | ||
|
|
85afa851dd | ||
|
|
57acdc1bf6 | ||
|
|
ae76657e17 | ||
|
|
4ca6ac34ac | ||
|
|
e4a71b86df | ||
|
|
4dd7848084 | ||
|
|
a95679c212 | ||
|
|
b41d356143 | ||
|
|
feb6a93881 | ||
|
|
940b40439f | ||
|
|
ed07bd202f | ||
|
|
8c29ffd084 | ||
|
|
dba2fa31b6 | ||
|
|
2de80571d8 | ||
|
|
51acba594b | ||
|
|
a194d45dfa | ||
|
|
9356296a84 | ||
|
|
2fa0b1117c | ||
|
|
49814e1919 | ||
|
|
74da83a0bb | ||
|
|
643d1dcdd1 | ||
|
|
b717add81b | ||
|
|
c36c4e36c5 | ||
|
|
0b48c3ea90 | ||
|
|
68e28159bb | ||
|
|
69a89303d0 | ||
|
|
9e87037d34 | ||
|
|
7cd4d35778 | ||
|
|
8296178e33 | ||
|
|
32dff999a5 | ||
|
|
13e5cf32d5 | ||
|
|
11d9e522d5 | ||
|
|
4aac0d6d1c | ||
|
|
ddf4f14dba | ||
|
|
b560176aeb | ||
|
|
802f964cd3 | ||
|
|
0c349c047d | ||
|
|
d4e3c39fa5 | ||
|
|
3a177d55f8 | ||
|
|
b2741a8316 | ||
|
|
909f1bcf3c | ||
|
|
009412d738 | ||
|
|
33c622ec86 | ||
|
|
05b602d0ce | ||
|
|
8519ea3299 | ||
|
|
aad46b0894 | ||
|
|
5dfbaebd4c | ||
|
|
b2b70bb37c | ||
|
|
35d37c3463 | ||
|
|
eea82efbf8 | ||
|
|
7659edd139 | ||
|
|
9f8a5a7af3 | ||
|
|
cc4897f8c1 | ||
|
|
ee5335ca6e | ||
|
|
dde8e47add | ||
|
|
0040f07097 | ||
|
|
64b2c9b36c | ||
|
|
d754b2bda7 | ||
|
|
9dd68c7add | ||
|
|
1499d44584 | ||
|
|
039903c6b2 | ||
|
|
5df1716144 | ||
|
|
f6d6a12c1a | ||
|
|
e316e4a267 | ||
|
|
9d84f139eb | ||
|
|
ad70cb27bd | ||
|
|
98fec2f317 | ||
|
|
72fc1e8dc6 | ||
|
|
301014e4a6 | ||
|
|
927ec6ab7a | ||
|
|
37d45e2881 | ||
|
|
915c1b19d3 | ||
|
|
b87dfb964c | ||
|
|
885ac53a48 | ||
|
|
d77bf0440c | ||
|
|
5a0be6672d | ||
|
|
724cae7de1 | ||
|
|
6c9769999b | ||
|
|
2bf2ad094c | ||
|
|
3eaf0fe82b | ||
|
|
013e7fb611 | ||
|
|
e24976c59f | ||
|
|
e3ae062c5c | ||
|
|
5e6e173d59 | ||
|
|
3fcd571db0 | ||
|
|
988fa73696 | ||
|
|
3c412e1cb8 | ||
|
|
a579f58454 | ||
|
|
35e867820e | ||
|
|
a757c62da5 | ||
|
|
370dd26745 | ||
|
|
e20697b870 | ||
|
|
4d01aa2772 | ||
|
|
4a485f9819 | ||
|
|
cebafeae40 | ||
|
|
150739e19e | ||
|
|
38f83cacf9 | ||
|
|
fc8ff314e2 | ||
|
|
8acf96d268 | ||
|
|
c49a44f944 | ||
|
|
390b804ca0 | ||
|
|
05317ad81e | ||
|
|
d559275711 | ||
|
|
909ff085ac | ||
|
|
dbbfef38b1 | ||
|
|
4006b6407c | ||
|
|
c95a93ef1c | ||
|
|
e5e1e207b6 | ||
|
|
e0c469183d | ||
|
|
4d2e4ed573 | ||
|
|
0cab034dab | ||
|
|
9f9d209e3d | ||
|
|
8740147aa2 | ||
|
|
9b755620d3 | ||
|
|
fa287c2422 | ||
|
|
b6cded379e | ||
|
|
8199ad2ae6 | ||
|
|
0d09143a77 | ||
|
|
7081f7799b | ||
|
|
b6583635d4 | ||
|
|
b01db4aa09 | ||
|
|
6d712da7e3 | ||
|
|
9b71117171 | ||
|
|
50ea0f0b45 | ||
|
|
fa8e158587 | ||
|
|
2768b1ff64 | ||
|
|
b3770bc407 | ||
|
|
8f44046f9a | ||
|
|
a717235212 | ||
|
|
805215be78 | ||
|
|
e7fbe84644 | ||
|
|
9653f20995 | ||
|
|
e959a40b49 | ||
|
|
d9ce3f0ca3 | ||
|
|
d8f57a0ecc | ||
|
|
c5e0b65cc7 | ||
|
|
b5e82dac6f | ||
|
|
1381d16f9c | ||
|
|
268508764f | ||
|
|
34109fa741 | ||
|
|
925ff2da5b | ||
|
|
b8a6658ba9 | ||
|
|
4a4814b41c | ||
|
|
f952dae0d0 | ||
|
|
cba155bcfb | ||
|
|
0f714c81cd | ||
|
|
92b5dab3f9 | ||
|
|
6ca238852a | ||
|
|
d2368d2d3b | ||
|
|
88269a613a | ||
|
|
5696fe8ec8 | ||
|
|
ba439b6824 | ||
|
|
c8a8576970 | ||
|
|
67cbecaba0 | ||
|
|
ec1db0c7bb | ||
|
|
4330d67e0d | ||
|
|
db8de9e60d | ||
|
|
9c9a306095 | ||
|
|
bda317b000 | ||
|
|
700510d63a | ||
|
|
ab2714fda9 | ||
|
|
33b94edcf0 | ||
|
|
44d3e58ddb | ||
|
|
f08c3f9134 | ||
|
|
8de90db429 | ||
|
|
81241b38eb | ||
|
|
1c07b9c85b | ||
|
|
1199224086 | ||
|
|
add4e3c6f5 | ||
|
|
eb55f1cf47 | ||
|
|
8367071dc6 | ||
|
|
68ac6b0cbb | ||
|
|
7fb1cb5b3d | ||
|
|
19b25c0d83 | ||
|
|
fd806f81ce | ||
|
|
d515404abd | ||
|
|
4509056d5e | ||
|
|
f604525b98 | ||
|
|
3afbb66b92 | ||
|
|
fadfd74923 | ||
|
|
222f8e1028 | ||
|
|
e3b6ea62d6 | ||
|
|
3795cc58b0 | ||
|
|
ed7d430f2b | ||
|
|
20f21b707b | ||
|
|
a584ca3678 | ||
|
|
ca881c5aaf | ||
|
|
2832708618 | ||
|
|
b00e56f587 | ||
|
|
d64f43da65 | ||
|
|
3e6d8ddbbd | ||
|
|
533548fdc7 | ||
|
|
3b95f49a14 | ||
|
|
d9d1d03d4d | ||
|
|
9546120ce4 | ||
|
|
48a5591508 | ||
|
|
a413935e91 | ||
|
|
241b07f763 | ||
|
|
d874ba80db | ||
|
|
3e46363ae1 | ||
|
|
d4a46fa35f | ||
|
|
134f8236cc | ||
|
|
55003716aa | ||
|
|
fe88330e87 | ||
|
|
ed68bd18b8 | ||
|
|
45228493eb | ||
|
|
80fb44b926 | ||
|
|
aa8f5e54df | ||
|
|
8134585578 | ||
|
|
a59388ecdd | ||
|
|
8051ad8b2a | ||
|
|
0a937cd2be | ||
|
|
db11c631f6 | ||
|
|
90bfd4bf0f | ||
|
|
39b98b0e4d | ||
|
|
b6c2e7ef76 | ||
|
|
fe96a9de33 | ||
|
|
b80f109524 | ||
|
|
cd40bdbec8 | ||
|
|
1533600720 | ||
|
|
263c4b9ab4 | ||
|
|
f1e72914f5 | ||
|
|
400d5cef3f | ||
|
|
af531d685e | ||
|
|
eb5f1f78bf | ||
|
|
c81a4bcafc | ||
|
|
1beeda170c | ||
|
|
9ad81c054d | ||
|
|
5604e75886 | ||
|
|
2e7ef7ea44 | ||
|
|
a0867fa7c5 | ||
|
|
31f5855001 | ||
|
|
0b24883649 | ||
|
|
4fda81a0b4 | ||
|
|
17c0888932 | ||
|
|
d20ec6952a | ||
|
|
e43b3309af | ||
|
|
d0c1b63064 | ||
|
|
a98e26a307 | ||
|
|
57d06c5241 | ||
|
|
f28e4574b0 | ||
|
|
c9b284d7f7 | ||
|
|
99a510701d | ||
|
|
eb3ecab6a8 | ||
|
|
11b9a06639 | ||
|
|
87d5b72b76 | ||
|
|
c95869e515 | ||
|
|
c2f7920068 | ||
|
|
cb7196a9c1 | ||
|
|
7de0f71a75 | ||
|
|
8dcb3726f9 | ||
|
|
d934526bb3 | ||
|
|
cab546cbb7 | ||
|
|
058d0bbe19 | ||
|
|
a32669ac0d | ||
|
|
cc4b3e9e6f | ||
|
|
fdcad1066e | ||
|
|
41d43920f9 | ||
|
|
fecc90e67c | ||
|
|
6e3b3fa5a2 | ||
|
|
c12c0363a0 | ||
|
|
1207dfde4c | ||
|
|
0f617c3d3c | ||
|
|
7b71ae6824 | ||
|
|
cfae3cd3af | ||
|
|
f470d21a55 | ||
|
|
af0a5744f2 | ||
|
|
2bcb7393c4 | ||
|
|
60dcb0e67f | ||
|
|
c88b691db7 | ||
|
|
27f07974e0 | ||
|
|
a840799b46 | ||
|
|
c8ef79817a | ||
|
|
29abba824d | ||
|
|
6ccec45c61 | ||
|
|
1dabd20d99 | ||
|
|
fedb08899c | ||
|
|
b8bfe8a9ad | ||
|
|
a230daa998 | ||
|
|
ba41634ad6 | ||
|
|
e9536508a5 | ||
|
|
965f2b1b6b | ||
|
|
e25417ab31 | ||
|
|
48c227c263 | ||
|
|
cbd6541e9a | ||
|
|
2a9f5a5fb8 | ||
|
|
78afa29ade | ||
|
|
73bb05e530 | ||
|
|
8cc23aca8d | ||
|
|
f96c6e4bd7 | ||
|
|
3afb4e017c | ||
|
|
54ee12308d | ||
|
|
fd09f13c9b | ||
|
|
86dd8e2dfa | ||
|
|
1b70ca2098 | ||
|
|
e8d1c69ea8 | ||
|
|
1883da463f | ||
|
|
e9879a3e4b | ||
|
|
dec05988f4 | ||
|
|
4087062798 | ||
|
|
31135321c0 | ||
|
|
226cbda7a6 | ||
|
|
66ef1a067d | ||
|
|
8a7efcdcd2 | ||
|
|
adb8fb59bd | ||
|
|
0ca9e8ee82 | ||
|
|
e7647ba183 | ||
|
|
be6599807d | ||
|
|
a8ca0329b4 | ||
|
|
6d9a88f415 | ||
|
|
0018d4b705 | ||
|
|
72e8b2882f | ||
|
|
89539ca15e | ||
|
|
175d052a28 | ||
|
|
d1a93a5135 | ||
|
|
f96485f950 | ||
|
|
79dfb2d2f3 | ||
|
|
de7ff0f944 | ||
|
|
80c77ef3a8 | ||
|
|
cad9580796 | ||
|
|
253789353f | ||
|
|
73262be2c2 | ||
|
|
0ad4c3ca93 | ||
|
|
b26e3a9629 | ||
|
|
c55f6d82d8 | ||
|
|
4b90c02420 | ||
|
|
d4fb1c1f8c | ||
|
|
445fe158cc | ||
|
|
a696f06a23 | ||
|
|
c019f13e8c | ||
|
|
b4f00f3b40 | ||
|
|
f60d8066f8 | ||
|
|
b8d5aa586e | ||
|
|
eeff20f1bc | ||
|
|
9035ffff55 | ||
|
|
ca522f06d3 | ||
|
|
7f534652a6 | ||
|
|
b93564894c | ||
|
|
54b8a62920 | ||
|
|
bcfba96d29 | ||
|
|
8e21530550 | ||
|
|
a4f59bc04e | ||
|
|
a378a719e9 | ||
|
|
441ee0d978 | ||
|
|
8d7a59161a | ||
|
|
d175a99811 | ||
|
|
724b29d6d4 | ||
|
|
336908eba0 | ||
|
|
0f5d929c09 | ||
|
|
c4b0170a0a | ||
|
|
936860edd5 | ||
|
|
1cadc9221a | ||
|
|
4890eebd3a | ||
|
|
3a65942b97 | ||
|
|
e06c558a86 | ||
|
|
0a0a408bf8 | ||
|
|
c9702b56e2 | ||
|
|
279eb23b38 | ||
|
|
8eb650ce03 | ||
|
|
7f9ac88c31 | ||
|
|
424a00cf29 | ||
|
|
3c078b4dab | ||
|
|
8cc49ffa80 | ||
|
|
58a09f6495 | ||
|
|
c2885f77c9 | ||
|
|
5d5a3138bc | ||
|
|
09f9d0729c | ||
|
|
3d989b6736 | ||
|
|
daa00e6539 | ||
|
|
382dbb500c | ||
|
|
92d6fd641f | ||
|
|
f219e7f0dd | ||
|
|
8a9e1824c3 | ||
|
|
b139d97f3d | ||
|
|
d29efb7f81 | ||
|
|
53cedc6e5d | ||
|
|
4f4aabef7a | ||
|
|
a888e4b960 | ||
|
|
15c31ad1ba | ||
|
|
196be5291d | ||
|
|
fe9f94555b | ||
|
|
47e0a61dd8 | ||
|
|
5ba324ca9a | ||
|
|
0721b34847 | ||
|
|
dc257f1f86 | ||
|
|
dfe111b95a | ||
|
|
a76ae8cd35 | ||
|
|
866e20b4be | ||
|
|
d25645ba67 | ||
|
|
ad1efa67bc | ||
|
|
cbb14f5ca2 | ||
|
|
a8cd101ff5 | ||
|
|
009e0790fe | ||
|
|
d31ebb71db | ||
|
|
2125a0be82 | ||
|
|
6dc01945af | ||
|
|
28b9df24a6 | ||
|
|
94b4ceb8ce | ||
|
|
e3eaf909a5 | ||
|
|
33580f66df | ||
|
|
139316b975 | ||
|
|
8fe8cd46b9 | ||
|
|
e3118359ad | ||
|
|
681de1b048 | ||
|
|
4880096f3d | ||
|
|
9c038a2402 | ||
|
|
c4d9dc91a6 | ||
|
|
16428baea2 | ||
|
|
4cd3119125 | ||
|
|
191b1aa719 | ||
|
|
035679057e | ||
|
|
fb4ec66b37 | ||
|
|
89f565906b | ||
|
|
6a5f732bba | ||
|
|
fba1772000 | ||
|
|
e62986b97d | ||
|
|
2e38bafdb1 | ||
|
|
f3e49b0696 | ||
|
|
70aad83b07 | ||
|
|
10c862f0bb | ||
|
|
d993c92cea | ||
|
|
546e4e431d | ||
|
|
4a7e98e398 | ||
|
|
ab4558ae32 | ||
|
|
978f73756b | ||
|
|
5086873f78 | ||
|
|
b2217474c1 | ||
|
|
9342d59a7c | ||
|
|
ad827eee90 | ||
|
|
a8034364ff | ||
|
|
c2c5111d75 | ||
|
|
4b3bd9c3cc | ||
|
|
476f545a67 | ||
|
|
16a1edb422 | ||
|
|
474445fb7d | ||
|
|
5db31517cb | ||
|
|
740e7fbf1a | ||
|
|
be5789b483 | ||
|
|
1c415b0666 | ||
|
|
8dd7f81175 | ||
|
|
87019a1a70 | ||
|
|
10c52bd6a6 | ||
|
|
c23c667c2d | ||
|
|
ec4275ca13 | ||
|
|
143bde007a | ||
|
|
a6ede12cd7 | ||
|
|
7a89a08534 | ||
|
|
5ad203ad99 | ||
|
|
82dcdc6314 | ||
|
|
371e38198f | ||
|
|
472a95e433 | ||
|
|
b84226244d | ||
|
|
e4290393af | ||
|
|
cab00a1450 | ||
|
|
ce50b38a75 | ||
|
|
e8d59c4326 | ||
|
|
b9d64784bb | ||
|
|
ad3eac2e38 | ||
|
|
e11c8a07ea | ||
|
|
a04cb08715 | ||
|
|
b9fc5474c5 | ||
|
|
709670be8e | ||
|
|
2afd3a85a9 | ||
|
|
92a0a4cf6c | ||
|
|
32c6f4cfe8 | ||
|
|
dbf19a5734 | ||
|
|
f7a9b56e93 | ||
|
|
53c73c0631 | ||
|
|
6c866ea909 | ||
|
|
8fcd39f621 | ||
|
|
ef352a69b4 | ||
|
|
99ef165884 | ||
|
|
77627c0d2d | ||
|
|
c91f0c575c | ||
|
|
1a5c0ab1ae | ||
|
|
11634740d3 | ||
|
|
640ac43059 | ||
|
|
6f231d5860 | ||
|
|
acb8b7771e | ||
|
|
301706b7d6 | ||
|
|
17cf6ffbd4 | ||
|
|
e803d3cc7a | ||
|
|
e4484f0c3e | ||
|
|
dd404fb785 | ||
|
|
a15ee1871a | ||
|
|
9b8ee42f79 | ||
|
|
939ead3aee | ||
|
|
026c85508a | ||
|
|
e6998dfd4b | ||
|
|
21949e2f0c | ||
|
|
1a79093378 | ||
|
|
ffad6fe884 | ||
|
|
0ca33dc6b8 | ||
|
|
a0bf74b9df | ||
|
|
b29ab48032 | ||
|
|
42afc5603d | ||
|
|
fab11950ee | ||
|
|
365638f1d5 | ||
|
|
73df08ebbf | ||
|
|
9c9e0d92f4 | ||
|
|
66aea0c3e8 | ||
|
|
a1c2adda3d | ||
|
|
0f18d63f7f | ||
|
|
2ee7caccfe | ||
|
|
2a2fc4903d | ||
|
|
9afc2daf75 | ||
|
|
8f94d5886d | ||
|
|
6de595f036 | ||
|
|
db6c37bfbc | ||
|
|
6bfa69ceda | ||
|
|
00467b53c7 | ||
|
|
adec718503 | ||
|
|
7c8a0ae2a3 | ||
|
|
add45b564e | ||
|
|
643a47cf7d | ||
|
|
2f967149fc | ||
|
|
5c99dff36d | ||
|
|
b2839b08cd | ||
|
|
cc29f43a35 | ||
|
|
b2afe7b3bf | ||
|
|
b4ba149662 | ||
|
|
43e8ecb118 | ||
|
|
ea60a04280 | ||
|
|
3c11bc5f98 | ||
|
|
8d4211bd3a | ||
|
|
497174bbe4 | ||
|
|
1c62211d99 | ||
|
|
7e86e53593 | ||
|
|
3349b8e6c7 | ||
|
|
49160819d2 | ||
|
|
83ff00dc29 | ||
|
|
e150a3e3b2 | ||
|
|
dd6f8669a1 | ||
|
|
fcf55df874 | ||
|
|
d81a34d3dd | ||
|
|
7b93a19e9b | ||
|
|
2312f84ec9 | ||
|
|
4e4227aef8 | ||
|
|
ee5312fff9 | ||
|
|
b99262af32 | ||
|
|
3d36a6a793 | ||
|
|
db98a3842f | ||
|
|
a5e2ea2899 | ||
|
|
e7feafb2cc | ||
|
|
4609a8d2be | ||
|
|
66ab127389 | ||
|
|
cb08f35c7f | ||
|
|
c511933cfc | ||
|
|
b3bccd2e1e | ||
|
|
3c892b8591 | ||
|
|
0a38f3321e | ||
|
|
61db17412c | ||
|
|
1965a5ee50 | ||
|
|
970b82c314 | ||
|
|
84878c4c77 | ||
|
|
949821f255 | ||
|
|
2cc2fd03fa | ||
|
|
2ed46e6f7f | ||
|
|
58c56ce7ae | ||
|
|
66983c7f67 | ||
|
|
116e4c877e | ||
|
|
ffb0c22a80 | ||
|
|
721a40ba82 | ||
|
|
9031dcbb2f | ||
|
|
d0abc38afe | ||
|
|
6a891be0e4 | ||
|
|
1d359cb8aa | ||
|
|
2736b5dab3 | ||
|
|
d5b2a5af26 | ||
|
|
e0f263950e | ||
|
|
750148f7b4 | ||
|
|
6ddb8c00dc | ||
|
|
ba46f2c820 | ||
|
|
c3301a197e | ||
|
|
69adff19fe | ||
|
|
64bf1bcb9f | ||
|
|
1f99a97544 | ||
|
|
f4b6ca70a9 | ||
|
|
e5c10f29de | ||
|
|
436deddf68 | ||
|
|
ad19381217 | ||
|
|
cd4c5d976b | ||
|
|
58ccb27792 | ||
|
|
e0e1d45859 | ||
|
|
c713deb1e8 | ||
|
|
91c7458ab8 | ||
|
|
5f3fa341b2 | ||
|
|
066d129536 | ||
|
|
348dc8365b | ||
|
|
dad7aa6a20 | ||
|
|
5d4f1e3c00 | ||
|
|
2d073e78ef | ||
|
|
72d6778894 | ||
|
|
0440c59d18 | ||
|
|
8ecc4061a8 | ||
|
|
3eecd664b4 | ||
|
|
4c5a306733 | ||
|
|
79c3377cd7 | ||
|
|
32c881bde9 | ||
|
|
27d73b362a | ||
|
|
ab1670ff03 | ||
|
|
d3c76d6998 | ||
|
|
a2c897aa9f | ||
|
|
a8de615034 | ||
|
|
1a0d8a4aa9 | ||
|
|
2ff4d56d6d | ||
|
|
ca1d2a32b0 | ||
|
|
b92e6e97ea | ||
|
|
84e2c35611 | ||
|
|
0349fdfd67 | ||
|
|
11e4111f25 | ||
|
|
6cac69238c | ||
|
|
17842e06aa | ||
|
|
fe6eac6c7d | ||
|
|
ae3958c997 | ||
|
|
9c84f92f3e | ||
|
|
48224a6455 | ||
|
|
41b9add5d6 | ||
|
|
716c7ee6f4 | ||
|
|
3d89181e96 | ||
|
|
32323a0006 | ||
|
|
6493bc4c8c | ||
|
|
6d404d1cc4 | ||
|
|
edc043c924 | ||
|
|
dca50fcec3 | ||
|
|
f0e297ba77 | ||
|
|
8a8ffbebf9 | ||
|
|
f4aadcbbfc | ||
|
|
81eedd4faf | ||
|
|
74fe964f75 | ||
|
|
a138b5ec8b | ||
|
|
054daadc33 | ||
|
|
05f079fa5b | ||
|
|
0bc8251e1b | ||
|
|
8c264b9a07 | ||
|
|
accfabf569 | ||
|
|
4a7a417423 | ||
|
|
386ef9197c | ||
|
|
d4e9518ec6 | ||
|
|
70d3365414 | ||
|
|
a8cb839734 | ||
|
|
5270eab512 | ||
|
|
bf5fc2db9b | ||
|
|
c97e849610 | ||
|
|
2cdcb45d16 | ||
|
|
df8b9f69b1 | ||
|
|
b431566421 | ||
|
|
4aa217970e | ||
|
|
444fe8bf1f | ||
|
|
f063a63b69 | ||
|
|
1d6b02f304 | ||
|
|
7d38fe61d2 | ||
|
|
2b0ec2bcc6 | ||
|
|
c575d40d63 | ||
|
|
950704c7e8 | ||
|
|
7c14c2758b | ||
|
|
ac1a03bf9c | ||
|
|
232b8721fe | ||
|
|
d82ceda770 | ||
|
|
5fe84a997f | ||
|
|
15127f7b4b | ||
|
|
04cbb76776 | ||
|
|
98aba2aa12 | ||
|
|
53092cfb7c | ||
|
|
9ef7ecbdaf | ||
|
|
1cb135f7f2 | ||
|
|
08e7c07c57 | ||
|
|
01e93c108c | ||
|
|
540e6ff01b | ||
|
|
4647efd22f | ||
|
|
884f30010c | ||
|
|
da31588e0d | ||
|
|
cbd9366898 | ||
|
|
9699dbb71f | ||
|
|
065185baea | ||
|
|
6c7fe80ec5 | ||
|
|
52d8d6fdb3 | ||
|
|
6f5184f001 | ||
|
|
80fb79daac | ||
|
|
dd804b090a | ||
|
|
c7d0da2cfd | ||
|
|
2da5bcb0b8 | ||
|
|
b073d35918 | ||
|
|
16bc7f10c1 | ||
|
|
f57bcfc429 | ||
|
|
7bd0c8aa06 | ||
|
|
162e47ca15 | ||
|
|
649730244b | ||
|
|
2efd91c150 | ||
|
|
7297faf09a | ||
|
|
a7b730654c | ||
|
|
2f5dfb1dc7 | ||
|
|
541b855512 | ||
|
|
8b42990bb3 | ||
|
|
5b216ee0e6 | ||
|
|
9b8edeb609 | ||
|
|
15d9b320db | ||
|
|
d38ffea4a3 | ||
|
|
dfa1ae1c20 | ||
|
|
6ee437e9bf | ||
|
|
0e5f697b48 | ||
|
|
22927c9478 | ||
|
|
f07d8c5677 | ||
|
|
cd35430d0e | ||
|
|
6a48568911 | ||
|
|
3921895dd5 | ||
|
|
aa17b3adc2 | ||
|
|
04fbec5120 | ||
|
|
76d0d3ec19 | ||
|
|
fd99d21c8f | ||
|
|
6a071e1b4d | ||
|
|
393d61b362 | ||
|
|
3d2464c30e | ||
|
|
890448d5fa | ||
|
|
2984c0d521 | ||
|
|
fc9fd46308 | ||
|
|
542e795fe0 | ||
|
|
fc1bc78fb9 | ||
|
|
2565a4e71b | ||
|
|
23d2dc5007 | ||
|
|
1fbebb0da7 | ||
|
|
2204e9bb15 | ||
|
|
8fd31106ca | ||
|
|
34fa0f1ff8 | ||
|
|
d49060d659 | ||
|
|
764deab5c1 | ||
|
|
28e266ac11 | ||
|
|
b08ec402d2 | ||
|
|
9721c4e761 | ||
|
|
70c96eeac6 | ||
|
|
c2efc4aeb3 | ||
|
|
55640a3ff7 | ||
|
|
dc907f501c | ||
|
|
972bb2e9fb |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -6,7 +6,10 @@
|
||||
/vendor/brightray/vendor/download/
|
||||
/vendor/python_26/
|
||||
/vendor/npm/
|
||||
/vendor/.gclient
|
||||
node_modules/
|
||||
*.xcodeproj
|
||||
*.swp
|
||||
*.pyc
|
||||
debug.log
|
||||
npm-debug.log
|
||||
|
||||
5
.gitmodules
vendored
5
.gitmodules
vendored
@@ -1,6 +1,6 @@
|
||||
[submodule "vendor/brightray"]
|
||||
path = vendor/brightray
|
||||
url = https://github.com/brightray/brightray.git
|
||||
url = https://github.com/atom/brightray.git
|
||||
[submodule "vendor/node"]
|
||||
path = vendor/node
|
||||
url = https://github.com/atom/node.git
|
||||
@@ -13,3 +13,6 @@
|
||||
[submodule "vendor/native_mate"]
|
||||
path = vendor/native_mate
|
||||
url = https://github.com/zcbenz/native-mate.git
|
||||
[submodule "vendor/crashpad"]
|
||||
path = vendor/crashpad
|
||||
url = https://github.com/atom/crashpad.git
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
language: objective-c
|
||||
language: cpp
|
||||
compiler: clang
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
notifications:
|
||||
email:
|
||||
@@ -6,3 +10,6 @@ notifications:
|
||||
on_failure: change
|
||||
|
||||
script: './script/cibuild'
|
||||
|
||||
git:
|
||||
depth: 10
|
||||
|
||||
71
CONTRIBUTING.md
Normal file
71
CONTRIBUTING.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Contributing to Electron
|
||||
|
||||
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
|
||||
|
||||
The following is a set of guidelines for contributing to Electron.
|
||||
These are just guidelines, not rules, use your best judgment and feel free to
|
||||
propose changes to this document in a pull request.
|
||||
|
||||
## Submitting Issues
|
||||
|
||||
* You can create an issue [here](https://github.com/atom/electron/issues/new),
|
||||
but before doing that please read the notes below and include as many details as
|
||||
possible with your report. If you can, please include:
|
||||
* The version of Electron you are using
|
||||
* The operating system you are using
|
||||
* If applicable, what you were doing when the issue arose and what you
|
||||
expected to happen
|
||||
* Other things that will help resolve your issue:
|
||||
* Screenshots and animated GIFs
|
||||
* Error output that appears in your terminal, dev tools or as an alert
|
||||
* Perform a [cursory search](https://github.com/atom/electron/issues?utf8=✓&q=is%3Aissue+)
|
||||
to see if a similar issue has already been submitted
|
||||
|
||||
## Submitting Pull Requests
|
||||
|
||||
* Include screenshots and animated GIFs in your pull request whenever possible.
|
||||
* Follow the CoffeeScript, JavaScript, C++ and Python [coding style defined in docs](/docs/development/coding-style.md).
|
||||
* Write documentation in [Markdown](https://daringfireball.net/projects/markdown).
|
||||
* Use short, present tense commit messages. See [Commit Message Styleguide](#git-commit-messages-styleguide).
|
||||
|
||||
## Styleguides
|
||||
|
||||
### General Code
|
||||
|
||||
* End files with a newline.
|
||||
* Place requires in the following order:
|
||||
* Built in Node Modules (such as `path`)
|
||||
* Built in Electron Modules (such as `ipc`, `app`)
|
||||
* Local Modules (using relative paths)
|
||||
* Place class properties in the following order:
|
||||
* Class methods and properties (methods starting with a `@`)
|
||||
* Instance methods and properties
|
||||
* Avoid platform-dependent code:
|
||||
* Use `path.join()` to concatenate filenames.
|
||||
* Use `os.tmpdir()` rather than `/tmp` when you need to reference the
|
||||
temporary directory.
|
||||
* Using a plain `return` when returning explicitly at the end of a function.
|
||||
* Not `return null`, `return undefined`, `null`, or `undefined`
|
||||
|
||||
### Git Commit Messages
|
||||
|
||||
* Use the present tense ("Add feature" not "Added feature")
|
||||
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
|
||||
* Limit the first line to 72 characters or less
|
||||
* Reference issues and pull requests liberally
|
||||
* Consider starting the commit message with an applicable emoji:
|
||||
* :art: `:art:` when improving the format/structure of the code
|
||||
* :racehorse: `:racehorse:` when improving performance
|
||||
* :non-potable_water: `:non-potable_water:` when plugging memory leaks
|
||||
* :memo: `:memo:` when writing docs
|
||||
* :penguin: `:penguin:` when fixing something on Linux
|
||||
* :apple: `:apple:` when fixing something on Mac OS
|
||||
* :checkered_flag: `:checkered_flag:` when fixing something on Windows
|
||||
* :bug: `:bug:` when fixing a bug
|
||||
* :fire: `:fire:` when removing code or files
|
||||
* :green_heart: `:green_heart:` when fixing the CI build
|
||||
* :white_check_mark: `:white_check_mark:` when adding tests
|
||||
* :lock: `:lock:` when dealing with security
|
||||
* :arrow_up: `:arrow_up:` when upgrading dependencies
|
||||
* :arrow_down: `:arrow_down:` when downgrading dependencies
|
||||
* :shirt: `:shirt:` when removing linter warnings
|
||||
41
README.md
41
README.md
@@ -1,22 +1,47 @@
|
||||
# Atom Shell [](https://travis-ci.org/atom/atom-shell)
|
||||
[](http://electron.atom.io/)
|
||||
|
||||
The Atom Shell framework lets you write cross-platform desktop applications
|
||||
using JavaScript, HTML and CSS. It is based on [node.js](http://nodejs.org) and
|
||||
[](https://travis-ci.org/atom/electron)
|
||||
[](https://david-dm.org/atom/electron#info=devDependencies)
|
||||
|
||||
: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
|
||||
[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.
|
||||
|
||||
## Downloads
|
||||
|
||||
Prebuilt binaries of atom-shell for Linux, Windows and Mac can be found on the
|
||||
[releases](https://github.com/atom/atom-shell/releases) page.
|
||||
Prebuilt binaries and debug symbols of Electron for Linux, Windows and Mac 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
|
||||
binaries:
|
||||
|
||||
```sh
|
||||
# Install the `electron` command globally in your $PATH
|
||||
npm install electron-prebuilt -g
|
||||
|
||||
# Install as a development dependency
|
||||
npm install electron-prebuilt --save-dev
|
||||
```
|
||||
|
||||
### Mirrors
|
||||
|
||||
- [China](https://npm.taobao.org/mirrors/electron)
|
||||
|
||||
## Documentation
|
||||
|
||||
Guides and the API reference are located in the
|
||||
[docs](https://github.com/atom/atom-shell/tree/master/docs) directory. It also
|
||||
contains documents describing how to build and contribute to atom-shell.
|
||||
[docs](https://github.com/atom/electron/tree/master/docs) directory. It also
|
||||
contains documents describing how to build and contribute to Electron.
|
||||
|
||||
## Community
|
||||
|
||||
There is an [`atom-shell` category on the Atom forums](http://discuss.atom.io/category/atom-shell)
|
||||
There is an [`electron` category on the Atom forums](http://discuss.atom.io/category/electron)
|
||||
as well as an `#atom-shell` channel on Freenode.
|
||||
|
||||
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron) for a community maintained list of useful example apps, tools and resources.
|
||||
|
||||
645
atom.gyp
645
atom.gyp
@@ -1,259 +1,32 @@
|
||||
{
|
||||
'variables': {
|
||||
'includes': [
|
||||
'vendor/native_mate/native_mate_files.gypi',
|
||||
],
|
||||
'project_name': 'atom',
|
||||
'product_name': 'Atom',
|
||||
'framework_name': 'Atom Framework',
|
||||
'app_sources': [
|
||||
'atom/app/atom_main.cc',
|
||||
'atom/app/atom_main.h',
|
||||
],
|
||||
'bundle_sources': [
|
||||
'atom/browser/resources/mac/atom.icns',
|
||||
],
|
||||
'coffee_sources': [
|
||||
'atom/browser/api/lib/app.coffee',
|
||||
'atom/browser/api/lib/atom-delegate.coffee',
|
||||
'atom/browser/api/lib/auto-updater.coffee',
|
||||
'atom/browser/api/lib/browser-window.coffee',
|
||||
'atom/browser/api/lib/dialog.coffee',
|
||||
'atom/browser/api/lib/ipc.coffee',
|
||||
'atom/browser/api/lib/menu.coffee',
|
||||
'atom/browser/api/lib/menu-item.coffee',
|
||||
'atom/browser/api/lib/power-monitor.coffee',
|
||||
'atom/browser/api/lib/protocol.coffee',
|
||||
'atom/browser/api/lib/web-contents.coffee',
|
||||
'atom/browser/lib/init.coffee',
|
||||
'atom/browser/lib/objects-registry.coffee',
|
||||
'atom/browser/lib/rpc-server.coffee',
|
||||
'atom/common/api/lib/callbacks-registry.coffee',
|
||||
'atom/common/api/lib/clipboard.coffee',
|
||||
'atom/common/api/lib/crash-reporter.coffee',
|
||||
'atom/common/api/lib/id-weak-map.coffee',
|
||||
'atom/common/api/lib/screen.coffee',
|
||||
'atom/common/api/lib/shell.coffee',
|
||||
'atom/common/lib/init.coffee',
|
||||
'atom/renderer/lib/init.coffee',
|
||||
'atom/renderer/lib/inspector.coffee',
|
||||
'atom/renderer/lib/override.coffee',
|
||||
'atom/renderer/api/lib/ipc.coffee',
|
||||
'atom/renderer/api/lib/remote.coffee',
|
||||
],
|
||||
'lib_sources': [
|
||||
'atom/app/atom_main_delegate.cc',
|
||||
'atom/app/atom_main_delegate.h',
|
||||
'atom/app/atom_main_delegate_mac.mm',
|
||||
'atom/browser/api/atom_api_app.cc',
|
||||
'atom/browser/api/atom_api_app.h',
|
||||
'atom/browser/api/atom_api_auto_updater.cc',
|
||||
'atom/browser/api/atom_api_auto_updater.h',
|
||||
'atom/browser/api/atom_api_dialog.cc',
|
||||
'atom/browser/api/atom_api_menu.cc',
|
||||
'atom/browser/api/atom_api_menu.h',
|
||||
'atom/browser/api/atom_api_menu_gtk.cc',
|
||||
'atom/browser/api/atom_api_menu_gtk.h',
|
||||
'atom/browser/api/atom_api_menu_mac.h',
|
||||
'atom/browser/api/atom_api_menu_mac.mm',
|
||||
'atom/browser/api/atom_api_menu_win.cc',
|
||||
'atom/browser/api/atom_api_menu_win.h',
|
||||
'atom/browser/api/atom_api_power_monitor.cc',
|
||||
'atom/browser/api/atom_api_power_monitor.h',
|
||||
'atom/browser/api/atom_api_protocol.cc',
|
||||
'atom/browser/api/atom_api_protocol.h',
|
||||
'atom/browser/api/atom_api_web_contents.cc',
|
||||
'atom/browser/api/atom_api_web_contents.h',
|
||||
'atom/browser/api/atom_api_window.cc',
|
||||
'atom/browser/api/atom_api_window.h',
|
||||
'atom/browser/api/event.cc',
|
||||
'atom/browser/api/event.h',
|
||||
'atom/browser/api/event_emitter.cc',
|
||||
'atom/browser/api/event_emitter.h',
|
||||
'atom/browser/auto_updater.cc',
|
||||
'atom/browser/auto_updater.h',
|
||||
'atom/browser/auto_updater_delegate.h',
|
||||
'atom/browser/auto_updater_linux.cc',
|
||||
'atom/browser/auto_updater_mac.mm',
|
||||
'atom/browser/auto_updater_win.cc',
|
||||
'atom/browser/atom_browser_client.cc',
|
||||
'atom/browser/atom_browser_client.h',
|
||||
'atom/browser/atom_browser_context.cc',
|
||||
'atom/browser/atom_browser_context.h',
|
||||
'atom/browser/atom_browser_main_parts.cc',
|
||||
'atom/browser/atom_browser_main_parts.h',
|
||||
'atom/browser/atom_browser_main_parts_mac.mm',
|
||||
'atom/browser/atom_javascript_dialog_manager.cc',
|
||||
'atom/browser/atom_javascript_dialog_manager.h',
|
||||
'atom/browser/browser.cc',
|
||||
'atom/browser/browser.h',
|
||||
'atom/browser/browser_linux.cc',
|
||||
'atom/browser/browser_mac.mm',
|
||||
'atom/browser/browser_win.cc',
|
||||
'atom/browser/browser_observer.h',
|
||||
'atom/browser/devtools_delegate.cc',
|
||||
'atom/browser/devtools_delegate.h',
|
||||
'atom/browser/mac/atom_application.h',
|
||||
'atom/browser/mac/atom_application.mm',
|
||||
'atom/browser/mac/atom_application_delegate.h',
|
||||
'atom/browser/mac/atom_application_delegate.mm',
|
||||
'atom/browser/native_window.cc',
|
||||
'atom/browser/native_window.h',
|
||||
'atom/browser/native_window_gtk.cc',
|
||||
'atom/browser/native_window_gtk.h',
|
||||
'atom/browser/native_window_mac.h',
|
||||
'atom/browser/native_window_mac.mm',
|
||||
'atom/browser/native_window_win.cc',
|
||||
'atom/browser/native_window_win.h',
|
||||
'atom/browser/native_window_observer.h',
|
||||
'atom/browser/net/adapter_request_job.cc',
|
||||
'atom/browser/net/adapter_request_job.h',
|
||||
'atom/browser/net/atom_url_request_context_getter.cc',
|
||||
'atom/browser/net/atom_url_request_context_getter.h',
|
||||
'atom/browser/net/atom_url_request_job_factory.cc',
|
||||
'atom/browser/net/atom_url_request_job_factory.h',
|
||||
'atom/browser/net/url_request_string_job.cc',
|
||||
'atom/browser/net/url_request_string_job.h',
|
||||
'atom/browser/ui/accelerator_util.cc',
|
||||
'atom/browser/ui/accelerator_util.h',
|
||||
'atom/browser/ui/accelerator_util_gtk.cc',
|
||||
'atom/browser/ui/accelerator_util_mac.mm',
|
||||
'atom/browser/ui/accelerator_util_win.cc',
|
||||
'atom/browser/ui/cocoa/atom_menu_controller.h',
|
||||
'atom/browser/ui/cocoa/atom_menu_controller.mm',
|
||||
'atom/browser/ui/cocoa/event_processing_window.h',
|
||||
'atom/browser/ui/cocoa/event_processing_window.mm',
|
||||
'atom/browser/ui/file_dialog.h',
|
||||
'atom/browser/ui/file_dialog_gtk.cc',
|
||||
'atom/browser/ui/file_dialog_mac.mm',
|
||||
'atom/browser/ui/file_dialog_win.cc',
|
||||
'atom/browser/ui/message_box.h',
|
||||
'atom/browser/ui/message_box_gtk.cc',
|
||||
'atom/browser/ui/message_box_mac.mm',
|
||||
'atom/browser/ui/message_box_win.cc',
|
||||
'atom/browser/ui/win/menu_2.cc',
|
||||
'atom/browser/ui/win/menu_2.h',
|
||||
'atom/browser/ui/win/native_menu_win.cc',
|
||||
'atom/browser/ui/win/native_menu_win.h',
|
||||
'atom/browser/window_list.cc',
|
||||
'atom/browser/window_list.h',
|
||||
'atom/browser/window_list_observer.h',
|
||||
'atom/common/api/api_messages.cc',
|
||||
'atom/common/api/api_messages.h',
|
||||
'atom/common/api/atom_api_clipboard.cc',
|
||||
'atom/common/api/atom_api_crash_reporter.cc',
|
||||
'atom/common/api/atom_api_id_weak_map.cc',
|
||||
'atom/common/api/atom_api_id_weak_map.h',
|
||||
'atom/common/api/atom_api_screen.cc',
|
||||
'atom/common/api/atom_api_screen.h',
|
||||
'atom/common/api/atom_api_shell.cc',
|
||||
'atom/common/api/atom_api_v8_util.cc',
|
||||
'atom/common/api/atom_bindings.cc',
|
||||
'atom/common/api/atom_bindings.h',
|
||||
'atom/common/api/atom_extensions.cc',
|
||||
'atom/common/api/atom_extensions.h',
|
||||
'atom/common/api/object_life_monitor.cc',
|
||||
'atom/common/api/object_life_monitor.h',
|
||||
'atom/common/browser_v8_locker.cc',
|
||||
'atom/common/browser_v8_locker.h',
|
||||
'atom/common/crash_reporter/crash_reporter.cc',
|
||||
'atom/common/crash_reporter/crash_reporter.h',
|
||||
'atom/common/crash_reporter/crash_reporter_linux.cc',
|
||||
'atom/common/crash_reporter/crash_reporter_linux.h',
|
||||
'atom/common/crash_reporter/crash_reporter_mac.h',
|
||||
'atom/common/crash_reporter/crash_reporter_mac.mm',
|
||||
'atom/common/crash_reporter/crash_reporter_win.cc',
|
||||
'atom/common/crash_reporter/crash_reporter_win.h',
|
||||
'atom/common/crash_reporter/linux/crash_dump_handler.cc',
|
||||
'atom/common/crash_reporter/linux/crash_dump_handler.h',
|
||||
'atom/common/crash_reporter/win/crash_service.cc',
|
||||
'atom/common/crash_reporter/win/crash_service.h',
|
||||
'atom/common/crash_reporter/win/crash_service_main.cc',
|
||||
'atom/common/crash_reporter/win/crash_service_main.h',
|
||||
'atom/common/draggable_region.cc',
|
||||
'atom/common/draggable_region.h',
|
||||
'atom/common/linux/application_info.cc',
|
||||
'atom/common/native_mate_converters/file_path_converter.h',
|
||||
'atom/common/native_mate_converters/function_converter.h',
|
||||
'atom/common/native_mate_converters/gurl_converter.h',
|
||||
'atom/common/native_mate_converters/string16_converter.h',
|
||||
'atom/common/native_mate_converters/v8_value_converter.cc',
|
||||
'atom/common/native_mate_converters/v8_value_converter.h',
|
||||
'atom/common/native_mate_converters/value_converter.cc',
|
||||
'atom/common/native_mate_converters/value_converter.h',
|
||||
'atom/common/node_bindings.cc',
|
||||
'atom/common/node_bindings.h',
|
||||
'atom/common/node_bindings_linux.cc',
|
||||
'atom/common/node_bindings_linux.h',
|
||||
'atom/common/node_bindings_mac.cc',
|
||||
'atom/common/node_bindings_mac.h',
|
||||
'atom/common/node_bindings_win.cc',
|
||||
'atom/common/node_bindings_win.h',
|
||||
'atom/common/node_includes.h',
|
||||
'atom/common/options_switches.cc',
|
||||
'atom/common/options_switches.h',
|
||||
'atom/common/platform_util.h',
|
||||
'atom/common/platform_util_linux.cc',
|
||||
'atom/common/platform_util_mac.mm',
|
||||
'atom/common/platform_util_win.cc',
|
||||
'atom/renderer/api/atom_api_renderer_ipc.cc',
|
||||
'atom/renderer/api/atom_renderer_bindings.cc',
|
||||
'atom/renderer/api/atom_renderer_bindings.h',
|
||||
'atom/renderer/atom_render_view_observer.cc',
|
||||
'atom/renderer/atom_render_view_observer.h',
|
||||
'atom/renderer/atom_renderer_client.cc',
|
||||
'atom/renderer/atom_renderer_client.h',
|
||||
'chrome/browser/ui/gtk/event_utils.cc',
|
||||
'chrome/browser/ui/gtk/event_utils.h',
|
||||
'chrome/browser/ui/gtk/gtk_custom_menu.cc',
|
||||
'chrome/browser/ui/gtk/gtk_custom_menu.h',
|
||||
'chrome/browser/ui/gtk/gtk_custom_menu_item.cc',
|
||||
'chrome/browser/ui/gtk/gtk_custom_menu_item.h',
|
||||
'chrome/browser/ui/gtk/gtk_util.cc',
|
||||
'chrome/browser/ui/gtk/gtk_util.h',
|
||||
'chrome/browser/ui/gtk/gtk_window_util.cc',
|
||||
'chrome/browser/ui/gtk/gtk_window_util.h',
|
||||
'chrome/browser/ui/gtk/menu_gtk.cc',
|
||||
'chrome/browser/ui/gtk/menu_gtk.h',
|
||||
'<@(native_mate_files)',
|
||||
],
|
||||
'framework_sources': [
|
||||
'atom/app/atom_library_main.cc',
|
||||
'atom/app/atom_library_main.h',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="win"', {
|
||||
'app_sources': [
|
||||
'atom/browser/resources/win/resource.h',
|
||||
'atom/browser/resources/win/atom.ico',
|
||||
'atom/browser/resources/win/atom.rc',
|
||||
'<(libchromiumcontent_src_dir)/content/app/startup_helper_win.cc',
|
||||
],
|
||||
}], # OS=="win"
|
||||
],
|
||||
'atom_source_root': '<!(python tools/atom_source_root.py)',
|
||||
'project_name%': 'electron',
|
||||
'product_name%': 'Electron',
|
||||
'company_name%': 'GitHub, Inc',
|
||||
'company_abbr%': 'github',
|
||||
'version%': '0.28.1',
|
||||
|
||||
'atom_source_root': '<!(["python", "tools/atom_source_root.py"])',
|
||||
},
|
||||
'includes': [
|
||||
'filenames.gypi',
|
||||
'vendor/native_mate/native_mate_files.gypi',
|
||||
],
|
||||
'target_defaults': {
|
||||
'defines': [
|
||||
'ATOM_PRODUCT_NAME="<(product_name)"',
|
||||
'ATOM_PROJECT_NAME="<(project_name)"',
|
||||
],
|
||||
'mac_framework_dirs': [
|
||||
'<(atom_source_root)/external_binaries',
|
||||
],
|
||||
'includes': [
|
||||
# Rules for excluding e.g. foo_win.cc from the build on non-Windows.
|
||||
'filename_rules.gypi',
|
||||
],
|
||||
'configurations': {
|
||||
'Debug': {
|
||||
'defines': [ 'DEBUG' ],
|
||||
'cflags': [ '-g', '-O0' ],
|
||||
},
|
||||
},
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': '<(project_name)',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'generated_sources',
|
||||
'compile_coffee',
|
||||
'<(project_name)_lib',
|
||||
],
|
||||
'sources': [
|
||||
@@ -272,8 +45,10 @@
|
||||
'dependencies': [
|
||||
'<(project_name)_framework',
|
||||
'<(project_name)_helper',
|
||||
'vendor/breakpad/breakpad.gyp:dump_syms',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'ATOM_BUNDLE_ID': 'com.<(company_abbr).<(project_name)',
|
||||
'INFOPLIST_FILE': 'atom/browser/resources/mac/Info.plist',
|
||||
'LD_RUNPATH_SEARCH_PATHS': [
|
||||
'@executable_path/../Frameworks',
|
||||
@@ -287,7 +62,7 @@
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Frameworks',
|
||||
'files': [
|
||||
'<(PRODUCT_DIR)/<(product_name) Helper.app',
|
||||
'<(PRODUCT_DIR)/<(framework_name).framework',
|
||||
'<(PRODUCT_DIR)/<(product_name) Framework.framework',
|
||||
'external_binaries/Squirrel.framework',
|
||||
'external_binaries/ReactiveCocoa.framework',
|
||||
'external_binaries/Mantle.framework',
|
||||
@@ -317,21 +92,62 @@
|
||||
'<(product_name)',
|
||||
],
|
||||
},
|
||||
# The application doesn't have real localizations, it just has
|
||||
# empty .lproj directories, which is enough to convince Cocoa
|
||||
# atom-shell supports those languages.
|
||||
{
|
||||
'postbuild_name': 'Make Empty Localizations',
|
||||
'variables': {
|
||||
'apply_locales_cmd': ['python', 'tools/mac/apply_locales.py'],
|
||||
'locale_dirs': [
|
||||
'>!@(<(apply_locales_cmd) -d ZZLOCALE.lproj <(locales))',
|
||||
],
|
||||
},
|
||||
'action': [
|
||||
'tools/mac/make_locale_dirs.sh',
|
||||
'<@(locale_dirs)',
|
||||
],
|
||||
},
|
||||
]
|
||||
}], # OS=="mac"
|
||||
}, { # OS=="mac"
|
||||
'dependencies': [
|
||||
'make_locale_paks',
|
||||
],
|
||||
}], # OS!="mac"
|
||||
['OS=="win"', {
|
||||
'copies': [
|
||||
{
|
||||
'variables': {
|
||||
'conditions': [
|
||||
['libchromiumcontent_component', {
|
||||
'copied_libraries': [
|
||||
'<@(libchromiumcontent_shared_libraries)',
|
||||
'<@(libchromiumcontent_shared_v8_libraries)',
|
||||
],
|
||||
}, {
|
||||
'copied_libraries': [
|
||||
'<(libchromiumcontent_dir)/pdf.dll',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
'destination': '<(PRODUCT_DIR)',
|
||||
'files': [
|
||||
'<(libchromiumcontent_library_dir)/chromiumcontent.dll',
|
||||
'<(libchromiumcontent_library_dir)/ffmpegsumo.dll',
|
||||
'<(libchromiumcontent_library_dir)/icudt.dll',
|
||||
'<(libchromiumcontent_library_dir)/libEGL.dll',
|
||||
'<(libchromiumcontent_library_dir)/libGLESv2.dll',
|
||||
'<(libchromiumcontent_resources_dir)/content_shell.pak',
|
||||
'external_binaries/d3dcompiler_43.dll',
|
||||
'<@(copied_libraries)',
|
||||
'<(libchromiumcontent_dir)/ffmpegsumo.dll',
|
||||
'<(libchromiumcontent_dir)/libEGL.dll',
|
||||
'<(libchromiumcontent_dir)/libGLESv2.dll',
|
||||
'<(libchromiumcontent_dir)/icudtl.dat',
|
||||
'<(libchromiumcontent_dir)/content_resources_200_percent.pak',
|
||||
'<(libchromiumcontent_dir)/content_shell.pak',
|
||||
'<(libchromiumcontent_dir)/ui_resources_200_percent.pak',
|
||||
'<(libchromiumcontent_dir)/natives_blob.bin',
|
||||
'<(libchromiumcontent_dir)/snapshot_blob.bin',
|
||||
'external_binaries/d3dcompiler_47.dll',
|
||||
'external_binaries/xinput1_3.dll',
|
||||
'external_binaries/msvcp120.dll',
|
||||
'external_binaries/msvcr120.dll',
|
||||
'external_binaries/vccorlib120.dll',
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -345,11 +161,29 @@
|
||||
['OS=="linux"', {
|
||||
'copies': [
|
||||
{
|
||||
'variables': {
|
||||
'conditions': [
|
||||
['libchromiumcontent_component', {
|
||||
'copied_libraries': [
|
||||
'<(PRODUCT_DIR)/lib/libnode.so',
|
||||
'<@(libchromiumcontent_shared_libraries)',
|
||||
'<@(libchromiumcontent_shared_v8_libraries)',
|
||||
],
|
||||
}, {
|
||||
'copied_libraries': [
|
||||
'<(PRODUCT_DIR)/lib/libnode.so',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
'destination': '<(PRODUCT_DIR)',
|
||||
'files': [
|
||||
'<(libchromiumcontent_library_dir)/libchromiumcontent.so',
|
||||
'<(libchromiumcontent_library_dir)/libffmpegsumo.so',
|
||||
'<(libchromiumcontent_resources_dir)/content_shell.pak',
|
||||
'<@(copied_libraries)',
|
||||
'<(libchromiumcontent_dir)/libffmpegsumo.so',
|
||||
'<(libchromiumcontent_dir)/icudtl.dat',
|
||||
'<(libchromiumcontent_dir)/content_shell.pak',
|
||||
'<(libchromiumcontent_dir)/natives_blob.bin',
|
||||
'<(libchromiumcontent_dir)/snapshot_blob.bin',
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -366,24 +200,41 @@
|
||||
'target_name': '<(project_name)_lib',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'atom_coffee2c',
|
||||
'vendor/brightray/brightray.gyp:brightray',
|
||||
'vendor/node/node.gyp:node_lib',
|
||||
'vendor/node/node.gyp:node',
|
||||
],
|
||||
'defines': [
|
||||
# This is defined in skia/skia_common.gypi.
|
||||
'SK_SUPPORT_LEGACY_GETTOPDEVICE',
|
||||
# Disable warnings for g_settings_list_schemas.
|
||||
'GLIB_DISABLE_DEPRECATION_WARNINGS',
|
||||
# Defined in Chromium but not exposed in its gyp file.
|
||||
'V8_USE_EXTERNAL_STARTUP_DATA',
|
||||
'ENABLE_PLUGINS',
|
||||
# Needed by Node.
|
||||
'NODE_WANT_INTERNALS=1',
|
||||
],
|
||||
'sources': [
|
||||
'<@(lib_sources)',
|
||||
],
|
||||
'include_dirs': [
|
||||
'.',
|
||||
'chromium_src',
|
||||
'vendor/brightray',
|
||||
'vendor/native_mate',
|
||||
# Include atom_natives.h.
|
||||
'<(SHARED_INTERMEDIATE_DIR)',
|
||||
# Include directories for uv and node.
|
||||
'vendor/node/src',
|
||||
'vendor/node/deps/http_parser',
|
||||
'vendor/node/deps/uv/include',
|
||||
# The `node.h` is using `#include"v8.h"`.
|
||||
'vendor/brightray/vendor/download/libchromiumcontent/src/v8/include',
|
||||
'<(libchromiumcontent_src_dir)/v8/include',
|
||||
# The `node.h` is using `#include"ares.h"`.
|
||||
'vendor/node/deps/cares/include',
|
||||
# The `third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h` is using `platform/PlatformExport.h`.
|
||||
'<(libchromiumcontent_src_dir)/third_party/WebKit/Source',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
@@ -394,24 +245,39 @@
|
||||
'vendor/brightray/brightray.gyp:brightray',
|
||||
],
|
||||
'conditions': [
|
||||
['libchromiumcontent_component', {
|
||||
'link_settings': {
|
||||
'libraries': [ '<@(libchromiumcontent_v8_libraries)' ],
|
||||
},
|
||||
}],
|
||||
['OS=="win"', {
|
||||
'sources': [
|
||||
'<@(lib_sources_win)',
|
||||
],
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'-limm32.lib',
|
||||
'-loleacc.lib',
|
||||
'-lComdlg32.lib',
|
||||
'-lWininet.lib',
|
||||
'<(atom_source_root)/<(libchromiumcontent_library_dir)/chromiumviews.lib',
|
||||
],
|
||||
},
|
||||
'dependencies': [
|
||||
# Node is built as static_library on Windows, so we also need to
|
||||
# include its dependencies here.
|
||||
'vendor/node/deps/cares/cares.gyp:cares',
|
||||
'vendor/node/deps/http_parser/http_parser.gyp:http_parser',
|
||||
'vendor/node/deps/uv/uv.gyp:libuv',
|
||||
'vendor/node/deps/zlib/zlib.gyp:zlib',
|
||||
# Build with breakpad support.
|
||||
'vendor/breakpad/breakpad.gyp:breakpad_handler',
|
||||
'vendor/breakpad/breakpad.gyp:breakpad_sender',
|
||||
],
|
||||
}], # OS=="win"
|
||||
['OS=="mac"', {
|
||||
'dependencies': [
|
||||
'vendor/breakpad/breakpad.gyp:breakpad',
|
||||
'vendor/crashpad/client/client.gyp:crashpad_client',
|
||||
'vendor/crashpad/handler/handler.gyp:crashpad_handler',
|
||||
],
|
||||
}], # OS=="mac"
|
||||
['OS=="linux"', {
|
||||
@@ -426,12 +292,13 @@
|
||||
],
|
||||
},
|
||||
# Required settings of using breakpad.
|
||||
'cflags_cc': [
|
||||
'-Wno-empty-body',
|
||||
'-Wno-reserved-user-defined-literal',
|
||||
],
|
||||
'include_dirs': [
|
||||
'vendor/breakpad/src',
|
||||
],
|
||||
'cflags': [
|
||||
'-Wno-empty-body',
|
||||
],
|
||||
'dependencies': [
|
||||
'vendor/breakpad/breakpad.gyp:breakpad_client',
|
||||
],
|
||||
@@ -439,150 +306,63 @@
|
||||
],
|
||||
}, # target <(product_name)_lib
|
||||
{
|
||||
'target_name': 'generated_sources',
|
||||
'target_name': 'compile_coffee',
|
||||
'type': 'none',
|
||||
'sources': [
|
||||
'<@(coffee_sources)',
|
||||
],
|
||||
'rules': [
|
||||
'actions': [
|
||||
{
|
||||
'rule_name': 'coffee',
|
||||
'extension': 'coffee',
|
||||
'action_name': 'compile_coffee',
|
||||
'variables': {
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
'resources_path': '<(PRODUCT_DIR)/<(product_name).app/Contents/Resources',
|
||||
},{
|
||||
'resources_path': '<(PRODUCT_DIR)/resources',
|
||||
}],
|
||||
],
|
||||
},
|
||||
'inputs': [
|
||||
'script/compile-coffee.py',
|
||||
'<@(coffee_sources)',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
'outputs': [
|
||||
'<(PRODUCT_DIR)/<(product_name).app/Contents/Resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
|
||||
],
|
||||
'action': [
|
||||
'python',
|
||||
'script/compile-coffee.py',
|
||||
'<(RULE_INPUT_PATH)',
|
||||
'<(PRODUCT_DIR)/<(product_name).app/Contents/Resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
|
||||
],
|
||||
},{ # OS=="mac"
|
||||
'outputs': [
|
||||
'<(PRODUCT_DIR)/resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
|
||||
],
|
||||
'action': [
|
||||
'python',
|
||||
'script/compile-coffee.py',
|
||||
'<(RULE_INPUT_PATH)',
|
||||
'<(PRODUCT_DIR)/resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
|
||||
],
|
||||
}], # OS=="win" or OS=="linux"
|
||||
'outputs': [
|
||||
'<(resources_path)/atom.asar',
|
||||
],
|
||||
},
|
||||
'action': [
|
||||
'python',
|
||||
'tools/coffee2asar.py',
|
||||
'<@(_outputs)',
|
||||
'<@(_inputs)',
|
||||
],
|
||||
}
|
||||
],
|
||||
}, # target generated_sources
|
||||
}, # target compile_coffee
|
||||
{
|
||||
'target_name': '<(project_name)_dump_symbols',
|
||||
'target_name': 'atom_coffee2c',
|
||||
'type': 'none',
|
||||
'dependencies': [
|
||||
'<(project_name)',
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'atom_coffee2c',
|
||||
'inputs': [
|
||||
'<@(coffee2c_sources)',
|
||||
],
|
||||
'outputs': [
|
||||
'<(SHARED_INTERMEDIATE_DIR)/atom_natives.h',
|
||||
],
|
||||
'action': [
|
||||
'python',
|
||||
'tools/coffee2c.py',
|
||||
'<@(_outputs)',
|
||||
'<@(_inputs)',
|
||||
],
|
||||
}
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
'dependencies': [
|
||||
'vendor/breakpad/breakpad.gyp:dump_syms',
|
||||
],
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'Dump Symbols',
|
||||
'inputs': [
|
||||
'<(PRODUCT_DIR)/<(product_name).app/Contents/MacOS/<(product_name)',
|
||||
],
|
||||
'outputs': [
|
||||
'<(PRODUCT_DIR)/Atom-Shell.breakpad.syms',
|
||||
],
|
||||
'action': [
|
||||
'python',
|
||||
'tools/posix/generate_breakpad_symbols.py',
|
||||
'--build-dir=<(PRODUCT_DIR)',
|
||||
'--binary=<(PRODUCT_DIR)/<(product_name).app/Contents/MacOS/<(product_name)',
|
||||
'--symbols-dir=<(PRODUCT_DIR)/Atom-Shell.breakpad.syms',
|
||||
'--libchromiumcontent-dir=<(libchromiumcontent_library_dir)',
|
||||
'--clear',
|
||||
'--jobs=16',
|
||||
],
|
||||
},
|
||||
],
|
||||
}], # OS=="mac"
|
||||
['OS=="win"', {
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'Dump Symbols',
|
||||
'inputs': [
|
||||
'<(PRODUCT_DIR)/<(project_name).exe',
|
||||
],
|
||||
'outputs': [
|
||||
'<(PRODUCT_DIR)/Atom-Shell.breakpad.syms',
|
||||
],
|
||||
'action': [
|
||||
'python',
|
||||
'tools/win/generate_breakpad_symbols.py',
|
||||
'--symbols-dir=<(PRODUCT_DIR)/Atom-Shell.breakpad.syms',
|
||||
'--jobs=16',
|
||||
'<(PRODUCT_DIR)',
|
||||
'<(libchromiumcontent_library_dir)',
|
||||
],
|
||||
},
|
||||
],
|
||||
}], # OS=="win"
|
||||
['OS=="linux"', {
|
||||
'dependencies': [
|
||||
'vendor/breakpad/breakpad.gyp:dump_syms',
|
||||
],
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'Dump Symbols',
|
||||
'inputs': [
|
||||
'<(PRODUCT_DIR)/<(project_name)',
|
||||
],
|
||||
'outputs': [
|
||||
'<(PRODUCT_DIR)/Atom-Shell.breakpad.syms',
|
||||
],
|
||||
'action': [
|
||||
'python',
|
||||
'tools/posix/generate_breakpad_symbols.py',
|
||||
'--build-dir=<(PRODUCT_DIR)',
|
||||
'--binary=<(PRODUCT_DIR)/<(project_name)',
|
||||
'--symbols-dir=<(PRODUCT_DIR)/Atom-Shell.breakpad.syms',
|
||||
'--libchromiumcontent-dir=<(libchromiumcontent_library_dir)',
|
||||
'--clear',
|
||||
'--jobs=16',
|
||||
],
|
||||
},
|
||||
{
|
||||
'action_name': 'Strip Binary',
|
||||
'inputs': [
|
||||
'<(PRODUCT_DIR)/libchromiumcontent.so',
|
||||
'<(PRODUCT_DIR)/libffmpegsumo.so',
|
||||
'<(PRODUCT_DIR)/<(project_name)',
|
||||
# Add the syms folder as input would force this action to run
|
||||
# after the 'Dump Symbols' action. And since it is a folder,
|
||||
# it would be ignored by the 'strip' command.
|
||||
'<(PRODUCT_DIR)/Atom-Shell.breakpad.syms',
|
||||
],
|
||||
'outputs': [
|
||||
# Gyp action requires a output file, add a fake one here.
|
||||
'<(PRODUCT_DIR)/dummy_file',
|
||||
],
|
||||
'action': [ 'strip', '<@(_inputs)' ],
|
||||
},
|
||||
],
|
||||
}], # OS=="linux"
|
||||
],
|
||||
}, # target <(project_name>_dump_symbols
|
||||
}, # target atom_coffee2c
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
'targets': [
|
||||
{
|
||||
'target_name': '<(project_name)_framework',
|
||||
'product_name': '<(framework_name)',
|
||||
'product_name': '<(product_name) Framework',
|
||||
'type': 'shared_library',
|
||||
'dependencies': [
|
||||
'<(project_name)_lib',
|
||||
@@ -593,7 +373,7 @@
|
||||
'include_dirs': [
|
||||
'.',
|
||||
'vendor',
|
||||
'<(libchromiumcontent_include_dir)',
|
||||
'<(libchromiumcontent_src_dir)',
|
||||
],
|
||||
'export_dependent_settings': [
|
||||
'<(project_name)_lib',
|
||||
@@ -601,6 +381,7 @@
|
||||
'link_settings': {
|
||||
'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',
|
||||
@@ -609,14 +390,15 @@
|
||||
'mac_bundle': 1,
|
||||
'mac_bundle_resources': [
|
||||
'atom/common/resources/mac/MainMenu.xib',
|
||||
'<(libchromiumcontent_resources_dir)/content_shell.pak',
|
||||
'<(libchromiumcontent_dir)/content_shell.pak',
|
||||
'<(libchromiumcontent_dir)/icudtl.dat',
|
||||
'<(libchromiumcontent_dir)/natives_blob.bin',
|
||||
'<(libchromiumcontent_dir)/snapshot_blob.bin',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'ATOM_BUNDLE_ID': 'com.<(company_abbr).<(project_name).framework',
|
||||
'INFOPLIST_FILE': 'atom/common/resources/mac/Info.plist',
|
||||
'LIBRARY_SEARCH_PATHS': [
|
||||
'<(libchromiumcontent_library_dir)',
|
||||
],
|
||||
'LD_DYLIB_INSTALL_NAME': '@rpath/<(framework_name).framework/<(framework_name)',
|
||||
'LD_DYLIB_INSTALL_NAME': '@rpath/<(product_name) Framework.framework/<(product_name) Framework',
|
||||
'LD_RUNPATH_SEARCH_PATHS': [
|
||||
'@loader_path/Libraries',
|
||||
],
|
||||
@@ -626,28 +408,51 @@
|
||||
},
|
||||
'copies': [
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/<(framework_name).framework/Versions/A/Libraries',
|
||||
'variables': {
|
||||
'conditions': [
|
||||
['libchromiumcontent_component', {
|
||||
'copied_libraries': [
|
||||
'<(PRODUCT_DIR)/libnode.dylib',
|
||||
'<@(libchromiumcontent_shared_libraries)',
|
||||
'<@(libchromiumcontent_shared_v8_libraries)',
|
||||
],
|
||||
}, {
|
||||
'copied_libraries': [
|
||||
'<(PRODUCT_DIR)/libnode.dylib',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Libraries',
|
||||
'files': [
|
||||
'<(libchromiumcontent_library_dir)/ffmpegsumo.so',
|
||||
'<(libchromiumcontent_library_dir)/libchromiumcontent.dylib',
|
||||
'<@(copied_libraries)',
|
||||
'<(libchromiumcontent_dir)/ffmpegsumo.so',
|
||||
],
|
||||
},
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/<(framework_name).framework/Versions/A/Resources',
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Resources',
|
||||
'files': [
|
||||
'<(PRODUCT_DIR)/Inspector',
|
||||
'<(PRODUCT_DIR)/crash_report_sender.app',
|
||||
'<(PRODUCT_DIR)/crashpad_handler',
|
||||
],
|
||||
},
|
||||
],
|
||||
'postbuilds': [
|
||||
{
|
||||
'postbuild_name': 'Fix path of libnode',
|
||||
'action': [
|
||||
'install_name_tool',
|
||||
'-change',
|
||||
'/usr/local/lib/libnode.dylib',
|
||||
'@rpath/libnode.dylib',
|
||||
'${BUILT_PRODUCTS_DIR}/<(product_name) Framework.framework/Versions/A/<(product_name) Framework',
|
||||
],
|
||||
},
|
||||
{
|
||||
'postbuild_name': 'Add symlinks for framework subdirectories',
|
||||
'action': [
|
||||
'tools/mac/create-framework-subdir-symlinks.sh',
|
||||
'<(framework_name)',
|
||||
'<(product_name) Framework',
|
||||
'Libraries',
|
||||
'Frameworks',
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -667,6 +472,7 @@
|
||||
],
|
||||
'mac_bundle': 1,
|
||||
'xcode_settings': {
|
||||
'ATOM_BUNDLE_ID': 'com.<(company_abbr).<(project_name).helper',
|
||||
'INFOPLIST_FILE': 'atom/renderer/resources/mac/Info.plist',
|
||||
'LD_RUNPATH_SEARCH_PATHS': [
|
||||
'@executable_path/../../..',
|
||||
@@ -674,38 +480,31 @@
|
||||
},
|
||||
}, # target helper
|
||||
],
|
||||
}], # OS==Mac
|
||||
['OS=="win"', {
|
||||
}, { # OS=="mac"
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'generate_node_lib',
|
||||
'target_name': 'make_locale_paks',
|
||||
'type': 'none',
|
||||
'dependencies': [
|
||||
'<(project_name)',
|
||||
],
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'Create node.lib',
|
||||
'action_name': 'Make Empty Paks',
|
||||
'inputs': [
|
||||
'<(PRODUCT_DIR)/atom.lib',
|
||||
'<(libchromiumcontent_library_dir)/chromiumcontent.dll.lib',
|
||||
'tools/make_locale_paks.py',
|
||||
],
|
||||
'outputs': [
|
||||
'<(PRODUCT_DIR)/node.lib',
|
||||
'<(PRODUCT_DIR)/locales'
|
||||
],
|
||||
'action': [
|
||||
'lib.exe',
|
||||
'/nologo',
|
||||
# We can't use <(_outputs) here because that escapes the
|
||||
# backslash in the path, which confuses lib.exe.
|
||||
'/OUT:<(PRODUCT_DIR)\\node.lib',
|
||||
'<@(_inputs)',
|
||||
'python',
|
||||
'tools/make_locale_paks.py',
|
||||
'<(PRODUCT_DIR)',
|
||||
'<@(locales)',
|
||||
],
|
||||
'msvs_cygwin_shell': 0,
|
||||
},
|
||||
],
|
||||
}, # target generate_node_lib
|
||||
},
|
||||
],
|
||||
}], # OS==win
|
||||
}], # OS!="mac"
|
||||
],
|
||||
}
|
||||
|
||||
96
atom/app/atom_content_client.cc
Normal file
96
atom/app/atom_content_client.cc
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/app/atom_content_client.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/chrome_version.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "content/public/common/content_constants.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
||||
const std::string& version) {
|
||||
content::PepperPluginInfo plugin;
|
||||
|
||||
plugin.is_out_of_process = true;
|
||||
plugin.name = content::kFlashPluginName;
|
||||
plugin.path = path;
|
||||
plugin.permissions = ppapi::PERMISSION_ALL_BITS;
|
||||
|
||||
std::vector<std::string> flash_version_numbers;
|
||||
base::SplitString(version, '.', &flash_version_numbers);
|
||||
if (flash_version_numbers.size() < 1)
|
||||
flash_version_numbers.push_back("11");
|
||||
// |SplitString()| puts in an empty string given an empty string. :(
|
||||
else if (flash_version_numbers[0].empty())
|
||||
flash_version_numbers[0] = "11";
|
||||
if (flash_version_numbers.size() < 2)
|
||||
flash_version_numbers.push_back("2");
|
||||
if (flash_version_numbers.size() < 3)
|
||||
flash_version_numbers.push_back("999");
|
||||
if (flash_version_numbers.size() < 4)
|
||||
flash_version_numbers.push_back("999");
|
||||
// E.g., "Shockwave Flash 10.2 r154":
|
||||
plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
|
||||
flash_version_numbers[1] + " r" + flash_version_numbers[2];
|
||||
plugin.version = JoinString(flash_version_numbers, '.');
|
||||
content::WebPluginMimeType swf_mime_type(
|
||||
content::kFlashPluginSwfMimeType,
|
||||
content::kFlashPluginSwfExtension,
|
||||
content::kFlashPluginSwfDescription);
|
||||
plugin.mime_types.push_back(swf_mime_type);
|
||||
content::WebPluginMimeType spl_mime_type(
|
||||
content::kFlashPluginSplMimeType,
|
||||
content::kFlashPluginSplExtension,
|
||||
content::kFlashPluginSplDescription);
|
||||
plugin.mime_types.push_back(spl_mime_type);
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomContentClient::AtomContentClient() {
|
||||
}
|
||||
|
||||
AtomContentClient::~AtomContentClient() {
|
||||
}
|
||||
|
||||
std::string AtomContentClient::GetProduct() const {
|
||||
return "Chrome/" CHROME_VERSION_STRING;
|
||||
}
|
||||
|
||||
void AtomContentClient::AddAdditionalSchemes(
|
||||
std::vector<std::string>* standard_schemes,
|
||||
std::vector<std::string>* savable_schemes) {
|
||||
standard_schemes->push_back("chrome-extension");
|
||||
}
|
||||
|
||||
void AtomContentClient::AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto flash_path = command_line->GetSwitchValueNative(
|
||||
switches::kPpapiFlashPath);
|
||||
if (flash_path.empty())
|
||||
return;
|
||||
|
||||
auto flash_version = command_line->GetSwitchValueASCII(
|
||||
switches::kPpapiFlashVersion);
|
||||
|
||||
plugins->push_back(
|
||||
CreatePepperFlashInfo(base::FilePath(flash_path), flash_version));
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
35
atom/app/atom_content_client.h
Normal file
35
atom/app/atom_content_client.h
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_APP_ATOM_CONTENT_CLIENT_H_
|
||||
#define ATOM_APP_ATOM_CONTENT_CLIENT_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "brightray/common/content_client.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomContentClient : public brightray::ContentClient {
|
||||
public:
|
||||
AtomContentClient();
|
||||
virtual ~AtomContentClient();
|
||||
|
||||
protected:
|
||||
// content::ContentClient:
|
||||
std::string GetProduct() const override;
|
||||
void AddAdditionalSchemes(
|
||||
std::vector<std::string>* standard_schemes,
|
||||
std::vector<std::string>* savable_schemes) override;
|
||||
void AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_APP_ATOM_CONTENT_CLIENT_H_
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/app/atom_library_main.h"
|
||||
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
#include "content/public/app/content_main.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
int AtomMain(int argc, const char* argv[]) {
|
||||
atom::AtomMainDelegate delegate;
|
||||
return content::ContentMain(argc, argv, &delegate);
|
||||
}
|
||||
#endif // OS_MACOSX
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
extern "C" {
|
||||
__attribute__((visibility("default")))
|
||||
int AtomMain(int argc, const char* argv[]);
|
||||
|
||||
__attribute__((visibility("default")))
|
||||
int AtomInitializeICUandStartNode(int argc, char *argv[]);
|
||||
}
|
||||
#endif // OS_MACOSX
|
||||
|
||||
|
||||
36
atom/app/atom_library_main.mm
Normal file
36
atom/app/atom_library_main.mm
Normal file
@@ -0,0 +1,36 @@
|
||||
// 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/app/atom_library_main.h"
|
||||
|
||||
#include "atom/app/atom_main_args.h"
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
#include "atom/app/node_main.h"
|
||||
#include "base/at_exit.h"
|
||||
#include "base/i18n/icu_util.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "brightray/common/mac/main_application_bundle.h"
|
||||
#include "content/public/app/content_main.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
int AtomMain(int argc, const char* argv[]) {
|
||||
atom::AtomMainDelegate delegate;
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.argc = argc;
|
||||
params.argv = argv;
|
||||
atom::AtomCommandLine::Init(argc, argv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
int AtomInitializeICUandStartNode(int argc, char *argv[]) {
|
||||
base::AtExitManager atexit_manager;
|
||||
base::mac::SetOverrideFrameworkBundlePath(
|
||||
brightray::MainApplicationBundlePath()
|
||||
.Append("Contents")
|
||||
.Append("Frameworks")
|
||||
.Append(ATOM_PRODUCT_NAME " Framework.framework"));
|
||||
base::i18n::InitializeICU();
|
||||
return atom::NodeMain(argc, argv);
|
||||
}
|
||||
#endif // OS_MACOSX
|
||||
@@ -1,8 +1,9 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// 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/app/atom_main.h"
|
||||
#include "atom/app/atom_main_args.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -13,13 +14,17 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <shellscalingapi.h>
|
||||
#include <tchar.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
#include "base/environment.h"
|
||||
#include "atom/common/crash_reporter/win/crash_service_main.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/win/windows_version.h"
|
||||
#include "content/public/app/startup_helper_win.h"
|
||||
#include "sandbox/win/src/sandbox_types.h"
|
||||
#include "ui/gfx/win/dpi.h"
|
||||
#elif defined(OS_LINUX) // defined(OS_WIN)
|
||||
#include "atom/app/atom_main_delegate.h" // NOLINT
|
||||
#include "content/public/app/content_main.h"
|
||||
@@ -27,13 +32,53 @@
|
||||
#include "atom/app/atom_library_main.h"
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
// Declaration of node::Start.
|
||||
namespace node {
|
||||
int Start(int argc, char *argv[]);
|
||||
}
|
||||
#include "atom/app/node_main.h"
|
||||
#include "base/i18n/icu_util.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
namespace {
|
||||
|
||||
// Win8.1 supports monitor-specific DPI scaling.
|
||||
bool SetProcessDpiAwarenessWrapper(PROCESS_DPI_AWARENESS value) {
|
||||
typedef HRESULT(WINAPI *SetProcessDpiAwarenessPtr)(PROCESS_DPI_AWARENESS);
|
||||
SetProcessDpiAwarenessPtr set_process_dpi_awareness_func =
|
||||
reinterpret_cast<SetProcessDpiAwarenessPtr>(
|
||||
GetProcAddress(GetModuleHandleA("user32.dll"),
|
||||
"SetProcessDpiAwarenessInternal"));
|
||||
if (set_process_dpi_awareness_func) {
|
||||
HRESULT hr = set_process_dpi_awareness_func(value);
|
||||
if (SUCCEEDED(hr)) {
|
||||
VLOG(1) << "SetProcessDpiAwareness succeeded.";
|
||||
return true;
|
||||
} else if (hr == E_ACCESSDENIED) {
|
||||
LOG(ERROR) << "Access denied error from SetProcessDpiAwareness. "
|
||||
"Function called twice, or manifest was used.";
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// This function works for Windows Vista through Win8. Win8.1 must use
|
||||
// SetProcessDpiAwareness[Wrapper].
|
||||
BOOL SetProcessDPIAwareWrapper() {
|
||||
typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID);
|
||||
SetProcessDPIAwarePtr set_process_dpi_aware_func =
|
||||
reinterpret_cast<SetProcessDPIAwarePtr>(
|
||||
GetProcAddress(GetModuleHandleA("user32.dll"),
|
||||
"SetProcessDPIAware"));
|
||||
return set_process_dpi_aware_func &&
|
||||
set_process_dpi_aware_func();
|
||||
}
|
||||
|
||||
void EnableHighDPISupport() {
|
||||
if (!SetProcessDpiAwarenessWrapper(PROCESS_SYSTEM_DPI_AWARE)) {
|
||||
SetProcessDPIAwareWrapper();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
int argc = 0;
|
||||
wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
||||
@@ -51,44 +96,46 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
freopen_s(&dontcare, "CON", "r", stdin);
|
||||
}
|
||||
|
||||
std::string node_indicator, crash_service_indicator;
|
||||
if (env->GetVar("ATOM_SHELL_INTERNAL_RUN_AS_NODE", &node_indicator) &&
|
||||
node_indicator == "1") {
|
||||
// Convert argv to to UTF8
|
||||
char** argv = new char*[argc];
|
||||
for (int i = 0; i < argc; i++) {
|
||||
// Compute the size of the required buffer
|
||||
DWORD size = WideCharToMultiByte(CP_UTF8,
|
||||
// Convert argv to to UTF8
|
||||
char** argv = new char*[argc];
|
||||
for (int i = 0; i < argc; i++) {
|
||||
// Compute the size of the required buffer
|
||||
DWORD size = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
wargv[i],
|
||||
-1,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
if (size == 0) {
|
||||
// This should never happen.
|
||||
fprintf(stderr, "Could not convert arguments to utf8.");
|
||||
exit(1);
|
||||
}
|
||||
// Do the actual conversion
|
||||
argv[i] = new char[size];
|
||||
DWORD result = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
wargv[i],
|
||||
-1,
|
||||
NULL,
|
||||
0,
|
||||
argv[i],
|
||||
size,
|
||||
NULL,
|
||||
NULL);
|
||||
if (size == 0) {
|
||||
// This should never happen.
|
||||
fprintf(stderr, "Could not convert arguments to utf8.");
|
||||
exit(1);
|
||||
}
|
||||
// Do the actual conversion
|
||||
argv[i] = new char[size];
|
||||
DWORD result = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
wargv[i],
|
||||
-1,
|
||||
argv[i],
|
||||
size,
|
||||
NULL,
|
||||
NULL);
|
||||
if (result == 0) {
|
||||
// This should never happen.
|
||||
fprintf(stderr, "Could not convert arguments to utf8.");
|
||||
exit(1);
|
||||
}
|
||||
if (result == 0) {
|
||||
// This should never happen.
|
||||
fprintf(stderr, "Could not convert arguments to utf8.");
|
||||
exit(1);
|
||||
}
|
||||
// Now that conversion is done, we can finally start.
|
||||
return node::Start(argc, argv);
|
||||
}
|
||||
|
||||
std::string node_indicator, crash_service_indicator;
|
||||
if (env->GetVar("ATOM_SHELL_INTERNAL_RUN_AS_NODE", &node_indicator) &&
|
||||
node_indicator == "1") {
|
||||
// Now that argv conversion is done, we can finally start.
|
||||
base::i18n::InitializeICU();
|
||||
return atom::NodeMain(argc, argv);
|
||||
} else if (env->GetVar("ATOM_SHELL_INTERNAL_CRASH_SERVICE",
|
||||
&crash_service_indicator) &&
|
||||
crash_service_indicator == "1") {
|
||||
@@ -98,26 +145,44 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
sandbox::SandboxInterfaceInfo sandbox_info = {0};
|
||||
content::InitializeSandboxInfo(&sandbox_info);
|
||||
atom::AtomMainDelegate delegate;
|
||||
return content::ContentMain(instance, &sandbox_info, &delegate);
|
||||
|
||||
// We don't want to set DPI awareness on pre-Win7 because we don't support
|
||||
// DirectWrite there. GDI fonts are kerned very badly, so better to leave
|
||||
// DPI-unaware and at effective 1.0. See also ShouldUseDirectWrite().
|
||||
if (base::win::GetVersion() >= base::win::VERSION_WIN7)
|
||||
EnableHighDPISupport();
|
||||
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.instance = instance;
|
||||
params.sandbox_info = &sandbox_info;
|
||||
atom::AtomCommandLine::Init(argc, argv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
#elif defined(OS_LINUX) // defined(OS_WIN)
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
char* node_indicator = getenv("ATOM_SHELL_INTERNAL_RUN_AS_NODE");
|
||||
if (node_indicator != NULL && strcmp(node_indicator, "1") == 0)
|
||||
return node::Start(argc, const_cast<char**>(argv));
|
||||
if (node_indicator != NULL && strcmp(node_indicator, "1") == 0) {
|
||||
base::i18n::InitializeICU();
|
||||
return atom::NodeMain(argc, const_cast<char**>(argv));
|
||||
}
|
||||
|
||||
atom::AtomMainDelegate delegate;
|
||||
return content::ContentMain(argc, argv, &delegate);
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.argc = argc;
|
||||
params.argv = argv;
|
||||
atom::AtomCommandLine::Init(argc, argv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
#else // defined(OS_LINUX)
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
char* node_indicator = getenv("ATOM_SHELL_INTERNAL_RUN_AS_NODE");
|
||||
if (node_indicator != NULL && strcmp(node_indicator, "1") == 0)
|
||||
return node::Start(argc, const_cast<char**>(argv));
|
||||
if (node_indicator != NULL && strcmp(node_indicator, "1") == 0) {
|
||||
return AtomInitializeICUandStartNode(argc, const_cast<char**>(argv));
|
||||
}
|
||||
|
||||
return AtomMain(argc, argv);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
||||
22
atom/app/atom_main_args.cc
Normal file
22
atom/app/atom_main_args.cc
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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/app/atom_main_args.h"
|
||||
#include "vendor/node/deps/uv/include/uv.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
// static
|
||||
std::vector<std::string> AtomCommandLine::argv_;
|
||||
|
||||
// static
|
||||
void AtomCommandLine::Init(int argc, const char* const* argv) {
|
||||
// Hack around with the argv pointer. Used for process.title = "blah"
|
||||
char** new_argv = uv_setup_args(argc, const_cast<char**>(argv));
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
argv_.push_back(new_argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
29
atom/app/atom_main_args.h
Normal file
29
atom/app/atom_main_args.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// 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_APP_ATOM_MAIN_ARGS_H_
|
||||
#define ATOM_APP_ATOM_MAIN_ARGS_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/macros.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
// Singleton to remember the original "argc" and "argv".
|
||||
class AtomCommandLine {
|
||||
public:
|
||||
static void Init(int argc, const char* const* argv);
|
||||
static std::vector<std::string> argv() { return argv_; }
|
||||
|
||||
private:
|
||||
static std::vector<std::string> argv_;
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(AtomCommandLine);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_APP_ATOM_MAIN_ARGS_H_
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -6,14 +6,17 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/app/atom_content_client.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/common/google_api_key.h"
|
||||
#include "atom/renderer/atom_renderer_client.h"
|
||||
#include "atom/utility/atom_content_utility_client.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/debug/stack_trace.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/logging.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "atom/renderer/atom_renderer_client.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
#include "base/path_service.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -25,8 +28,8 @@ AtomMainDelegate::~AtomMainDelegate() {
|
||||
|
||||
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
// Disable logging out to debug.log on Windows
|
||||
#if defined(OS_WIN)
|
||||
logging::LoggingSettings settings;
|
||||
#if defined(OS_WIN)
|
||||
#if defined(DEBUG)
|
||||
settings.logging_dest = logging::LOG_TO_ALL;
|
||||
settings.log_file = L"debug.log";
|
||||
@@ -34,17 +37,15 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
|
||||
#else
|
||||
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
||||
#endif
|
||||
settings.dcheck_state =
|
||||
logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS;
|
||||
logging::InitLogging(settings);
|
||||
#endif // defined(DEBUG)
|
||||
#endif // defined(OS_WIN)
|
||||
logging::InitLogging(settings);
|
||||
|
||||
// Logging with pid and timestamp.
|
||||
logging::SetLogItems(true, false, true, false);
|
||||
|
||||
// Enable convient stack printing.
|
||||
#if defined(DEBUG) && defined(OS_LINUX)
|
||||
// Enable convient stack printing.
|
||||
base::debug::EnableInProcessStackDumping();
|
||||
#endif
|
||||
|
||||
@@ -52,41 +53,42 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
}
|
||||
|
||||
void AtomMainDelegate::PreSandboxStartup() {
|
||||
#if defined(OS_MACOSX)
|
||||
OverrideChildProcessPath();
|
||||
OverrideFrameworkBundlePath();
|
||||
#endif
|
||||
InitializeResourceBundle();
|
||||
brightray::MainDelegate::PreSandboxStartup();
|
||||
|
||||
CommandLine* command_line = CommandLine::ForCurrentProcess();
|
||||
// Set google API key.
|
||||
scoped_ptr<base::Environment> env(base::Environment::Create());
|
||||
if (!env->HasVar("GOOGLE_API_KEY"))
|
||||
env->SetVar("GOOGLE_API_KEY", GOOGLEAPIS_API_KEY);
|
||||
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
std::string process_type = command_line->GetSwitchValueASCII(
|
||||
switches::kProcessType);
|
||||
|
||||
if (process_type == switches::kUtilityProcess) {
|
||||
AtomContentUtilityClient::PreSandboxStartup();
|
||||
}
|
||||
|
||||
// Only append arguments for browser process.
|
||||
if (!process_type.empty())
|
||||
return;
|
||||
|
||||
// Add a flag to mark the start of switches added by atom-shell.
|
||||
command_line->AppendSwitch("atom-shell-switches-start");
|
||||
#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);
|
||||
|
||||
// Add a flag to mark the end of switches added by atom-shell.
|
||||
command_line->AppendSwitch("atom-shell-switches-end");
|
||||
}
|
||||
// Allow file:// URIs to read other file:// URIs by default.
|
||||
command_line->AppendSwitch(switches::kAllowFileAccessFromFiles);
|
||||
|
||||
void AtomMainDelegate::InitializeResourceBundle() {
|
||||
base::FilePath path;
|
||||
#if defined(OS_MACOSX)
|
||||
path = GetResourcesPakFilePath();
|
||||
#else
|
||||
base::FilePath pak_dir;
|
||||
PathService::Get(base::DIR_MODULE, &pak_dir);
|
||||
path = pak_dir.Append(FILE_PATH_LITERAL("content_shell.pak"));
|
||||
// Enable AVFoundation.
|
||||
command_line->AppendSwitch("enable-avfoundation");
|
||||
#endif
|
||||
|
||||
ui::ResourceBundle::InitSharedInstanceWithPakPath(path);
|
||||
}
|
||||
|
||||
content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
|
||||
@@ -100,4 +102,25 @@ content::ContentRendererClient*
|
||||
return renderer_client_.get();
|
||||
}
|
||||
|
||||
content::ContentUtilityClient* AtomMainDelegate::CreateContentUtilityClient() {
|
||||
utility_client_.reset(new AtomContentUtilityClient);
|
||||
return utility_client_.get();
|
||||
}
|
||||
|
||||
scoped_ptr<brightray::ContentClient> AtomMainDelegate::CreateContentClient() {
|
||||
return scoped_ptr<brightray::ContentClient>(new AtomContentClient).Pass();
|
||||
}
|
||||
|
||||
void AtomMainDelegate::AddDataPackFromPath(
|
||||
ui::ResourceBundle* bundle, const base::FilePath& pak_dir) {
|
||||
#if defined(OS_WIN)
|
||||
bundle->AddDataPackFromPath(
|
||||
pak_dir.Append(FILE_PATH_LITERAL("ui_resources_200_percent.pak")),
|
||||
ui::SCALE_FACTOR_200P);
|
||||
bundle->AddDataPackFromPath(
|
||||
pak_dir.Append(FILE_PATH_LITERAL("content_resources_200_percent.pak")),
|
||||
ui::SCALE_FACTOR_200P);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define ATOM_APP_ATOM_MAIN_DELEGATE_H_
|
||||
|
||||
#include "brightray/common/main_delegate.h"
|
||||
#include "brightray/common/content_client.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -15,23 +16,27 @@ class AtomMainDelegate : public brightray::MainDelegate {
|
||||
~AtomMainDelegate();
|
||||
|
||||
protected:
|
||||
virtual bool BasicStartupComplete(int* exit_code) OVERRIDE;
|
||||
virtual void PreSandboxStartup() OVERRIDE;
|
||||
virtual void InitializeResourceBundle();
|
||||
// content::ContentMainDelegate:
|
||||
bool BasicStartupComplete(int* exit_code) override;
|
||||
void PreSandboxStartup() override;
|
||||
content::ContentBrowserClient* CreateContentBrowserClient() override;
|
||||
content::ContentRendererClient* CreateContentRendererClient() override;
|
||||
content::ContentUtilityClient* CreateContentUtilityClient() override;
|
||||
|
||||
// brightray::MainDelegate:
|
||||
scoped_ptr<brightray::ContentClient> CreateContentClient() override;
|
||||
void AddDataPackFromPath(
|
||||
ui::ResourceBundle* bundle, const base::FilePath& pak_dir) override;
|
||||
#if defined(OS_MACOSX)
|
||||
virtual base::FilePath GetResourcesPakFilePath();
|
||||
virtual void OverrideChildProcessPath();
|
||||
virtual void OverrideFrameworkBundlePath();
|
||||
void OverrideChildProcessPath() override;
|
||||
void OverrideFrameworkBundlePath() override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
virtual content::ContentBrowserClient* CreateContentBrowserClient() OVERRIDE;
|
||||
virtual content::ContentRendererClient*
|
||||
CreateContentRendererClient() OVERRIDE;
|
||||
|
||||
brightray::ContentClient content_client_;
|
||||
scoped_ptr<content::ContentBrowserClient> browser_client_;
|
||||
scoped_ptr<content::ContentRendererClient> renderer_client_;
|
||||
scoped_ptr<content::ContentUtilityClient> utility_client_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomMainDelegate);
|
||||
};
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
|
||||
#import "base/mac/bundle_locations.h"
|
||||
#import "base/mac/foundation_util.h"
|
||||
#import "base/mac/mac_util.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
#include "brightray/common/mac/main_application_bundle.h"
|
||||
#include "content/public/common/content_paths.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "vendor/brightray/common/application_info.h"
|
||||
#include "vendor/brightray/common/mac/main_application_bundle.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -24,24 +21,30 @@ base::FilePath GetFrameworksPath() {
|
||||
.Append("Frameworks");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
base::FilePath AtomMainDelegate::GetResourcesPakFilePath() {
|
||||
NSString* path = [base::mac::FrameworkBundle()
|
||||
pathForResource:@"content_shell" ofType:@"pak"];
|
||||
return base::mac::NSStringToFilePath(path);
|
||||
base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
|
||||
const std::string& name) {
|
||||
return frameworks_path.Append(name + " Helper.app")
|
||||
.Append("Contents")
|
||||
.Append("MacOS")
|
||||
.Append(name + " Helper");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void AtomMainDelegate::OverrideFrameworkBundlePath() {
|
||||
base::mac::SetOverrideFrameworkBundlePath(
|
||||
GetFrameworksPath().Append("Atom Framework.framework"));
|
||||
GetFrameworksPath().Append(ATOM_PRODUCT_NAME " Framework.framework"));
|
||||
}
|
||||
|
||||
void AtomMainDelegate::OverrideChildProcessPath() {
|
||||
base::FilePath helper_path = GetFrameworksPath().Append("Atom Helper.app")
|
||||
.Append("Contents")
|
||||
.Append("MacOS")
|
||||
.Append("Atom Helper");
|
||||
base::FilePath frameworks_path = GetFrameworksPath();
|
||||
base::FilePath helper_path = GetHelperAppPath(frameworks_path,
|
||||
ATOM_PRODUCT_NAME);
|
||||
if (!base::PathExists(helper_path))
|
||||
helper_path = GetHelperAppPath(frameworks_path,
|
||||
brightray::GetApplicationName());
|
||||
if (!base::PathExists(helper_path))
|
||||
LOG(FATAL) << "Unable to find helper app";
|
||||
PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
|
||||
}
|
||||
|
||||
|
||||
68
atom/app/node_main.cc
Normal file
68
atom/app/node_main.cc
Normal file
@@ -0,0 +1,68 @@
|
||||
// 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/app/node_main.h"
|
||||
|
||||
#include "atom/browser/javascript_environment.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "gin/array_buffer.h"
|
||||
#include "gin/public/isolate_holder.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
int NodeMain(int argc, char *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;
|
||||
{
|
||||
gin::IsolateHolder::LoadV8Snapshot();
|
||||
gin::IsolateHolder::Initialize(
|
||||
gin::IsolateHolder::kNonStrictMode,
|
||||
gin::ArrayBufferAllocator::SharedInstance());
|
||||
|
||||
JavascriptEnvironment gin_env;
|
||||
node::Environment* env = node::CreateEnvironment(
|
||||
gin_env.isolate(), uv_default_loop(), gin_env.context(), argc, argv,
|
||||
exec_argc, exec_argv);
|
||||
|
||||
// Start debugger.
|
||||
node::node_isolate = gin_env.isolate();
|
||||
if (node::use_debug_agent)
|
||||
node::StartDebug(env, node::debug_wait_connect);
|
||||
|
||||
node::LoadEnvironment(env);
|
||||
|
||||
// Enable debugger.
|
||||
if (node::use_debug_agent)
|
||||
node::EnableDebug(env);
|
||||
|
||||
bool more;
|
||||
do {
|
||||
more = uv_run(env->event_loop(), UV_RUN_ONCE);
|
||||
if (more == false) {
|
||||
node::EmitBeforeExit(env);
|
||||
|
||||
// Emit `beforeExit` if the loop became alive either after emitting
|
||||
// event, or after running some callbacks.
|
||||
more = uv_loop_alive(env->event_loop());
|
||||
if (uv_run(env->event_loop(), UV_RUN_NOWAIT) != 0)
|
||||
more = true;
|
||||
}
|
||||
} while (more == true);
|
||||
|
||||
exit_code = node::EmitExit(env);
|
||||
node::RunAtExit(env);
|
||||
|
||||
env->Dispose();
|
||||
}
|
||||
|
||||
v8::V8::Dispose();
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
14
atom/app/node_main.h
Normal file
14
atom/app/node_main.h
Normal file
@@ -0,0 +1,14 @@
|
||||
// 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_APP_NODE_MAIN_H_
|
||||
#define ATOM_APP_NODE_MAIN_H_
|
||||
|
||||
namespace atom {
|
||||
|
||||
int NodeMain(int argc, char *argv[]);
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_APP_NODE_MAIN_H_
|
||||
@@ -1,25 +1,136 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_app.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/values.h"
|
||||
#include "base/command_line.h"
|
||||
#if defined(OS_WIN)
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.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 "native_mate/callback.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/proxy/proxy_service.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#endif
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using atom::Browser;
|
||||
|
||||
namespace mate {
|
||||
|
||||
#if defined(OS_WIN)
|
||||
template<>
|
||||
struct Converter<Browser::UserTask> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
Browser::UserTask* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
if (!dict.Get("program", &(out->program)) ||
|
||||
!dict.Get("title", &(out->title)))
|
||||
return false;
|
||||
if (dict.Get("iconPath", &(out->icon_path)) &&
|
||||
!dict.Get("iconIndex", &(out->icon_index)))
|
||||
return false;
|
||||
dict.Get("arguments", &(out->arguments));
|
||||
dict.Get("description", &(out->description));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace mate
|
||||
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// Return the path constant from string.
|
||||
int GetPathConstant(const std::string& name) {
|
||||
if (name == "appData")
|
||||
return brightray::DIR_APP_DATA;
|
||||
else if (name == "userData")
|
||||
return brightray::DIR_USER_DATA;
|
||||
else if (name == "cache")
|
||||
return brightray::DIR_CACHE;
|
||||
else if (name == "userCache")
|
||||
return brightray::DIR_USER_CACHE;
|
||||
else if (name == "home")
|
||||
return base::DIR_HOME;
|
||||
else if (name == "temp")
|
||||
return base::DIR_TEMP;
|
||||
else if (name == "userDesktop")
|
||||
return base::DIR_USER_DESKTOP;
|
||||
else if (name == "exe")
|
||||
return base::FILE_EXE;
|
||||
else if (name == "module")
|
||||
return base::FILE_MODULE;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
class ResolveProxyHelper {
|
||||
public:
|
||||
ResolveProxyHelper(const GURL& url, App::ResolveProxyCallback callback)
|
||||
: callback_(callback) {
|
||||
net::ProxyService* proxy_service = AtomBrowserContext::Get()->
|
||||
url_request_context_getter()->GetURLRequestContext()->proxy_service();
|
||||
|
||||
// Start the request.
|
||||
int result = proxy_service->ResolveProxy(
|
||||
url, net::LOAD_NORMAL, &proxy_info_,
|
||||
base::Bind(&ResolveProxyHelper::OnResolveProxyCompleted,
|
||||
base::Unretained(this)),
|
||||
&pac_req_, nullptr, net::BoundNetLog());
|
||||
|
||||
// Completed synchronously.
|
||||
if (result != net::ERR_IO_PENDING)
|
||||
OnResolveProxyCompleted(result);
|
||||
}
|
||||
|
||||
void OnResolveProxyCompleted(int result) {
|
||||
std::string proxy;
|
||||
if (result == net::OK)
|
||||
proxy = proxy_info_.ToPacString();
|
||||
callback_.Run(proxy);
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
App::ResolveProxyCallback callback_;
|
||||
net::ProxyInfo proxy_info_;
|
||||
net::ProxyService::PacRequest* pac_req_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
App::App() {
|
||||
Browser::Get()->AddObserver(this);
|
||||
}
|
||||
@@ -28,6 +139,10 @@ App::~App() {
|
||||
Browser::Get()->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void App::OnBeforeQuit(bool* prevent_default) {
|
||||
*prevent_default = Emit("before-quit");
|
||||
}
|
||||
|
||||
void App::OnWillQuit(bool* prevent_default) {
|
||||
*prevent_default = Emit("will-quit");
|
||||
}
|
||||
@@ -36,16 +151,16 @@ void App::OnWindowAllClosed() {
|
||||
Emit("window-all-closed");
|
||||
}
|
||||
|
||||
void App::OnQuit() {
|
||||
Emit("quit");
|
||||
}
|
||||
|
||||
void App::OnOpenFile(bool* prevent_default, const std::string& file_path) {
|
||||
base::ListValue args;
|
||||
args.AppendString(file_path);
|
||||
*prevent_default = Emit("open-file", args);
|
||||
*prevent_default = Emit("open-file", file_path);
|
||||
}
|
||||
|
||||
void App::OnOpenURL(const std::string& url) {
|
||||
base::ListValue args;
|
||||
args.AppendString(url);
|
||||
Emit("open-url", args);
|
||||
Emit("open-url", url);
|
||||
}
|
||||
|
||||
void App::OnActivateWithNoOpenWindows() {
|
||||
@@ -60,22 +175,70 @@ void App::OnFinishLaunching() {
|
||||
Emit("ready");
|
||||
}
|
||||
|
||||
base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
|
||||
bool succeed = false;
|
||||
base::FilePath path;
|
||||
int key = GetPathConstant(name);
|
||||
if (key >= 0)
|
||||
succeed = PathService::Get(key, &path);
|
||||
if (!succeed)
|
||||
args->ThrowError("Failed to get path");
|
||||
return path;
|
||||
}
|
||||
|
||||
void App::SetPath(mate::Arguments* args,
|
||||
const std::string& name,
|
||||
const base::FilePath& path) {
|
||||
bool succeed = false;
|
||||
int key = GetPathConstant(name);
|
||||
if (key >= 0)
|
||||
succeed = PathService::Override(key, path);
|
||||
if (!succeed)
|
||||
args->ThrowError("Failed to set path");
|
||||
}
|
||||
|
||||
void App::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
|
||||
new ResolveProxyHelper(url, callback);
|
||||
}
|
||||
|
||||
void App::SetDesktopName(const std::string& desktop_name) {
|
||||
#if defined(OS_LINUX)
|
||||
scoped_ptr<base::Environment> env(base::Environment::Create());
|
||||
env->SetVar("CHROME_DESKTOP", 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
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
Browser* browser = Browser::Get();
|
||||
auto browser = base::Unretained(Browser::Get());
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("quit", base::Bind(&Browser::Quit,
|
||||
base::Unretained(browser)))
|
||||
.SetMethod("focus", base::Bind(&Browser::Focus,
|
||||
base::Unretained(browser)))
|
||||
.SetMethod("getVersion", base::Bind(&Browser::GetVersion,
|
||||
base::Unretained(browser)))
|
||||
.SetMethod("setVersion", base::Bind(&Browser::SetVersion,
|
||||
base::Unretained(browser)))
|
||||
.SetMethod("getName", base::Bind(&Browser::GetName,
|
||||
base::Unretained(browser)))
|
||||
.SetMethod("setName", base::Bind(&Browser::SetName,
|
||||
base::Unretained(browser)));
|
||||
.SetMethod("quit", base::Bind(&Browser::Quit, browser))
|
||||
.SetMethod("focus", base::Bind(&Browser::Focus, browser))
|
||||
.SetMethod("getVersion", base::Bind(&Browser::GetVersion, browser))
|
||||
.SetMethod("setVersion", base::Bind(&Browser::SetVersion, browser))
|
||||
.SetMethod("getName", base::Bind(&Browser::GetName, browser))
|
||||
.SetMethod("setName", base::Bind(&Browser::SetName, browser))
|
||||
.SetMethod("isReady", base::Bind(&Browser::is_ready, browser))
|
||||
.SetMethod("addRecentDocument",
|
||||
base::Bind(&Browser::AddRecentDocument, browser))
|
||||
.SetMethod("clearRecentDocuments",
|
||||
base::Bind(&Browser::ClearRecentDocuments, browser))
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("setUserTasks",
|
||||
base::Bind(&Browser::SetUserTasks, browser))
|
||||
#endif
|
||||
.SetMethod("setPath", &App::SetPath)
|
||||
.SetMethod("getPath", &App::GetPath)
|
||||
.SetMethod("resolveProxy", &App::ResolveProxy)
|
||||
.SetMethod("setDesktopName", &App::SetDesktopName)
|
||||
.SetMethod("setAppUserModelId", &App::SetAppUserModelId);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -91,11 +254,12 @@ mate::Handle<App> App::Create(v8::Isolate* isolate) {
|
||||
namespace {
|
||||
|
||||
void AppendSwitch(const std::string& switch_string, mate::Arguments* args) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
std::string value;
|
||||
if (args->GetNext(&value))
|
||||
CommandLine::ForCurrentProcess()->AppendSwitchASCII(switch_string, value);
|
||||
command_line->AppendSwitchASCII(switch_string, value);
|
||||
else
|
||||
CommandLine::ForCurrentProcess()->AppendSwitch(switch_string);
|
||||
command_line->AppendSwitch(switch_string);
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
@@ -107,33 +271,38 @@ int DockBounce(const std::string& type) {
|
||||
request_id = Browser::Get()->DockBounce(Browser::BOUNCE_INFORMATIONAL);
|
||||
return request_id;
|
||||
}
|
||||
|
||||
void DockSetMenu(atom::api::Menu* menu) {
|
||||
Browser::Get()->DockSetMenu(menu->model());
|
||||
}
|
||||
#endif
|
||||
|
||||
void Initialize(v8::Handle<v8::Object> exports) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
Browser* browser = Browser::Get();
|
||||
CommandLine* command_line = CommandLine::ForCurrentProcess();
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("app", atom::api::App::Create(isolate));
|
||||
dict.SetMethod("appendSwitch", &AppendSwitch);
|
||||
dict.SetMethod("appendArgument",
|
||||
base::Bind(&CommandLine::AppendArg,
|
||||
base::Bind(&base::CommandLine::AppendArg,
|
||||
base::Unretained(command_line)));
|
||||
#if defined(OS_MACOSX)
|
||||
auto browser = base::Unretained(Browser::Get());
|
||||
dict.SetMethod("dockBounce", &DockBounce);
|
||||
dict.SetMethod("dockCancelBounce",
|
||||
base::Bind(&Browser::DockCancelBounce,
|
||||
base::Unretained(browser)));
|
||||
base::Bind(&Browser::DockCancelBounce, browser));
|
||||
dict.SetMethod("dockSetBadgeText",
|
||||
base::Bind(&Browser::DockSetBadgeText,
|
||||
base::Unretained(browser)));
|
||||
base::Bind(&Browser::DockSetBadgeText, browser));
|
||||
dict.SetMethod("dockGetBadgeText",
|
||||
base::Bind(&Browser::DockGetBadgeText,
|
||||
base::Unretained(browser)));
|
||||
base::Bind(&Browser::DockGetBadgeText, browser));
|
||||
dict.SetMethod("dockHide", base::Bind(&Browser::DockHide, browser));
|
||||
dict.SetMethod("dockShow", base::Bind(&Browser::DockShow, browser));
|
||||
dict.SetMethod("dockSetMenu", &DockSetMenu);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE(atom_browser_app, Initialize)
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_app, Initialize)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -7,11 +7,21 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/browser_observer.h"
|
||||
#include "base/callback.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
class GURL;
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -19,27 +29,40 @@ namespace api {
|
||||
class App : public mate::EventEmitter,
|
||||
public BrowserObserver {
|
||||
public:
|
||||
typedef base::Callback<void(std::string)> ResolveProxyCallback;
|
||||
|
||||
static mate::Handle<App> Create(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
App();
|
||||
virtual ~App();
|
||||
|
||||
// BrowserObserver implementations:
|
||||
virtual void OnWillQuit(bool* prevent_default) OVERRIDE;
|
||||
virtual void OnWindowAllClosed() OVERRIDE;
|
||||
virtual void OnOpenFile(bool* prevent_default,
|
||||
const std::string& file_path) OVERRIDE;
|
||||
virtual void OnOpenURL(const std::string& url) OVERRIDE;
|
||||
virtual void OnActivateWithNoOpenWindows() OVERRIDE;
|
||||
virtual void OnWillFinishLaunching() OVERRIDE;
|
||||
virtual void OnFinishLaunching() OVERRIDE;
|
||||
// BrowserObserver:
|
||||
void OnBeforeQuit(bool* prevent_default) override;
|
||||
void OnWillQuit(bool* prevent_default) override;
|
||||
void OnWindowAllClosed() override;
|
||||
void OnQuit() override;
|
||||
void OnOpenFile(bool* prevent_default, const std::string& file_path) override;
|
||||
void OnOpenURL(const std::string& url) override;
|
||||
void OnActivateWithNoOpenWindows() override;
|
||||
void OnWillFinishLaunching() override;
|
||||
void OnFinishLaunching() override;
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate);
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
// Get/Set the pre-defined path in PathService.
|
||||
base::FilePath GetPath(mate::Arguments* args, const std::string& name);
|
||||
void SetPath(mate::Arguments* args,
|
||||
const std::string& name,
|
||||
const base::FilePath& path);
|
||||
|
||||
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
|
||||
void SetDesktopName(const std::string& desktop_name);
|
||||
void SetAppUserModelId(const std::string& app_id);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(App);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_auto_updater.h"
|
||||
|
||||
#include "base/time/time.h"
|
||||
#include "base/values.h"
|
||||
#include "atom/browser/auto_updater.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
@@ -26,9 +25,7 @@ AutoUpdater::~AutoUpdater() {
|
||||
}
|
||||
|
||||
void AutoUpdater::OnError(const std::string& error) {
|
||||
base::ListValue args;
|
||||
args.AppendString(error);
|
||||
Emit("error", args);
|
||||
Emit("error", error);
|
||||
}
|
||||
|
||||
void AutoUpdater::OnCheckingForUpdate() {
|
||||
@@ -49,13 +46,8 @@ void AutoUpdater::OnUpdateDownloaded(const std::string& release_notes,
|
||||
const std::string& update_url,
|
||||
const base::Closure& quit_and_install) {
|
||||
quit_and_install_ = quit_and_install;
|
||||
|
||||
base::ListValue args;
|
||||
args.AppendString(release_notes);
|
||||
args.AppendString(release_name);
|
||||
args.AppendDouble(release_date.ToJsTime());
|
||||
args.AppendString(update_url);
|
||||
Emit("update-downloaded-raw", args);
|
||||
Emit("update-downloaded-raw", release_notes, release_name,
|
||||
release_date.ToJsTime(), update_url);
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder AutoUpdater::GetObjectTemplateBuilder(
|
||||
@@ -85,12 +77,13 @@ mate::Handle<AutoUpdater> AutoUpdater::Create(v8::Isolate* isolate) {
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Handle<v8::Object> exports) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("autoUpdater", atom::api::AutoUpdater::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE(atom_browser_auto_updater, Initialize)
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_auto_updater, Initialize)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -26,20 +26,20 @@ class AutoUpdater : public mate::EventEmitter,
|
||||
virtual ~AutoUpdater();
|
||||
|
||||
// AutoUpdaterDelegate implementations.
|
||||
virtual void OnError(const std::string& error) OVERRIDE;
|
||||
virtual void OnCheckingForUpdate() OVERRIDE;
|
||||
virtual void OnUpdateAvailable() OVERRIDE;
|
||||
virtual void OnUpdateNotAvailable() OVERRIDE;
|
||||
virtual void OnUpdateDownloaded(
|
||||
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;
|
||||
const base::Closure& quit_and_install) override;
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate);
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
void QuitAndInstall();
|
||||
|
||||
75
atom/browser/api/atom_api_content_tracing.cc
Normal file
75
atom/browser/api/atom_api_content_tracing.cc
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "base/bind.h"
|
||||
#include "content/public/browser/tracing_controller.h"
|
||||
#include "native_mate/callback.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using content::TracingController;
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<base::trace_event::CategoryFilter> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::trace_event::CategoryFilter* out) {
|
||||
std::string filter;
|
||||
if (!ConvertFromV8(isolate, val, &filter))
|
||||
return false;
|
||||
*out = base::trace_event::CategoryFilter(filter);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<base::trace_event::TraceOptions> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::trace_event::TraceOptions* out) {
|
||||
std::string options;
|
||||
if (!ConvertFromV8(isolate, val, &options))
|
||||
return false;
|
||||
return out->SetFromString(options);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
auto controller = base::Unretained(TracingController::GetInstance());
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("getCategories", base::Bind(
|
||||
&TracingController::GetCategories, controller));
|
||||
dict.SetMethod("startRecording", base::Bind(
|
||||
&TracingController::EnableRecording, controller));
|
||||
dict.SetMethod("stopRecording", base::Bind(
|
||||
&TracingController::DisableRecording, controller, nullptr));
|
||||
dict.SetMethod("startMonitoring", base::Bind(
|
||||
&TracingController::EnableMonitoring, controller));
|
||||
dict.SetMethod("stopMonitoring", base::Bind(
|
||||
&TracingController::DisableMonitoring, controller));
|
||||
dict.SetMethod("captureMonitoringSnapshot", base::Bind(
|
||||
&TracingController::CaptureMonitoringSnapshot, controller, nullptr));
|
||||
dict.SetMethod("getTraceBufferUsage", base::Bind(
|
||||
&TracingController::GetTraceBufferUsage, controller));
|
||||
dict.SetMethod("setWatchEvent", base::Bind(
|
||||
&TracingController::SetWatchEvent, controller));
|
||||
dict.SetMethod("cancelWatchEvent", base::Bind(
|
||||
&TracingController::CancelWatchEvent, controller));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_content_tracing, Initialize)
|
||||
@@ -1,88 +1,120 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// 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 <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "atom/browser/api/atom_api_window.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "atom/browser/ui/message_box.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/function_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "native_mate/callback.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<file_dialog::Filter> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
file_dialog::Filter* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
if (!dict.Get("name", &(out->first)))
|
||||
return false;
|
||||
if (!dict.Get("extensions", &(out->second)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace {
|
||||
|
||||
void ShowMessageBox(int type,
|
||||
const std::vector<std::string>& buttons,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::vector<std::string>& texts,
|
||||
const gfx::ImageSkia& icon,
|
||||
atom::NativeWindow* window,
|
||||
mate::Arguments* args) {
|
||||
v8::Handle<v8::Value> peek = args->PeekNext();
|
||||
// FIXME We are exceeding the parameters limit of base::Bind here, so we have
|
||||
// to pass some parameters in an array. We should remove this once we have
|
||||
// variadic template support in base::Bind.
|
||||
const std::string& title = texts[0];
|
||||
const std::string& message = texts[1];
|
||||
const std::string& detail = texts[2];
|
||||
|
||||
v8::Local<v8::Value> peek = args->PeekNext();
|
||||
atom::MessageBoxCallback callback;
|
||||
if (mate::Converter<atom::MessageBoxCallback>::FromV8(node_isolate,
|
||||
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(),
|
||||
peek,
|
||||
&callback)) {
|
||||
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons, title,
|
||||
message, detail, callback);
|
||||
message, detail, icon, callback);
|
||||
} else {
|
||||
int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type,
|
||||
buttons, title, message, detail);
|
||||
buttons, title, message, detail, icon);
|
||||
args->Return(chosen);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowOpenDialog(const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
const file_dialog::Filters& filters,
|
||||
int properties,
|
||||
atom::NativeWindow* window,
|
||||
mate::Arguments* args) {
|
||||
v8::Handle<v8::Value> peek = args->PeekNext();
|
||||
v8::Local<v8::Value> peek = args->PeekNext();
|
||||
file_dialog::OpenDialogCallback callback;
|
||||
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(node_isolate,
|
||||
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(args->isolate(),
|
||||
peek,
|
||||
&callback)) {
|
||||
file_dialog::ShowOpenDialog(window, title, default_path, properties,
|
||||
callback);
|
||||
file_dialog::ShowOpenDialog(window, title, default_path, filters,
|
||||
properties, callback);
|
||||
} else {
|
||||
std::vector<base::FilePath> paths;
|
||||
if (file_dialog::ShowOpenDialog(window, title, default_path, properties,
|
||||
&paths))
|
||||
if (file_dialog::ShowOpenDialog(window, title, default_path, filters,
|
||||
properties, &paths))
|
||||
args->Return(paths);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowSaveDialog(const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
const file_dialog::Filters& filters,
|
||||
atom::NativeWindow* window,
|
||||
mate::Arguments* args) {
|
||||
v8::Handle<v8::Value> peek = args->PeekNext();
|
||||
v8::Local<v8::Value> peek = args->PeekNext();
|
||||
file_dialog::SaveDialogCallback callback;
|
||||
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(node_isolate,
|
||||
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(args->isolate(),
|
||||
peek,
|
||||
&callback)) {
|
||||
file_dialog::ShowSaveDialog(window, title, default_path, callback);
|
||||
file_dialog::ShowSaveDialog(window, title, default_path, filters, callback);
|
||||
} else {
|
||||
base::FilePath path;
|
||||
if (file_dialog::ShowSaveDialog(window, title, default_path, &path))
|
||||
if (file_dialog::ShowSaveDialog(window, title, default_path, filters,
|
||||
&path))
|
||||
args->Return(path);
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize(v8::Handle<v8::Object> exports) {
|
||||
mate::Dictionary dict(v8::Isolate::GetCurrent(), exports);
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("showMessageBox", &ShowMessageBox);
|
||||
dict.SetMethod("showErrorBox", &atom::ShowErrorBox);
|
||||
dict.SetMethod("showOpenDialog", &ShowOpenDialog);
|
||||
dict.SetMethod("showSaveDialog", &ShowSaveDialog);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE(atom_browser_dialog, Initialize)
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_dialog, Initialize)
|
||||
|
||||
98
atom/browser/api/atom_api_global_shortcut.cc
Normal file
98
atom/browser/api/atom_api_global_shortcut.cc
Normal file
@@ -0,0 +1,98 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_global_shortcut.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/common/native_mate_converters/accelerator_converter.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "native_mate/callback.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using extensions::GlobalShortcutListener;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
GlobalShortcut::GlobalShortcut() {
|
||||
}
|
||||
|
||||
GlobalShortcut::~GlobalShortcut() {
|
||||
UnregisterAll();
|
||||
}
|
||||
|
||||
void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
|
||||
if (accelerator_callback_map_.find(accelerator) ==
|
||||
accelerator_callback_map_.end()) {
|
||||
// This should never occur, because if it does, GlobalGlobalShortcutListener
|
||||
// notifes us with wrong accelerator.
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
accelerator_callback_map_[accelerator].Run();
|
||||
}
|
||||
|
||||
bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
|
||||
const base::Closure& callback) {
|
||||
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(
|
||||
accelerator, this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
accelerator_callback_map_[accelerator] = callback;
|
||||
return true;
|
||||
}
|
||||
|
||||
void GlobalShortcut::Unregister(const ui::Accelerator& accelerator) {
|
||||
if (!ContainsKey(accelerator_callback_map_, accelerator))
|
||||
return;
|
||||
|
||||
accelerator_callback_map_.erase(accelerator);
|
||||
GlobalShortcutListener::GetInstance()->UnregisterAccelerator(
|
||||
accelerator, this);
|
||||
}
|
||||
|
||||
bool GlobalShortcut::IsRegistered(const ui::Accelerator& accelerator) {
|
||||
return ContainsKey(accelerator_callback_map_, accelerator);
|
||||
}
|
||||
|
||||
void GlobalShortcut::UnregisterAll() {
|
||||
accelerator_callback_map_.clear();
|
||||
GlobalShortcutListener::GetInstance()->UnregisterAccelerators(this);
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder GlobalShortcut::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("register", &GlobalShortcut::Register)
|
||||
.SetMethod("isRegistered", &GlobalShortcut::IsRegistered)
|
||||
.SetMethod("unregister", &GlobalShortcut::Unregister)
|
||||
.SetMethod("unregisterAll", &GlobalShortcut::UnregisterAll);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
|
||||
return CreateHandle(isolate, new GlobalShortcut);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("globalShortcut", atom::api::GlobalShortcut::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_global_shortcut, Initialize)
|
||||
55
atom/browser/api/atom_api_global_shortcut.h
Normal file
55
atom/browser/api/atom_api_global_shortcut.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#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"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
|
||||
public mate::Wrappable {
|
||||
public:
|
||||
static mate::Handle<GlobalShortcut> Create(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
GlobalShortcut();
|
||||
virtual ~GlobalShortcut();
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
typedef std::map<ui::Accelerator, base::Closure> AcceleratorCallbackMap;
|
||||
|
||||
bool Register(const ui::Accelerator& accelerator,
|
||||
const base::Closure& callback);
|
||||
bool IsRegistered(const ui::Accelerator& accelerator);
|
||||
void Unregister(const ui::Accelerator& accelerator);
|
||||
void UnregisterAll();
|
||||
|
||||
// GlobalShortcutListener::Observer implementation.
|
||||
void OnKeyPressed(const ui::Accelerator& accelerator) override;
|
||||
|
||||
AcceleratorCallbackMap accelerator_callback_map_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(GlobalShortcut);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
|
||||
@@ -1,12 +1,14 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_window.h"
|
||||
#include "atom/browser/ui/accelerator_util.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/common/native_mate_converters/accelerator_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "native_mate/callback.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
@@ -17,122 +19,55 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// Call method of delegate object.
|
||||
v8::Handle<v8::Value> CallDelegate(v8::Handle<v8::Value> default_value,
|
||||
v8::Handle<v8::Object> menu,
|
||||
const char* method,
|
||||
int command_id) {
|
||||
v8::Locker locker(node_isolate);
|
||||
v8::HandleScope handle_scope(node_isolate);
|
||||
|
||||
v8::Handle<v8::Value> delegate = menu->Get(v8::String::New("delegate"));
|
||||
if (!delegate->IsObject())
|
||||
return default_value;
|
||||
|
||||
v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(
|
||||
delegate->ToObject()->Get(v8::String::New(method)));
|
||||
if (!function->IsFunction())
|
||||
return default_value;
|
||||
|
||||
v8::Handle<v8::Value> argv = v8::Integer::New(command_id);
|
||||
|
||||
return handle_scope.Close(
|
||||
function->Call(v8::Context::GetCurrent()->Global(), 1, &argv));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Menu::Menu() : model_(new ui::SimpleMenuModel(this)) {
|
||||
Menu::Menu()
|
||||
: model_(new ui::SimpleMenuModel(this)),
|
||||
parent_(NULL) {
|
||||
}
|
||||
|
||||
Menu::~Menu() {
|
||||
}
|
||||
|
||||
void Menu::AfterInit(v8::Isolate* isolate) {
|
||||
mate::Dictionary wrappable(isolate, GetWrapper(isolate));
|
||||
mate::Dictionary delegate;
|
||||
if (!wrappable.Get("delegate", &delegate))
|
||||
return;
|
||||
|
||||
delegate.Get("isCommandIdChecked", &is_checked_);
|
||||
delegate.Get("isCommandIdEnabled", &is_enabled_);
|
||||
delegate.Get("isCommandIdVisible", &is_visible_);
|
||||
delegate.Get("getAcceleratorForCommandId", &get_accelerator_);
|
||||
delegate.Get("executeCommand", &execute_command_);
|
||||
delegate.Get("menuWillShow", &menu_will_show_);
|
||||
}
|
||||
|
||||
bool Menu::IsCommandIdChecked(int command_id) const {
|
||||
v8::Locker locker(node_isolate);
|
||||
v8::HandleScope handle_scope(node_isolate);
|
||||
return CallDelegate(v8::False(),
|
||||
const_cast<Menu*>(this)->GetWrapper(node_isolate),
|
||||
"isCommandIdChecked",
|
||||
command_id)->BooleanValue();
|
||||
return is_checked_.Run(command_id);
|
||||
}
|
||||
|
||||
bool Menu::IsCommandIdEnabled(int command_id) const {
|
||||
v8::Locker locker(node_isolate);
|
||||
v8::HandleScope handle_scope(node_isolate);
|
||||
return CallDelegate(v8::True(),
|
||||
const_cast<Menu*>(this)->GetWrapper(node_isolate),
|
||||
"isCommandIdEnabled",
|
||||
command_id)->BooleanValue();
|
||||
return is_enabled_.Run(command_id);
|
||||
}
|
||||
|
||||
bool Menu::IsCommandIdVisible(int command_id) const {
|
||||
v8::Locker locker(node_isolate);
|
||||
v8::HandleScope handle_scope(node_isolate);
|
||||
return CallDelegate(v8::True(),
|
||||
const_cast<Menu*>(this)->GetWrapper(node_isolate),
|
||||
"isCommandIdVisible",
|
||||
command_id)->BooleanValue();
|
||||
return is_visible_.Run(command_id);
|
||||
}
|
||||
|
||||
bool Menu::GetAcceleratorForCommandId(int command_id,
|
||||
ui::Accelerator* accelerator) {
|
||||
v8::Locker locker(node_isolate);
|
||||
v8::HandleScope handle_scope(node_isolate);
|
||||
v8::Handle<v8::Value> shortcut = CallDelegate(v8::Undefined(),
|
||||
GetWrapper(node_isolate),
|
||||
"getAcceleratorForCommandId",
|
||||
command_id);
|
||||
if (shortcut->IsString()) {
|
||||
std::string shortcut_str = mate::V8ToString(shortcut);
|
||||
return accelerator_util::StringToAccelerator(shortcut_str, accelerator);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Menu::IsItemForCommandIdDynamic(int command_id) const {
|
||||
v8::Locker locker(node_isolate);
|
||||
v8::HandleScope handle_scope(node_isolate);
|
||||
return CallDelegate(v8::False(),
|
||||
const_cast<Menu*>(this)->GetWrapper(node_isolate),
|
||||
"isItemForCommandIdDynamic",
|
||||
command_id)->BooleanValue();
|
||||
}
|
||||
|
||||
string16 Menu::GetLabelForCommandId(int command_id) const {
|
||||
v8::Locker locker(node_isolate);
|
||||
v8::HandleScope handle_scope(node_isolate);
|
||||
v8::Handle<v8::Value> result = CallDelegate(
|
||||
v8::False(),
|
||||
const_cast<Menu*>(this)->GetWrapper(node_isolate),
|
||||
"getLabelForCommandId",
|
||||
command_id);
|
||||
string16 label;
|
||||
mate::ConvertFromV8(node_isolate, result, &label);
|
||||
return label;
|
||||
}
|
||||
|
||||
string16 Menu::GetSublabelForCommandId(int command_id) const {
|
||||
v8::Locker locker(node_isolate);
|
||||
v8::HandleScope handle_scope(node_isolate);
|
||||
v8::Handle<v8::Value> result = CallDelegate(
|
||||
v8::False(),
|
||||
const_cast<Menu*>(this)->GetWrapper(node_isolate),
|
||||
"getSubLabelForCommandId",
|
||||
command_id);
|
||||
string16 label;
|
||||
mate::ConvertFromV8(node_isolate, result, &label);
|
||||
return label;
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Value> val = get_accelerator_.Run(command_id);
|
||||
return mate::ConvertFromV8(isolate, val, accelerator);
|
||||
}
|
||||
|
||||
void Menu::ExecuteCommand(int command_id, int event_flags) {
|
||||
v8::Locker locker(node_isolate);
|
||||
v8::HandleScope handle_scope(node_isolate);
|
||||
CallDelegate(v8::False(), GetWrapper(node_isolate), "executeCommand",
|
||||
command_id);
|
||||
execute_command_.Run(command_id);
|
||||
}
|
||||
|
||||
void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
|
||||
menu_will_show_.Run();
|
||||
}
|
||||
|
||||
void Menu::InsertItemAt(
|
||||
@@ -161,9 +96,14 @@ void Menu::InsertSubMenuAt(int index,
|
||||
int command_id,
|
||||
const base::string16& label,
|
||||
Menu* menu) {
|
||||
menu->parent_ = this;
|
||||
model_->InsertSubMenuAt(index, command_id, label, menu->model_.get());
|
||||
}
|
||||
|
||||
void Menu::SetIcon(int index, const gfx::Image& image) {
|
||||
model_->SetIcon(index, image);
|
||||
}
|
||||
|
||||
void Menu::SetSublabel(int index, const base::string16& sublabel) {
|
||||
model_->SetSublabel(index, sublabel);
|
||||
}
|
||||
@@ -206,13 +146,14 @@ bool Menu::IsVisibleAt(int index) const {
|
||||
|
||||
// static
|
||||
void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Handle<v8::ObjectTemplate> prototype) {
|
||||
v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("insertItem", &Menu::InsertItemAt)
|
||||
.SetMethod("insertCheckItem", &Menu::InsertCheckItemAt)
|
||||
.SetMethod("insertRadioItem", &Menu::InsertRadioItemAt)
|
||||
.SetMethod("insertSeparator", &Menu::InsertSeparatorAt)
|
||||
.SetMethod("insertSubMenu", &Menu::InsertSubMenuAt)
|
||||
.SetMethod("setIcon", &Menu::SetIcon)
|
||||
.SetMethod("setSublabel", &Menu::SetSublabel)
|
||||
.SetMethod("clear", &Menu::Clear)
|
||||
.SetMethod("getIndexOfCommandId", &Menu::GetIndexOfCommandId)
|
||||
@@ -223,10 +164,8 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("isItemCheckedAt", &Menu::IsItemCheckedAt)
|
||||
.SetMethod("isEnabledAt", &Menu::IsEnabledAt)
|
||||
.SetMethod("isVisibleAt", &Menu::IsVisibleAt)
|
||||
#if defined(OS_WIN) || defined(TOOLKIT_GTK)
|
||||
.SetMethod("attachToWindow", &Menu::AttachToWindow)
|
||||
#endif
|
||||
.SetMethod("popup", &Menu::Popup);
|
||||
.SetMethod("_popup", &Menu::Popup)
|
||||
.SetMethod("_popupAt", &Menu::PopupAt);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
@@ -236,12 +175,14 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Handle<v8::Object> exports) {
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
using atom::api::Menu;
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::Local<v8::Function> constructor = mate::CreateConstructor<Menu>(
|
||||
node_isolate, "Menu", base::Bind(&Menu::Create));
|
||||
mate::Dictionary dict(v8::Isolate::GetCurrent(), exports);
|
||||
dict.Set("Menu", static_cast<v8::Handle<v8::Value>>(constructor));
|
||||
isolate, "Menu", base::Bind(&Menu::Create));
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("Menu", static_cast<v8::Local<v8::Value>>(constructor));
|
||||
#if defined(OS_MACOSX)
|
||||
dict.SetMethod("setApplicationMenu", &Menu::SetApplicationMenu);
|
||||
dict.SetMethod("sendActionToFirstResponder",
|
||||
@@ -251,4 +192,4 @@ void Initialize(v8::Handle<v8::Object> exports) {
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE(atom_browser_menu, Initialize)
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_menu, Initialize)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/atom_api_window.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "ui/base/models/simple_menu_model.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
@@ -16,15 +17,13 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class MenuMac;
|
||||
|
||||
class Menu : public mate::Wrappable,
|
||||
public ui::SimpleMenuModel::Delegate {
|
||||
public:
|
||||
static mate::Wrappable* Create();
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Handle<v8::ObjectTemplate> prototype);
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// Set the global menubar.
|
||||
@@ -34,25 +33,29 @@ class Menu : public mate::Wrappable,
|
||||
static void SendActionToFirstResponder(const std::string& action);
|
||||
#endif
|
||||
|
||||
ui::SimpleMenuModel* model() const { return model_.get(); }
|
||||
|
||||
protected:
|
||||
Menu();
|
||||
virtual ~Menu();
|
||||
|
||||
// mate::Wrappable:
|
||||
void AfterInit(v8::Isolate* isolate) override;
|
||||
|
||||
// ui::SimpleMenuModel::Delegate implementations:
|
||||
virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
|
||||
virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
|
||||
virtual bool IsCommandIdVisible(int command_id) const OVERRIDE;
|
||||
virtual bool GetAcceleratorForCommandId(
|
||||
int command_id,
|
||||
ui::Accelerator* accelerator) OVERRIDE;
|
||||
virtual bool IsItemForCommandIdDynamic(int command_id) const OVERRIDE;
|
||||
virtual string16 GetLabelForCommandId(int command_id) const OVERRIDE;
|
||||
virtual string16 GetSublabelForCommandId(int command_id) const OVERRIDE;
|
||||
virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
|
||||
bool IsCommandIdChecked(int command_id) const override;
|
||||
bool IsCommandIdEnabled(int command_id) const override;
|
||||
bool IsCommandIdVisible(int command_id) const override;
|
||||
bool GetAcceleratorForCommandId(int command_id,
|
||||
ui::Accelerator* accelerator) override;
|
||||
void ExecuteCommand(int command_id, int event_flags) override;
|
||||
void MenuWillShow(ui::SimpleMenuModel* source) override;
|
||||
|
||||
virtual void Popup(Window* window) = 0;
|
||||
virtual void PopupAt(Window* window, int x, int y) = 0;
|
||||
|
||||
scoped_ptr<ui::SimpleMenuModel> model_;
|
||||
Menu* parent_;
|
||||
|
||||
private:
|
||||
void InsertItemAt(int index, int command_id, const base::string16& label);
|
||||
@@ -68,6 +71,7 @@ class Menu : public mate::Wrappable,
|
||||
int command_id,
|
||||
const base::string16& label,
|
||||
Menu* menu);
|
||||
void SetIcon(int index, const gfx::Image& image);
|
||||
void SetSublabel(int index, const base::string16& sublabel);
|
||||
void Clear();
|
||||
int GetIndexOfCommandId(int command_id);
|
||||
@@ -79,9 +83,13 @@ class Menu : public mate::Wrappable,
|
||||
bool IsEnabledAt(int index) const;
|
||||
bool IsVisibleAt(int index) const;
|
||||
|
||||
#if defined(OS_WIN) || defined(TOOLKIT_GTK)
|
||||
void AttachToWindow(Window* window);
|
||||
#endif
|
||||
// Stored delegate methods.
|
||||
base::Callback<bool(int)> is_checked_;
|
||||
base::Callback<bool(int)> is_enabled_;
|
||||
base::Callback<bool(int)> is_visible_;
|
||||
base::Callback<v8::Local<v8::Value>(int)> get_accelerator_;
|
||||
base::Callback<void(int)> execute_command_;
|
||||
base::Callback<void()> menu_will_show_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Menu);
|
||||
};
|
||||
@@ -90,4 +98,27 @@ class Menu : public mate::Wrappable,
|
||||
|
||||
} // namespace atom
|
||||
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<ui::SimpleMenuModel*> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
ui::SimpleMenuModel** out) {
|
||||
// null would be tranfered to NULL.
|
||||
if (val->IsNull()) {
|
||||
*out = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
atom::api::Menu* menu;
|
||||
if (!Converter<atom::api::Menu*>::FromV8(isolate, val, &menu))
|
||||
return false;
|
||||
*out = menu->model();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_H_
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_menu_gtk.h"
|
||||
|
||||
#include "atom/browser/native_window_gtk.h"
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
#include "ui/gfx/point.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
MenuGtk::MenuGtk() {
|
||||
}
|
||||
|
||||
void MenuGtk::Popup(Window* window) {
|
||||
uint32_t triggering_event_time;
|
||||
gfx::Point point;
|
||||
|
||||
NativeWindow* native_window = window->window();
|
||||
GdkEventButton* event = native_window->GetWebContents()->
|
||||
GetRenderWidgetHostView()->GetLastMouseDown();
|
||||
if (event) {
|
||||
triggering_event_time = event->time;
|
||||
point = gfx::Point(event->x_root, event->y_root);
|
||||
} else {
|
||||
triggering_event_time = GDK_CURRENT_TIME;
|
||||
point = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
|
||||
}
|
||||
|
||||
menu_gtk_.reset(new ::MenuGtk(this, model_.get()));
|
||||
menu_gtk_->PopupAsContext(point, triggering_event_time);
|
||||
}
|
||||
|
||||
void Menu::AttachToWindow(Window* window) {
|
||||
static_cast<NativeWindowGtk*>(window->window())->SetMenu(model_.get());
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Wrappable* Menu::Create() {
|
||||
return new MenuGtk();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_GTK_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_GTK_H_
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "chrome/browser/ui/gtk/menu_gtk.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class MenuGtk : public Menu,
|
||||
public ::MenuGtk::Delegate {
|
||||
public:
|
||||
MenuGtk();
|
||||
|
||||
protected:
|
||||
virtual void Popup(Window* window) OVERRIDE;
|
||||
|
||||
private:
|
||||
scoped_ptr<::MenuGtk> menu_gtk_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MenuGtk);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_GTK_H_
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -19,7 +19,8 @@ class MenuMac : public Menu {
|
||||
protected:
|
||||
MenuMac();
|
||||
|
||||
virtual void Popup(Window* window) OVERRIDE;
|
||||
void Popup(Window* window) override;
|
||||
void PopupAt(Window* window, int x, int y) override;
|
||||
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller_;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/browser/web_contents_view.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
@@ -20,13 +19,17 @@ MenuMac::MenuMac() {
|
||||
}
|
||||
|
||||
void MenuMac::Popup(Window* window) {
|
||||
NativeWindow* native_window = window->window();
|
||||
if (!native_window)
|
||||
return;
|
||||
content::WebContents* web_contents = native_window->GetWebContents();
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
NSWindow* nswindow = native_window->GetNativeWindow();
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller(
|
||||
[[AtomMenuController alloc] initWithModel:model_.get()]);
|
||||
|
||||
NativeWindow* native_window = window->window();
|
||||
NSWindow* nswindow = native_window->GetNativeWindow();
|
||||
content::WebContents* web_contents = native_window->GetWebContents();
|
||||
|
||||
// Fake out a context menu event.
|
||||
NSEvent* currentEvent = [NSApp currentEvent];
|
||||
NSPoint position = [nswindow mouseLocationOutsideOfEventStream];
|
||||
@@ -44,7 +47,26 @@ void MenuMac::Popup(Window* window) {
|
||||
// Show the menu.
|
||||
[NSMenu popUpContextMenu:[menu_controller menu]
|
||||
withEvent:clickEvent
|
||||
forView:web_contents->GetView()->GetContentNativeView()];
|
||||
forView:web_contents->GetContentNativeView()];
|
||||
}
|
||||
|
||||
void MenuMac::PopupAt(Window* window, int x, int y) {
|
||||
NativeWindow* native_window = window->window();
|
||||
if (!native_window)
|
||||
return;
|
||||
content::WebContents* web_contents = native_window->GetWebContents();
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller(
|
||||
[[AtomMenuController alloc] initWithModel:model_.get()]);
|
||||
NSMenu* menu = [menu_controller menu];
|
||||
NSView* view = web_contents->GetContentNativeView();
|
||||
|
||||
// Show the menu.
|
||||
[menu popUpMenuPositioningItem:[menu itemAtIndex:0]
|
||||
atLocation:NSMakePoint(x, [view frame].size.height - y)
|
||||
inView:view];
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
57
atom/browser/api/atom_api_menu_views.cc
Normal file
57
atom/browser/api/atom_api_menu_views.cc
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_menu_views.h"
|
||||
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
#include "ui/views/controls/menu/menu_runner.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
MenuViews::MenuViews() {
|
||||
}
|
||||
|
||||
void MenuViews::Popup(Window* window) {
|
||||
PopupAtPoint(window, gfx::Screen::GetNativeScreen()->GetCursorScreenPoint());
|
||||
}
|
||||
|
||||
void MenuViews::PopupAt(Window* window, int x, int y) {
|
||||
NativeWindow* native_window = static_cast<NativeWindow*>(window->window());
|
||||
if (!native_window)
|
||||
return;
|
||||
content::WebContents* web_contents = native_window->GetWebContents();
|
||||
if (!web_contents)
|
||||
return;
|
||||
content::RenderWidgetHostView* view = web_contents->GetRenderWidgetHostView();
|
||||
if (!view)
|
||||
return;
|
||||
|
||||
gfx::Point origin = view->GetViewBounds().origin();
|
||||
PopupAtPoint(window, gfx::Point(origin.x() + x, origin.y() + y));
|
||||
}
|
||||
|
||||
void MenuViews::PopupAtPoint(Window* window, const gfx::Point& point) {
|
||||
views::MenuRunner menu_runner(
|
||||
model(),
|
||||
views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS);
|
||||
ignore_result(menu_runner.RunMenuAt(
|
||||
static_cast<NativeWindowViews*>(window->window())->widget(),
|
||||
NULL,
|
||||
gfx::Rect(point, gfx::Size()),
|
||||
views::MENU_ANCHOR_TOPLEFT,
|
||||
ui::MENU_SOURCE_MOUSE));
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Wrappable* Menu::Create() {
|
||||
return new MenuViews();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
33
atom/browser/api/atom_api_menu_views.h
Normal file
33
atom/browser/api/atom_api_menu_views.h
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class MenuViews : public Menu {
|
||||
public:
|
||||
MenuViews();
|
||||
|
||||
protected:
|
||||
void Popup(Window* window) override;
|
||||
void PopupAt(Window* window, int x, int y) override;
|
||||
|
||||
private:
|
||||
void PopupAtPoint(Window* window, const gfx::Point& point);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MenuViews);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
|
||||
@@ -1,38 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_menu_win.h"
|
||||
|
||||
#include "atom/browser/native_window_win.h"
|
||||
#include "atom/browser/ui/win/menu_2.h"
|
||||
#include "ui/gfx/point.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
MenuWin::MenuWin() {
|
||||
}
|
||||
|
||||
void MenuWin::Popup(Window* window) {
|
||||
gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
|
||||
menu_.reset(new atom::Menu2(model_.get()));
|
||||
menu_->RunContextMenuAt(cursor);
|
||||
}
|
||||
|
||||
void Menu::AttachToWindow(Window* window) {
|
||||
static_cast<NativeWindowWin*>(window->window())->SetMenu(model_.get());
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Wrappable* Menu::Create() {
|
||||
return new MenuWin();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_WIN_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_WIN_H_
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class Menu2;
|
||||
|
||||
namespace api {
|
||||
|
||||
class MenuWin : public Menu {
|
||||
public:
|
||||
MenuWin();
|
||||
|
||||
protected:
|
||||
virtual void Popup(Window* window) OVERRIDE;
|
||||
|
||||
private:
|
||||
scoped_ptr<atom::Menu2> menu_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MenuWin);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_WIN_H_
|
||||
@@ -1,9 +1,10 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_power_monitor.h"
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "base/power_monitor/power_monitor.h"
|
||||
#include "base/power_monitor/power_monitor_device_source.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
@@ -38,8 +39,15 @@ void PowerMonitor::OnResume() {
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<PowerMonitor> PowerMonitor::Create(v8::Isolate* isolate) {
|
||||
return CreateHandle(isolate, new PowerMonitor);
|
||||
v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
node::ThrowError(
|
||||
isolate,
|
||||
"Cannot initialize \"power-monitor\" module before app is ready");
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
return CreateHandle(isolate, new PowerMonitor).ToV8();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
@@ -49,18 +57,18 @@ mate::Handle<PowerMonitor> PowerMonitor::Create(v8::Isolate* isolate) {
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Handle<v8::Object> exports) {
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
#if defined(OS_MACOSX)
|
||||
base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
|
||||
#endif
|
||||
|
||||
using atom::api::PowerMonitor;
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
mate::Handle<PowerMonitor> power_monitor = PowerMonitor::Create(isolate);
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("powerMonitor", power_monitor);
|
||||
dict.Set("powerMonitor", PowerMonitor::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE(atom_browser_power_monitor, Initialize)
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_power_monitor, Initialize)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -17,16 +17,16 @@ namespace api {
|
||||
class PowerMonitor : public mate::EventEmitter,
|
||||
public base::PowerObserver {
|
||||
public:
|
||||
static mate::Handle<PowerMonitor> Create(v8::Isolate* isolate);
|
||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
PowerMonitor();
|
||||
virtual ~PowerMonitor();
|
||||
|
||||
// base::PowerObserver implementations:
|
||||
virtual void OnPowerStateChange(bool on_battery_power) OVERRIDE;
|
||||
virtual void OnSuspend() OVERRIDE;
|
||||
virtual void OnResume() OVERRIDE;
|
||||
void OnPowerStateChange(bool on_battery_power) override;
|
||||
void OnSuspend() override;
|
||||
void OnResume() override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_protocol.h"
|
||||
|
||||
#include "base/stl_util.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/net/adapter_request_job.h"
|
||||
#include "atom/browser/net/atom_url_request_context_getter.h"
|
||||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/function_converter.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/callback.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
|
||||
@@ -23,7 +21,7 @@ namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<const net::URLRequest*> {
|
||||
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const net::URLRequest* val) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetValue("method", val->method())
|
||||
@@ -44,6 +42,14 @@ namespace {
|
||||
|
||||
typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler;
|
||||
|
||||
scoped_refptr<base::RefCountedBytes> BufferToRefCountedBytes(
|
||||
v8::Local<v8::Value> buf) {
|
||||
scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes);
|
||||
auto start = reinterpret_cast<const unsigned char*>(node::Buffer::Data(buf));
|
||||
data->data().assign(start, start + node::Buffer::Length(buf));
|
||||
return data;
|
||||
}
|
||||
|
||||
class CustomProtocolRequestJob : public AdapterRequestJob {
|
||||
public:
|
||||
CustomProtocolRequestJob(Protocol* registry,
|
||||
@@ -55,16 +61,17 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
|
||||
}
|
||||
|
||||
// AdapterRequestJob:
|
||||
virtual void GetJobTypeInUI() OVERRIDE {
|
||||
void GetJobTypeInUI() override {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
|
||||
v8::Locker locker(node_isolate);
|
||||
v8::HandleScope handle_scope(node_isolate);
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
// Call the JS handler.
|
||||
Protocol::JsProtocolHandler callback =
|
||||
registry_->GetProtocolHandler(request()->url().scheme());
|
||||
v8::Handle<v8::Value> result = callback.Run(request());
|
||||
v8::Local<v8::Value> result = callback.Run(request());
|
||||
|
||||
// Determine the type of the job we are going to create.
|
||||
if (result->IsString()) {
|
||||
@@ -74,8 +81,8 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
|
||||
GetWeakPtr(), "text/plain", "UTF-8", data));
|
||||
return;
|
||||
} else if (result->IsObject()) {
|
||||
v8::Handle<v8::Object> obj = result->ToObject();
|
||||
mate::Dictionary dict(node_isolate, obj);
|
||||
v8::Local<v8::Object> obj = result->ToObject();
|
||||
mate::Dictionary dict(isolate, obj);
|
||||
std::string name = mate::V8ToString(obj->GetConstructorName());
|
||||
if (name == "RequestStringJob") {
|
||||
std::string mime_type, charset, data;
|
||||
@@ -87,6 +94,18 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
|
||||
base::Bind(&AdapterRequestJob::CreateStringJobAndStart,
|
||||
GetWeakPtr(), mime_type, charset, data));
|
||||
return;
|
||||
} else if (name == "RequestBufferJob") {
|
||||
std::string mime_type, encoding;
|
||||
v8::Local<v8::Value> buffer;
|
||||
dict.Get("mimeType", &mime_type);
|
||||
dict.Get("encoding", &encoding);
|
||||
dict.Get("data", &buffer);
|
||||
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&AdapterRequestJob::CreateBufferJobAndStart,
|
||||
GetWeakPtr(), mime_type, encoding,
|
||||
BufferToRefCountedBytes(buffer)));
|
||||
return;
|
||||
} else if (name == "RequestFileJob") {
|
||||
base::FilePath path;
|
||||
dict.Get("path", &path);
|
||||
@@ -95,6 +114,15 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
|
||||
base::Bind(&AdapterRequestJob::CreateFileJobAndStart,
|
||||
GetWeakPtr(), path));
|
||||
return;
|
||||
} else if (name == "RequestErrorJob") {
|
||||
// Default value net::ERR_NOT_IMPLEMENTED
|
||||
int error = -11;
|
||||
dict.Get("error", &error);
|
||||
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&AdapterRequestJob::CreateErrorJobAndStart,
|
||||
GetWeakPtr(), error));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,9 +157,9 @@ class CustomProtocolHandler : public ProtocolHandler {
|
||||
: registry_(registry), protocol_handler_(protocol_handler) {
|
||||
}
|
||||
|
||||
virtual net::URLRequestJob* MaybeCreateJob(
|
||||
net::URLRequestJob* MaybeCreateJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const OVERRIDE {
|
||||
net::NetworkDelegate* network_delegate) const override {
|
||||
return new CustomProtocolRequestJob(registry_, protocol_handler_.get(),
|
||||
request, network_delegate);
|
||||
}
|
||||
@@ -151,8 +179,9 @@ class CustomProtocolHandler : public ProtocolHandler {
|
||||
|
||||
} // namespace
|
||||
|
||||
Protocol::Protocol() : job_factory_(
|
||||
AtomBrowserContext::Get()->url_request_context_getter()->job_factory()) {
|
||||
Protocol::Protocol()
|
||||
: job_factory_(AtomBrowserContext::Get()->job_factory()) {
|
||||
CHECK(job_factory_);
|
||||
}
|
||||
|
||||
Protocol::JsProtocolHandler Protocol::GetProtocolHandler(
|
||||
@@ -163,28 +192,19 @@ Protocol::JsProtocolHandler Protocol::GetProtocolHandler(
|
||||
mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("registerProtocol",
|
||||
base::Bind(&Protocol::RegisterProtocol,
|
||||
base::Unretained(this)))
|
||||
.SetMethod("unregisterProtocol",
|
||||
base::Bind(&Protocol::UnregisterProtocol,
|
||||
base::Unretained(this)))
|
||||
.SetMethod("isHandledProtocol",
|
||||
base::Bind(&Protocol::IsHandledProtocol,
|
||||
base::Unretained(this)))
|
||||
.SetMethod("interceptProtocol",
|
||||
base::Bind(&Protocol::InterceptProtocol,
|
||||
base::Unretained(this)))
|
||||
.SetMethod("uninterceptProtocol",
|
||||
base::Bind(&Protocol::UninterceptProtocol,
|
||||
base::Unretained(this)));
|
||||
.SetMethod("registerProtocol", &Protocol::RegisterProtocol)
|
||||
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
|
||||
.SetMethod("isHandledProtocol", &Protocol::IsHandledProtocol)
|
||||
.SetMethod("interceptProtocol", &Protocol::InterceptProtocol)
|
||||
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
|
||||
}
|
||||
|
||||
void Protocol::RegisterProtocol(const std::string& scheme,
|
||||
void Protocol::RegisterProtocol(v8::Isolate* isolate,
|
||||
const std::string& scheme,
|
||||
const JsProtocolHandler& callback) {
|
||||
if (ContainsKey(protocol_handlers_, scheme) ||
|
||||
job_factory_->IsHandledProtocol(scheme))
|
||||
return node::ThrowError("The scheme is already registered");
|
||||
return node::ThrowError(isolate, "The scheme is already registered");
|
||||
|
||||
protocol_handlers_[scheme] = callback;
|
||||
BrowserThread::PostTask(BrowserThread::IO,
|
||||
@@ -193,10 +213,11 @@ void Protocol::RegisterProtocol(const std::string& scheme,
|
||||
base::Unretained(this), scheme));
|
||||
}
|
||||
|
||||
void Protocol::UnregisterProtocol(const std::string& scheme) {
|
||||
void Protocol::UnregisterProtocol(v8::Isolate* isolate,
|
||||
const std::string& scheme) {
|
||||
ProtocolHandlersMap::iterator it(protocol_handlers_.find(scheme));
|
||||
if (it == protocol_handlers_.end())
|
||||
return node::ThrowError("The scheme has not been registered");
|
||||
return node::ThrowError(isolate, "The scheme has not been registered");
|
||||
|
||||
protocol_handlers_.erase(it);
|
||||
BrowserThread::PostTask(BrowserThread::IO,
|
||||
@@ -209,13 +230,14 @@ bool Protocol::IsHandledProtocol(const std::string& scheme) {
|
||||
return job_factory_->IsHandledProtocol(scheme);
|
||||
}
|
||||
|
||||
void Protocol::InterceptProtocol(const std::string& scheme,
|
||||
void Protocol::InterceptProtocol(v8::Isolate* isolate,
|
||||
const std::string& scheme,
|
||||
const JsProtocolHandler& callback) {
|
||||
if (!job_factory_->HasProtocolHandler(scheme))
|
||||
return node::ThrowError("Scheme does not exist.");
|
||||
return node::ThrowError(isolate, "Scheme does not exist.");
|
||||
|
||||
if (ContainsKey(protocol_handlers_, scheme))
|
||||
return node::ThrowError("Cannot intercept custom procotols");
|
||||
return node::ThrowError(isolate, "Cannot intercept custom procotols");
|
||||
|
||||
protocol_handlers_[scheme] = callback;
|
||||
BrowserThread::PostTask(BrowserThread::IO,
|
||||
@@ -224,10 +246,11 @@ void Protocol::InterceptProtocol(const std::string& scheme,
|
||||
base::Unretained(this), scheme));
|
||||
}
|
||||
|
||||
void Protocol::UninterceptProtocol(const std::string& scheme) {
|
||||
void Protocol::UninterceptProtocol(v8::Isolate* isolate,
|
||||
const std::string& scheme) {
|
||||
ProtocolHandlersMap::iterator it(protocol_handlers_.find(scheme));
|
||||
if (it == protocol_handlers_.end())
|
||||
return node::ThrowError("The scheme has not been registered");
|
||||
return node::ThrowError(isolate, "The scheme has not been registered");
|
||||
|
||||
protocol_handlers_.erase(it);
|
||||
BrowserThread::PostTask(BrowserThread::IO,
|
||||
@@ -305,9 +328,7 @@ void Protocol::UninterceptProtocolInIO(const std::string& scheme) {
|
||||
|
||||
void Protocol::EmitEventInUI(const std::string& event,
|
||||
const std::string& parameter) {
|
||||
base::ListValue args;
|
||||
args.AppendString(parameter);
|
||||
Emit(event, args);
|
||||
Emit(event, parameter);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -321,16 +342,13 @@ mate::Handle<Protocol> Protocol::Create(v8::Isolate* isolate) {
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Handle<v8::Object> exports) {
|
||||
// Make sure the job factory has been created.
|
||||
atom::AtomBrowserContext::Get()->url_request_context_getter()->
|
||||
GetURLRequestContext();
|
||||
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("protocol", atom::api::Protocol::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE(atom_browser_protocol, Initialize)
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_protocol, Initialize)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace api {
|
||||
|
||||
class Protocol : public mate::EventEmitter {
|
||||
public:
|
||||
typedef base::Callback<v8::Handle<v8::Value>(const net::URLRequest*)>
|
||||
typedef base::Callback<v8::Local<v8::Value>(const net::URLRequest*)>
|
||||
JsProtocolHandler;
|
||||
|
||||
static mate::Handle<Protocol> Create(v8::Isolate* isolate);
|
||||
@@ -43,9 +43,10 @@ class Protocol : public mate::EventEmitter {
|
||||
|
||||
// Register/unregister an networking |scheme| which would be handled by
|
||||
// |callback|.
|
||||
void RegisterProtocol(const std::string& scheme,
|
||||
void RegisterProtocol(v8::Isolate* isolate,
|
||||
const std::string& scheme,
|
||||
const JsProtocolHandler& callback);
|
||||
void UnregisterProtocol(const std::string& scheme);
|
||||
void UnregisterProtocol(v8::Isolate* isolate, const std::string& scheme);
|
||||
|
||||
// Returns whether a scheme has been registered.
|
||||
// FIXME Should accept a callback and be asynchronous so we do not have to use
|
||||
@@ -53,9 +54,10 @@ class Protocol : public mate::EventEmitter {
|
||||
bool IsHandledProtocol(const std::string& scheme);
|
||||
|
||||
// Intercept/unintercept an existing protocol handler.
|
||||
void InterceptProtocol(const std::string& scheme,
|
||||
void InterceptProtocol(v8::Isolate* isolate,
|
||||
const std::string& scheme,
|
||||
const JsProtocolHandler& callback);
|
||||
void UninterceptProtocol(const std::string& scheme);
|
||||
void UninterceptProtocol(v8::Isolate* isolate, const std::string& scheme);
|
||||
|
||||
// The networking related operations have to be done in IO thread.
|
||||
void RegisterProtocolInIO(const std::string& scheme);
|
||||
|
||||
144
atom/browser/api/atom_api_screen.cc
Normal file
144
atom/browser/api/atom_api_screen.cc
Normal file
@@ -0,0 +1,144 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_screen.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "base/bind.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// Find an item in container according to its ID.
|
||||
template<class T>
|
||||
typename T::iterator FindById(T* container, int id) {
|
||||
auto predicate = [id] (const typename T::value_type& item) -> bool {
|
||||
return item.id() == id;
|
||||
};
|
||||
return std::find_if(container->begin(), container->end(), predicate);
|
||||
}
|
||||
|
||||
// Convert the changed_metrics bitmask to string array.
|
||||
std::vector<std::string> MetricsToArray(uint32_t metrics) {
|
||||
std::vector<std::string> array;
|
||||
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS)
|
||||
array.push_back("bounds");
|
||||
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA)
|
||||
array.push_back("workArea");
|
||||
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR)
|
||||
array.push_back("scaleFactor");
|
||||
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_ROTATION)
|
||||
array.push_back("rotaion");
|
||||
return array;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Screen::Screen(gfx::Screen* screen) : screen_(screen) {
|
||||
displays_ = screen_->GetAllDisplays();
|
||||
screen_->AddObserver(this);
|
||||
}
|
||||
|
||||
Screen::~Screen() {
|
||||
screen_->RemoveObserver(this);
|
||||
}
|
||||
|
||||
gfx::Point Screen::GetCursorScreenPoint() {
|
||||
return screen_->GetCursorScreenPoint();
|
||||
}
|
||||
|
||||
gfx::Display Screen::GetPrimaryDisplay() {
|
||||
return screen_->GetPrimaryDisplay();
|
||||
}
|
||||
|
||||
std::vector<gfx::Display> Screen::GetAllDisplays() {
|
||||
return displays_;
|
||||
}
|
||||
|
||||
gfx::Display Screen::GetDisplayNearestPoint(const gfx::Point& point) {
|
||||
return screen_->GetDisplayNearestPoint(point);
|
||||
}
|
||||
|
||||
gfx::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) {
|
||||
return screen_->GetDisplayMatching(match_rect);
|
||||
}
|
||||
|
||||
void Screen::OnDisplayAdded(const gfx::Display& new_display) {
|
||||
displays_.push_back(new_display);
|
||||
Emit("display-added", new_display);
|
||||
}
|
||||
|
||||
void Screen::OnDisplayRemoved(const gfx::Display& old_display) {
|
||||
auto iter = FindById(&displays_, old_display.id());
|
||||
if (iter == displays_.end())
|
||||
return;
|
||||
|
||||
displays_.erase(iter);
|
||||
Emit("display-removed", old_display);
|
||||
}
|
||||
|
||||
void Screen::OnDisplayMetricsChanged(const gfx::Display& display,
|
||||
uint32_t changed_metrics) {
|
||||
auto iter = FindById(&displays_, display.id());
|
||||
if (iter == displays_.end())
|
||||
return;
|
||||
|
||||
*iter = display;
|
||||
Emit("display-metrics-changed", display, MetricsToArray(changed_metrics));
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder Screen::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint)
|
||||
.SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
|
||||
.SetMethod("getAllDisplays", &Screen::GetAllDisplays)
|
||||
.SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint)
|
||||
.SetMethod("getDisplayMatching", &Screen::GetDisplayMatching);
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
node::ThrowError(isolate,
|
||||
"Cannot initialize \"screen\" module before app is ready");
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
gfx::Screen* screen = gfx::Screen::GetNativeScreen();
|
||||
if (!screen) {
|
||||
node::ThrowError(isolate, "Failed to get screen information");
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
return mate::CreateHandle(isolate, new Screen(screen)).ToV8();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.Set("screen", atom::api::Screen::Create(context->GetIsolate()));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_screen, Initialize)
|
||||
60
atom/browser/api/atom_api_screen.h
Normal file
60
atom/browser/api/atom_api_screen.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_ATOM_API_SCREEN_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_SCREEN_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "ui/gfx/display_observer.h"
|
||||
|
||||
namespace gfx {
|
||||
class Point;
|
||||
class Rect;
|
||||
class Screen;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Screen : public mate::EventEmitter,
|
||||
public gfx::DisplayObserver {
|
||||
public:
|
||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
explicit Screen(gfx::Screen* screen);
|
||||
virtual ~Screen();
|
||||
|
||||
gfx::Point GetCursorScreenPoint();
|
||||
gfx::Display GetPrimaryDisplay();
|
||||
std::vector<gfx::Display> GetAllDisplays();
|
||||
gfx::Display GetDisplayNearestPoint(const gfx::Point& point);
|
||||
gfx::Display GetDisplayMatching(const gfx::Rect& match_rect);
|
||||
|
||||
// gfx::DisplayObserver:
|
||||
void OnDisplayAdded(const gfx::Display& new_display) override;
|
||||
void OnDisplayRemoved(const gfx::Display& old_display) override;
|
||||
void OnDisplayMetricsChanged(const gfx::Display& display,
|
||||
uint32_t changed_metrics) override;
|
||||
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
gfx::Screen* screen_;
|
||||
std::vector<gfx::Display> displays_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Screen);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_SCREEN_H_
|
||||
162
atom/browser/api/atom_api_tray.cc
Normal file
162
atom/browser/api/atom_api_tray.cc
Normal file
@@ -0,0 +1,162 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_tray.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/ui/tray_icon.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
Tray::Tray(const gfx::Image& image)
|
||||
: tray_icon_(TrayIcon::Create()) {
|
||||
tray_icon_->SetImage(image);
|
||||
tray_icon_->AddObserver(this);
|
||||
}
|
||||
|
||||
Tray::~Tray() {
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
node::ThrowError(isolate, "Cannot create Tray before app is ready");
|
||||
return nullptr;
|
||||
}
|
||||
return new Tray(image);
|
||||
}
|
||||
|
||||
void Tray::OnClicked(const gfx::Rect& bounds) {
|
||||
Emit("clicked", bounds);
|
||||
}
|
||||
|
||||
void Tray::OnDoubleClicked() {
|
||||
Emit("double-clicked");
|
||||
}
|
||||
|
||||
void Tray::OnBalloonShow() {
|
||||
Emit("balloon-show");
|
||||
}
|
||||
|
||||
void Tray::OnBalloonClicked() {
|
||||
Emit("balloon-clicked");
|
||||
}
|
||||
|
||||
void Tray::OnBalloonClosed() {
|
||||
Emit("balloon-closed");
|
||||
}
|
||||
|
||||
void Tray::Destroy() {
|
||||
tray_icon_.reset();
|
||||
}
|
||||
|
||||
void Tray::SetImage(mate::Arguments* args, const gfx::Image& image) {
|
||||
if (!CheckTrayLife(args))
|
||||
return;
|
||||
tray_icon_->SetImage(image);
|
||||
}
|
||||
|
||||
void Tray::SetPressedImage(mate::Arguments* args, const gfx::Image& image) {
|
||||
if (!CheckTrayLife(args))
|
||||
return;
|
||||
tray_icon_->SetPressedImage(image);
|
||||
}
|
||||
|
||||
void Tray::SetToolTip(mate::Arguments* args, const std::string& tool_tip) {
|
||||
if (!CheckTrayLife(args))
|
||||
return;
|
||||
tray_icon_->SetToolTip(tool_tip);
|
||||
}
|
||||
|
||||
void Tray::SetTitle(mate::Arguments* args, const std::string& title) {
|
||||
if (!CheckTrayLife(args))
|
||||
return;
|
||||
tray_icon_->SetTitle(title);
|
||||
}
|
||||
|
||||
void Tray::SetHighlightMode(mate::Arguments* args, bool highlight) {
|
||||
if (!CheckTrayLife(args))
|
||||
return;
|
||||
tray_icon_->SetHighlightMode(highlight);
|
||||
}
|
||||
|
||||
void Tray::DisplayBalloon(mate::Arguments* args,
|
||||
const mate::Dictionary& options) {
|
||||
if (!CheckTrayLife(args))
|
||||
return;
|
||||
|
||||
gfx::Image icon;
|
||||
options.Get("icon", &icon);
|
||||
base::string16 title, content;
|
||||
if (!options.Get("title", &title) ||
|
||||
!options.Get("content", &content)) {
|
||||
args->ThrowError("'title' and 'content' must be defined");
|
||||
return;
|
||||
}
|
||||
|
||||
tray_icon_->DisplayBalloon(icon, title, content);
|
||||
}
|
||||
|
||||
void Tray::SetContextMenu(mate::Arguments* args, Menu* menu) {
|
||||
if (!CheckTrayLife(args))
|
||||
return;
|
||||
tray_icon_->SetContextMenu(menu->model());
|
||||
}
|
||||
|
||||
bool Tray::CheckTrayLife(mate::Arguments* args) {
|
||||
if (!tray_icon_) {
|
||||
args->ThrowError("Tray is already destroyed");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void Tray::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("destroy", &Tray::Destroy)
|
||||
.SetMethod("setImage", &Tray::SetImage)
|
||||
.SetMethod("setPressedImage", &Tray::SetPressedImage)
|
||||
.SetMethod("setToolTip", &Tray::SetToolTip)
|
||||
.SetMethod("setTitle", &Tray::SetTitle)
|
||||
.SetMethod("setHighlightMode", &Tray::SetHighlightMode)
|
||||
.SetMethod("displayBalloon", &Tray::DisplayBalloon)
|
||||
.SetMethod("_setContextMenu", &Tray::SetContextMenu);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
using atom::api::Tray;
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::Local<v8::Function> constructor = mate::CreateConstructor<Tray>(
|
||||
isolate, "Tray", base::Bind(&Tray::New));
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("Tray", static_cast<v8::Local<v8::Value>>(constructor));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_tray, Initialize)
|
||||
71
atom/browser/api/atom_api_tray.h
Normal file
71
atom/browser/api/atom_api_tray.h
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_TRAY_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_TRAY_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/ui/tray_icon_observer.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
|
||||
namespace gfx {
|
||||
class Image;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class TrayIcon;
|
||||
|
||||
namespace api {
|
||||
|
||||
class Menu;
|
||||
|
||||
class Tray : public mate::EventEmitter,
|
||||
public TrayIconObserver {
|
||||
public:
|
||||
static mate::Wrappable* New(v8::Isolate* isolate, const gfx::Image& image);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit Tray(const gfx::Image& image);
|
||||
virtual ~Tray();
|
||||
|
||||
// TrayIconObserver:
|
||||
void OnClicked(const gfx::Rect&) override;
|
||||
void OnDoubleClicked() override;
|
||||
void OnBalloonShow() override;
|
||||
void OnBalloonClicked() override;
|
||||
void OnBalloonClosed() override;
|
||||
|
||||
void Destroy();
|
||||
void SetImage(mate::Arguments* args, const gfx::Image& image);
|
||||
void SetPressedImage(mate::Arguments* args, const gfx::Image& image);
|
||||
void SetToolTip(mate::Arguments* args, const std::string& tool_tip);
|
||||
void SetTitle(mate::Arguments* args, const std::string& title);
|
||||
void SetHighlightMode(mate::Arguments* args, bool highlight);
|
||||
void DisplayBalloon(mate::Arguments* args, const mate::Dictionary& options);
|
||||
void SetContextMenu(mate::Arguments* args, Menu* menu);
|
||||
|
||||
private:
|
||||
bool CheckTrayLife(mate::Arguments* args);
|
||||
|
||||
scoped_ptr<TrayIcon> tray_icon_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Tray);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_TRAY_H_
|
||||
@@ -1,54 +1,349 @@
|
||||
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
#include "content/public/browser/favicon_status.h"
|
||||
#include "content/public/browser/guest_host.h"
|
||||
#include "content/public/browser/navigation_details.h"
|
||||
#include "content/public/browser/navigation_entry.h"
|
||||
#include "content/public/browser/plugin_service.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
#include "content/public/browser/resource_request_details.h"
|
||||
#include "content/public/browser/service_worker_context.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/browser/site_instance.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "native_mate/callback.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<atom::api::SetSizeParams> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
atom::api::SetSizeParams* out) {
|
||||
mate::Dictionary params;
|
||||
if (!ConvertFromV8(isolate, val, ¶ms))
|
||||
return false;
|
||||
bool autosize;
|
||||
if (params.Get("enableAutoSize", &autosize))
|
||||
out->enable_auto_size.reset(new bool(true));
|
||||
gfx::Size size;
|
||||
if (params.Get("min", &size))
|
||||
out->min_size.reset(new gfx::Size(size));
|
||||
if (params.Get("max", &size))
|
||||
out->max_size.reset(new gfx::Size(size));
|
||||
if (params.Get("normal", &size))
|
||||
out->normal_size.reset(new gfx::Size(size));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
const int kDefaultWidth = 300;
|
||||
const int kDefaultHeight = 300;
|
||||
|
||||
v8::Persistent<v8::ObjectTemplate> template_;
|
||||
|
||||
// The wrapWebContents funtion which is implemented in JavaScript
|
||||
using WrapWebContentsCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
WrapWebContentsCallback g_wrap_web_contents;
|
||||
|
||||
content::ServiceWorkerContext* GetServiceWorkerContext(
|
||||
const content::WebContents* web_contents) {
|
||||
auto context = web_contents->GetBrowserContext();
|
||||
auto site_instance = web_contents->GetSiteInstance();
|
||||
if (!context || !site_instance)
|
||||
return nullptr;
|
||||
|
||||
auto storage_partition =
|
||||
content::BrowserContext::GetStoragePartition(context, site_instance);
|
||||
if (!storage_partition)
|
||||
return nullptr;
|
||||
|
||||
return storage_partition->GetServiceWorkerContext();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
WebContents::WebContents(brightray::InspectableWebContents* web_contents)
|
||||
: WebContents(web_contents->GetWebContents()) {
|
||||
inspectable_web_contents_ = web_contents;
|
||||
}
|
||||
|
||||
WebContents::WebContents(content::WebContents* web_contents)
|
||||
: content::WebContentsObserver(web_contents),
|
||||
web_contents_(web_contents) {
|
||||
: CommonWebContentsDelegate(false),
|
||||
content::WebContentsObserver(web_contents),
|
||||
guest_opaque_(true),
|
||||
guest_host_(nullptr),
|
||||
auto_size_enabled_(false),
|
||||
is_full_page_plugin_(false),
|
||||
inspectable_web_contents_(nullptr) {
|
||||
}
|
||||
|
||||
WebContents::WebContents(const mate::Dictionary& options)
|
||||
: CommonWebContentsDelegate(true),
|
||||
guest_opaque_(true),
|
||||
guest_host_(nullptr),
|
||||
auto_size_enabled_(false),
|
||||
is_full_page_plugin_(false) {
|
||||
auto browser_context = AtomBrowserContext::Get();
|
||||
content::SiteInstance* site_instance = content::SiteInstance::CreateForURL(
|
||||
browser_context, GURL("chrome-guest://fake-host"));
|
||||
|
||||
content::WebContents::CreateParams params(browser_context, site_instance);
|
||||
params.guest_delegate = this;
|
||||
auto web_contents = content::WebContents::Create(params);
|
||||
|
||||
NativeWindow* owner_window = nullptr;
|
||||
WebContents* embedder = nullptr;
|
||||
if (options.Get("embedder", &embedder) && embedder)
|
||||
owner_window = NativeWindow::FromWebContents(embedder->web_contents());
|
||||
|
||||
InitWithWebContents(web_contents, owner_window);
|
||||
inspectable_web_contents_ = managed_web_contents();
|
||||
|
||||
Observe(GetWebContents());
|
||||
}
|
||||
|
||||
WebContents::~WebContents() {
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool WebContents::AddMessageToConsole(content::WebContents* source,
|
||||
int32 level,
|
||||
const base::string16& message,
|
||||
int32 line_no,
|
||||
const base::string16& source_id) {
|
||||
Emit("console-message", level, message, line_no, source_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebContents::ShouldCreateWebContents(
|
||||
content::WebContents* web_contents,
|
||||
int route_id,
|
||||
int main_frame_route_id,
|
||||
WindowContainerType window_container_type,
|
||||
const base::string16& frame_name,
|
||||
const GURL& target_url,
|
||||
const std::string& partition_id,
|
||||
content::SessionStorageNamespace* session_storage_namespace) {
|
||||
Emit("-new-window",
|
||||
target_url,
|
||||
frame_name,
|
||||
static_cast<int>(NEW_FOREGROUND_TAB));
|
||||
return false;
|
||||
}
|
||||
|
||||
void WebContents::CloseContents(content::WebContents* source) {
|
||||
Emit("close");
|
||||
}
|
||||
|
||||
content::WebContents* WebContents::OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) {
|
||||
if (params.disposition != CURRENT_TAB) {
|
||||
Emit("-new-window", params.url, "", static_cast<int>(params.disposition));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Give user a chance to cancel navigation.
|
||||
if (Emit("will-navigate", params.url))
|
||||
return nullptr;
|
||||
|
||||
return CommonWebContentsDelegate::OpenURLFromTab(source, params);
|
||||
}
|
||||
|
||||
void WebContents::HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
if (!attached())
|
||||
return;
|
||||
|
||||
// Send the unhandled keyboard events back to the embedder to reprocess them.
|
||||
embedder_web_contents_->GetDelegate()->HandleKeyboardEvent(
|
||||
web_contents(), event);
|
||||
}
|
||||
|
||||
void WebContents::EnterFullscreenModeForTab(content::WebContents* source,
|
||||
const GURL& origin) {
|
||||
CommonWebContentsDelegate::EnterFullscreenModeForTab(source, origin);
|
||||
Emit("enter-html-full-screen");
|
||||
}
|
||||
|
||||
void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
|
||||
CommonWebContentsDelegate::ExitFullscreenModeForTab(source);
|
||||
Emit("leave-html-full-screen");
|
||||
}
|
||||
|
||||
void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
|
||||
base::ListValue args;
|
||||
args.AppendInteger(render_view_host->GetProcess()->GetID());
|
||||
args.AppendInteger(render_view_host->GetRoutingID());
|
||||
Emit("render-view-deleted", args);
|
||||
Emit("render-view-deleted",
|
||||
render_view_host->GetProcess()->GetID(),
|
||||
render_view_host->GetRoutingID());
|
||||
}
|
||||
|
||||
void WebContents::RenderProcessGone(base::TerminationStatus status) {
|
||||
Emit("crashed");
|
||||
}
|
||||
|
||||
void WebContents::DidFinishLoad(int64 frame_id,
|
||||
const GURL& validated_url,
|
||||
bool is_main_frame,
|
||||
content::RenderViewHost* render_view_host) {
|
||||
Emit("did-finish-load");
|
||||
void WebContents::PluginCrashed(const base::FilePath& plugin_path,
|
||||
base::ProcessId plugin_pid) {
|
||||
content::WebPluginInfo info;
|
||||
auto plugin_service = content::PluginService::GetInstance();
|
||||
plugin_service->GetPluginInfoByPath(plugin_path, &info);
|
||||
Emit("plugin-crashed", info.name, info.version);
|
||||
}
|
||||
|
||||
void WebContents::DidStartLoading(content::RenderViewHost* render_view_host) {
|
||||
void WebContents::OnGpuProcessCrashed(base::TerminationStatus exit_code) {
|
||||
if (exit_code == base::TERMINATION_STATUS_PROCESS_CRASHED)
|
||||
Emit("gpu-crashed");
|
||||
}
|
||||
|
||||
void WebContents::DocumentLoadedInFrame(
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
if (!render_frame_host->GetParent())
|
||||
Emit("dom-ready");
|
||||
}
|
||||
|
||||
void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url) {
|
||||
bool is_main_frame = !render_frame_host->GetParent();
|
||||
Emit("did-frame-finish-load", is_main_frame);
|
||||
|
||||
if (is_main_frame)
|
||||
Emit("did-finish-load");
|
||||
}
|
||||
|
||||
// this error occurs when host could not be found
|
||||
void WebContents::DidFailProvisionalLoad(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url,
|
||||
int error_code,
|
||||
const base::string16& error_description) {
|
||||
Emit("did-fail-load", error_code, error_description);
|
||||
}
|
||||
|
||||
void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url,
|
||||
int error_code,
|
||||
const base::string16& error_description) {
|
||||
Emit("did-fail-load", error_code, error_description);
|
||||
}
|
||||
|
||||
void WebContents::DidStartLoading() {
|
||||
Emit("did-start-loading");
|
||||
}
|
||||
|
||||
void WebContents::DidStopLoading(content::RenderViewHost* render_view_host) {
|
||||
void WebContents::DidStopLoading() {
|
||||
Emit("did-stop-loading");
|
||||
}
|
||||
|
||||
void WebContents::DidGetResourceResponseStart(
|
||||
const content::ResourceRequestDetails& details) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
base::DictionaryValue response_headers;
|
||||
|
||||
net::HttpResponseHeaders* headers = details.headers.get();
|
||||
if (!headers)
|
||||
return;
|
||||
void* iter = nullptr;
|
||||
std::string key;
|
||||
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))
|
||||
values->AppendString(value);
|
||||
} else {
|
||||
scoped_ptr<base::ListValue> values(new base::ListValue());
|
||||
values->AppendString(value);
|
||||
response_headers.Set(key, values.Pass());
|
||||
}
|
||||
}
|
||||
|
||||
Emit("did-get-response-details",
|
||||
details.socket_address.IsEmpty(),
|
||||
details.url,
|
||||
details.original_url,
|
||||
details.http_response_code,
|
||||
details.method,
|
||||
details.referrer,
|
||||
response_headers);
|
||||
}
|
||||
|
||||
void WebContents::DidGetRedirectForResourceRequest(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const content::ResourceRedirectDetails& details) {
|
||||
Emit("did-get-redirect-request",
|
||||
details.url,
|
||||
details.new_url,
|
||||
(details.resource_type == content::RESOURCE_TYPE_MAIN_FRAME));
|
||||
}
|
||||
|
||||
void WebContents::DidNavigateMainFrame(
|
||||
const content::LoadCommittedDetails& details,
|
||||
const content::FrameNavigateParams& params) {
|
||||
if (details.is_navigation_to_different_page())
|
||||
Emit("did-navigate-to-different-page");
|
||||
}
|
||||
|
||||
void WebContents::TitleWasSet(content::NavigationEntry* entry,
|
||||
bool explicit_set) {
|
||||
// Back/Forward navigation may have pruned entries.
|
||||
if (entry)
|
||||
Emit("page-title-set", entry->GetTitle(), explicit_set);
|
||||
}
|
||||
|
||||
void WebContents::DidUpdateFaviconURL(
|
||||
const std::vector<content::FaviconURL>& urls) {
|
||||
std::set<GURL> unique_urls;
|
||||
for (auto iter = urls.begin(); iter != urls.end(); ++iter) {
|
||||
if (iter->icon_type != content::FaviconURL::FAVICON)
|
||||
continue;
|
||||
const GURL& url = iter->icon_url;
|
||||
if (url.is_valid())
|
||||
unique_urls.insert(url);
|
||||
}
|
||||
Emit("page-favicon-updated", unique_urls);
|
||||
}
|
||||
|
||||
bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(WebContents, message)
|
||||
@@ -61,28 +356,96 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
||||
return handled;
|
||||
}
|
||||
|
||||
void WebContents::WebContentsDestroyed(content::WebContents*) {
|
||||
void WebContents::RenderViewReady() {
|
||||
if (!is_guest())
|
||||
return;
|
||||
|
||||
// We don't want to accidentally set the opacity of an interstitial page.
|
||||
// WebContents::GetRenderWidgetHostView will return the RWHV of an
|
||||
// interstitial page if one is showing at this time. We only want opacity
|
||||
// to apply to web pages.
|
||||
auto render_view_host_view = web_contents()->GetRenderViewHost()->GetView();
|
||||
if (guest_opaque_)
|
||||
render_view_host_view->SetBackgroundColorToDefault();
|
||||
else
|
||||
render_view_host_view->SetBackgroundColor(SK_ColorTRANSPARENT);
|
||||
}
|
||||
|
||||
void WebContents::WebContentsDestroyed() {
|
||||
// The RenderViewDeleted was not called when the WebContents is destroyed.
|
||||
RenderViewDeleted(web_contents_->GetRenderViewHost());
|
||||
RenderViewDeleted(web_contents()->GetRenderViewHost());
|
||||
Emit("destroyed");
|
||||
}
|
||||
|
||||
void WebContents::NavigationEntryCommitted(
|
||||
const content::LoadCommittedDetails& details) {
|
||||
Emit("navigation-entry-commited", details.entry->GetURL(),
|
||||
details.is_in_page, details.did_replace_entry);
|
||||
}
|
||||
|
||||
void WebContents::DidAttach(int guest_proxy_routing_id) {
|
||||
Emit("did-attach");
|
||||
}
|
||||
|
||||
content::WebContents* WebContents::GetOwnerWebContents() const {
|
||||
return embedder_web_contents_;
|
||||
}
|
||||
|
||||
void WebContents::GuestSizeChanged(const gfx::Size& new_size) {
|
||||
if (!auto_size_enabled_)
|
||||
return;
|
||||
GuestSizeChangedDueToAutoSize(guest_size_, new_size);
|
||||
guest_size_ = new_size;
|
||||
}
|
||||
|
||||
void WebContents::SetGuestHost(content::GuestHost* guest_host) {
|
||||
guest_host_ = guest_host;
|
||||
}
|
||||
|
||||
void WebContents::WillAttach(content::WebContents* embedder_web_contents,
|
||||
int element_instance_id,
|
||||
bool is_full_page_plugin) {
|
||||
embedder_web_contents_ = embedder_web_contents;
|
||||
is_full_page_plugin_ = is_full_page_plugin;
|
||||
}
|
||||
|
||||
void WebContents::Destroy() {
|
||||
if (is_guest() && managed_web_contents()) {
|
||||
// When force destroying the "destroyed" event is not emitted.
|
||||
WebContentsDestroyed();
|
||||
|
||||
// Give the content module an opportunity to perform some cleanup.
|
||||
guest_host_->WillDestroy();
|
||||
guest_host_ = nullptr;
|
||||
|
||||
Observe(nullptr);
|
||||
DestroyWebContents();
|
||||
}
|
||||
}
|
||||
|
||||
bool WebContents::IsAlive() const {
|
||||
return web_contents() != NULL;
|
||||
}
|
||||
|
||||
void WebContents::LoadURL(const GURL& url) {
|
||||
void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
|
||||
content::NavigationController::LoadURLParams params(url);
|
||||
params.transition_type = content::PAGE_TRANSITION_TYPED;
|
||||
|
||||
GURL http_referrer;
|
||||
if (options.Get("httpReferrer", &http_referrer))
|
||||
params.referrer = content::Referrer(http_referrer.GetAsReferrer(),
|
||||
blink::WebReferrerPolicyDefault);
|
||||
|
||||
std::string user_agent;
|
||||
if (options.Get("userAgent", &user_agent))
|
||||
SetUserAgent(user_agent);
|
||||
|
||||
params.transition_type = ui::PAGE_TRANSITION_TYPED;
|
||||
params.should_clear_history_list = true;
|
||||
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
|
||||
web_contents()->GetController().LoadURLWithParams(params);
|
||||
}
|
||||
|
||||
GURL WebContents::GetURL() const {
|
||||
return web_contents()->GetURL();
|
||||
}
|
||||
|
||||
string16 WebContents::GetTitle() const {
|
||||
base::string16 WebContents::GetTitle() const {
|
||||
return web_contents()->GetTitle();
|
||||
}
|
||||
|
||||
@@ -98,42 +461,22 @@ void WebContents::Stop() {
|
||||
web_contents()->Stop();
|
||||
}
|
||||
|
||||
void WebContents::Reload() {
|
||||
// Navigating to a URL would always restart the renderer process, we want this
|
||||
// because normal reloading will break our node integration.
|
||||
// This is done by AtomBrowserClient::ShouldSwapProcessesForNavigation.
|
||||
LoadURL(GetURL());
|
||||
}
|
||||
|
||||
void WebContents::ReloadIgnoringCache() {
|
||||
Reload();
|
||||
}
|
||||
|
||||
bool WebContents::CanGoBack() const {
|
||||
return web_contents()->GetController().CanGoBack();
|
||||
}
|
||||
|
||||
bool WebContents::CanGoForward() const {
|
||||
return web_contents()->GetController().CanGoForward();
|
||||
}
|
||||
|
||||
bool WebContents::CanGoToOffset(int offset) const {
|
||||
return web_contents()->GetController().CanGoToOffset(offset);
|
||||
web_contents()->GetController().ReloadIgnoringCache(false);
|
||||
}
|
||||
|
||||
void WebContents::GoBack() {
|
||||
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
|
||||
web_contents()->GetController().GoBack();
|
||||
}
|
||||
|
||||
void WebContents::GoForward() {
|
||||
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
|
||||
web_contents()->GetController().GoForward();
|
||||
}
|
||||
|
||||
void WebContents::GoToIndex(int index) {
|
||||
web_contents()->GetController().GoToIndex(index);
|
||||
}
|
||||
|
||||
void WebContents::GoToOffset(int offset) {
|
||||
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
|
||||
web_contents()->GetController().GoToOffset(offset);
|
||||
}
|
||||
|
||||
@@ -149,61 +492,348 @@ bool WebContents::IsCrashed() const {
|
||||
return web_contents()->IsCrashed();
|
||||
}
|
||||
|
||||
void WebContents::ExecuteJavaScript(const string16& code) {
|
||||
web_contents()->GetRenderViewHost()->ExecuteJavascriptInWebFrame(
|
||||
string16(), code);
|
||||
void WebContents::SetUserAgent(const std::string& user_agent) {
|
||||
web_contents()->SetUserAgentOverride(user_agent);
|
||||
}
|
||||
|
||||
bool WebContents::SendIPCMessage(const string16& channel,
|
||||
void WebContents::InsertCSS(const std::string& css) {
|
||||
web_contents()->InsertCSS(css);
|
||||
}
|
||||
|
||||
void WebContents::ExecuteJavaScript(const base::string16& code) {
|
||||
web_contents()->GetMainFrame()->ExecuteJavaScript(code);
|
||||
}
|
||||
|
||||
void WebContents::OpenDevTools(mate::Arguments* args) {
|
||||
if (!inspectable_web_contents())
|
||||
return;
|
||||
bool detach = false;
|
||||
if (is_guest()) {
|
||||
detach = true;
|
||||
} else if (args && args->Length() == 1) {
|
||||
mate::Dictionary options;
|
||||
args->GetNext(&options) && options.Get("detach", &detach);
|
||||
}
|
||||
inspectable_web_contents()->SetCanDock(!detach);
|
||||
inspectable_web_contents()->ShowDevTools();
|
||||
}
|
||||
|
||||
void WebContents::CloseDevTools() {
|
||||
if (!inspectable_web_contents())
|
||||
return;
|
||||
inspectable_web_contents()->CloseDevTools();
|
||||
}
|
||||
|
||||
bool WebContents::IsDevToolsOpened() {
|
||||
if (!inspectable_web_contents())
|
||||
return false;
|
||||
return inspectable_web_contents()->IsDevToolsViewShowing();
|
||||
}
|
||||
|
||||
void WebContents::ToggleDevTools() {
|
||||
if (IsDevToolsOpened())
|
||||
CloseDevTools();
|
||||
else
|
||||
OpenDevTools(nullptr);
|
||||
}
|
||||
|
||||
void WebContents::InspectElement(int x, int y) {
|
||||
if (!inspectable_web_contents())
|
||||
return;
|
||||
OpenDevTools(nullptr);
|
||||
scoped_refptr<content::DevToolsAgentHost> agent(
|
||||
content::DevToolsAgentHost::GetOrCreateFor(web_contents()));
|
||||
agent->InspectElement(x, y);
|
||||
}
|
||||
|
||||
void WebContents::InspectServiceWorker() {
|
||||
if (!inspectable_web_contents())
|
||||
return;
|
||||
for (const auto& agent_host : content::DevToolsAgentHost::GetOrCreateAll()) {
|
||||
if (agent_host->GetType() ==
|
||||
content::DevToolsAgentHost::TYPE_SERVICE_WORKER) {
|
||||
OpenDevTools(nullptr);
|
||||
inspectable_web_contents()->AttachTo(agent_host);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebContents::HasServiceWorker(
|
||||
const base::Callback<void(bool)>& callback) {
|
||||
auto context = GetServiceWorkerContext(web_contents());
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
context->CheckHasServiceWorker(web_contents()->GetLastCommittedURL(),
|
||||
GURL::EmptyGURL(),
|
||||
callback);
|
||||
}
|
||||
|
||||
void WebContents::UnregisterServiceWorker(
|
||||
const base::Callback<void(bool)>& callback) {
|
||||
auto context = GetServiceWorkerContext(web_contents());
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
context->UnregisterServiceWorker(web_contents()->GetLastCommittedURL(),
|
||||
callback);
|
||||
}
|
||||
|
||||
void WebContents::Undo() {
|
||||
web_contents()->Undo();
|
||||
}
|
||||
|
||||
void WebContents::Redo() {
|
||||
web_contents()->Redo();
|
||||
}
|
||||
|
||||
void WebContents::Cut() {
|
||||
web_contents()->Cut();
|
||||
}
|
||||
|
||||
void WebContents::Copy() {
|
||||
web_contents()->Copy();
|
||||
}
|
||||
|
||||
void WebContents::Paste() {
|
||||
web_contents()->Paste();
|
||||
}
|
||||
|
||||
void WebContents::PasteAndMatchStyle() {
|
||||
web_contents()->PasteAndMatchStyle();
|
||||
}
|
||||
|
||||
void WebContents::Delete() {
|
||||
web_contents()->Delete();
|
||||
}
|
||||
|
||||
void WebContents::SelectAll() {
|
||||
web_contents()->SelectAll();
|
||||
}
|
||||
|
||||
void WebContents::Unselect() {
|
||||
web_contents()->Unselect();
|
||||
}
|
||||
|
||||
void WebContents::Replace(const base::string16& word) {
|
||||
web_contents()->Replace(word);
|
||||
}
|
||||
|
||||
void WebContents::ReplaceMisspelling(const base::string16& word) {
|
||||
web_contents()->ReplaceMisspelling(word);
|
||||
}
|
||||
|
||||
bool WebContents::SendIPCMessage(const base::string16& channel,
|
||||
const base::ListValue& args) {
|
||||
return Send(new AtomViewMsg_Message(routing_id(), channel, args));
|
||||
}
|
||||
|
||||
void WebContents::SetSize(const SetSizeParams& params) {
|
||||
bool enable_auto_size =
|
||||
params.enable_auto_size ? *params.enable_auto_size : auto_size_enabled_;
|
||||
gfx::Size min_size = params.min_size ? *params.min_size : min_auto_size_;
|
||||
gfx::Size max_size = params.max_size ? *params.max_size : max_auto_size_;
|
||||
|
||||
if (params.normal_size)
|
||||
normal_size_ = *params.normal_size;
|
||||
|
||||
min_auto_size_ = min_size;
|
||||
min_auto_size_.SetToMin(max_size);
|
||||
max_auto_size_ = max_size;
|
||||
max_auto_size_.SetToMax(min_size);
|
||||
|
||||
enable_auto_size &= !min_auto_size_.IsEmpty() && !max_auto_size_.IsEmpty();
|
||||
|
||||
content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
|
||||
if (enable_auto_size) {
|
||||
// Autosize is being enabled.
|
||||
rvh->EnableAutoResize(min_auto_size_, max_auto_size_);
|
||||
normal_size_.SetSize(0, 0);
|
||||
} else {
|
||||
// Autosize is being disabled.
|
||||
// Use default width/height if missing from partially defined normal size.
|
||||
if (normal_size_.width() && !normal_size_.height())
|
||||
normal_size_.set_height(GetDefaultSize().height());
|
||||
if (!normal_size_.width() && normal_size_.height())
|
||||
normal_size_.set_width(GetDefaultSize().width());
|
||||
|
||||
gfx::Size new_size;
|
||||
if (!normal_size_.IsEmpty()) {
|
||||
new_size = normal_size_;
|
||||
} else if (!guest_size_.IsEmpty()) {
|
||||
new_size = guest_size_;
|
||||
} else {
|
||||
new_size = GetDefaultSize();
|
||||
}
|
||||
|
||||
if (auto_size_enabled_) {
|
||||
// Autosize was previously enabled.
|
||||
rvh->DisableAutoResize(new_size);
|
||||
GuestSizeChangedDueToAutoSize(guest_size_, new_size);
|
||||
} else {
|
||||
// Autosize was already disabled.
|
||||
guest_host_->SizeContents(new_size);
|
||||
}
|
||||
|
||||
guest_size_ = new_size;
|
||||
}
|
||||
|
||||
auto_size_enabled_ = enable_auto_size;
|
||||
}
|
||||
|
||||
void WebContents::SetAllowTransparency(bool allow) {
|
||||
if (guest_opaque_ != allow)
|
||||
return;
|
||||
|
||||
guest_opaque_ = !allow;
|
||||
if (!web_contents()->GetRenderViewHost()->GetView())
|
||||
return;
|
||||
|
||||
if (guest_opaque_) {
|
||||
web_contents()
|
||||
->GetRenderViewHost()
|
||||
->GetView()
|
||||
->SetBackgroundColorToDefault();
|
||||
} else {
|
||||
web_contents()->GetRenderViewHost()->GetView()->SetBackgroundColor(
|
||||
SK_ColorTRANSPARENT);
|
||||
}
|
||||
}
|
||||
|
||||
bool WebContents::IsGuest() const {
|
||||
return is_guest();
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("isAlive", &WebContents::IsAlive)
|
||||
.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("reload", &WebContents::Reload)
|
||||
.SetMethod("reloadIgnoringCache", &WebContents::ReloadIgnoringCache)
|
||||
.SetMethod("canGoBack", &WebContents::CanGoBack)
|
||||
.SetMethod("canGoForward", &WebContents::CanGoForward)
|
||||
.SetMethod("canGoToOffset", &WebContents::CanGoToOffset)
|
||||
.SetMethod("goBack", &WebContents::GoBack)
|
||||
.SetMethod("goForward", &WebContents::GoForward)
|
||||
.SetMethod("goToIndex", &WebContents::GoToIndex)
|
||||
.SetMethod("goToOffset", &WebContents::GoToOffset)
|
||||
.SetMethod("getRoutingId", &WebContents::GetRoutingID)
|
||||
.SetMethod("getProcessId", &WebContents::GetProcessID)
|
||||
.SetMethod("isCrashed", &WebContents::IsCrashed)
|
||||
.SetMethod("executeJavaScript", &WebContents::ExecuteJavaScript)
|
||||
.SetMethod("_send", &WebContents::SendIPCMessage);
|
||||
if (template_.IsEmpty())
|
||||
template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("destroy", &WebContents::Destroy)
|
||||
.SetMethod("isAlive", &WebContents::IsAlive)
|
||||
.SetMethod("_loadUrl", &WebContents::LoadURL)
|
||||
.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)
|
||||
.SetMethod("getRoutingId", &WebContents::GetRoutingID)
|
||||
.SetMethod("getProcessId", &WebContents::GetProcessID)
|
||||
.SetMethod("isCrashed", &WebContents::IsCrashed)
|
||||
.SetMethod("setUserAgent", &WebContents::SetUserAgent)
|
||||
.SetMethod("insertCSS", &WebContents::InsertCSS)
|
||||
.SetMethod("_executeJavaScript", &WebContents::ExecuteJavaScript)
|
||||
.SetMethod("openDevTools", &WebContents::OpenDevTools)
|
||||
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
|
||||
.SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
|
||||
.SetMethod("toggleDevTools", &WebContents::ToggleDevTools)
|
||||
.SetMethod("inspectElement", &WebContents::InspectElement)
|
||||
.SetMethod("undo", &WebContents::Undo)
|
||||
.SetMethod("redo", &WebContents::Redo)
|
||||
.SetMethod("cut", &WebContents::Cut)
|
||||
.SetMethod("copy", &WebContents::Copy)
|
||||
.SetMethod("paste", &WebContents::Paste)
|
||||
.SetMethod("pasteAndMatchStyle", &WebContents::PasteAndMatchStyle)
|
||||
.SetMethod("delete", &WebContents::Delete)
|
||||
.SetMethod("selectAll", &WebContents::SelectAll)
|
||||
.SetMethod("unselect", &WebContents::Unselect)
|
||||
.SetMethod("replace", &WebContents::Replace)
|
||||
.SetMethod("replaceMisspelling", &WebContents::ReplaceMisspelling)
|
||||
.SetMethod("_send", &WebContents::SendIPCMessage)
|
||||
.SetMethod("setSize", &WebContents::SetSize)
|
||||
.SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
|
||||
.SetMethod("isGuest", &WebContents::IsGuest)
|
||||
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
|
||||
.SetMethod("unregisterServiceWorker",
|
||||
&WebContents::UnregisterServiceWorker)
|
||||
.SetMethod("inspectServiceWorker", &WebContents::InspectServiceWorker)
|
||||
.Build());
|
||||
|
||||
return mate::ObjectTemplateBuilder(
|
||||
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
|
||||
}
|
||||
|
||||
void WebContents::OnRendererMessage(const string16& channel,
|
||||
void WebContents::OnRendererMessage(const base::string16& channel,
|
||||
const base::ListValue& args) {
|
||||
// webContents.emit(channel, new Event(), args...);
|
||||
Emit(UTF16ToUTF8(channel), args, web_contents(), NULL);
|
||||
Emit(base::UTF16ToUTF8(channel), args);
|
||||
}
|
||||
|
||||
void WebContents::OnRendererMessageSync(const string16& channel,
|
||||
void WebContents::OnRendererMessageSync(const base::string16& channel,
|
||||
const base::ListValue& args,
|
||||
IPC::Message* message) {
|
||||
// webContents.emit(channel, new Event(sender, message), args...);
|
||||
Emit(UTF16ToUTF8(channel), args, web_contents(), message);
|
||||
EmitWithSender(base::UTF16ToUTF8(channel), web_contents(), message, args);
|
||||
}
|
||||
|
||||
void WebContents::GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
|
||||
const gfx::Size& new_size) {
|
||||
Emit("size-changed",
|
||||
old_size.width(), old_size.height(),
|
||||
new_size.width(), new_size.height());
|
||||
}
|
||||
|
||||
gfx::Size WebContents::GetDefaultSize() const {
|
||||
if (is_full_page_plugin_) {
|
||||
// Full page plugins default to the size of the owner's viewport.
|
||||
return embedder_web_contents_->GetRenderWidgetHostView()
|
||||
->GetVisibleViewportSize();
|
||||
} else {
|
||||
return gfx::Size(kDefaultWidth, kDefaultHeight);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<WebContents> WebContents::CreateFrom(
|
||||
v8::Isolate* isolate, brightray::InspectableWebContents* web_contents) {
|
||||
auto handle = mate::CreateHandle(isolate, new WebContents(web_contents));
|
||||
g_wrap_web_contents.Run(handle.ToV8());
|
||||
return handle;
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<WebContents> WebContents::CreateFrom(
|
||||
v8::Isolate* isolate, content::WebContents* web_contents) {
|
||||
auto handle = mate::CreateHandle(isolate, new WebContents(web_contents));
|
||||
g_wrap_web_contents.Run(handle.ToV8());
|
||||
return handle;
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<WebContents> WebContents::Create(
|
||||
v8::Isolate* isolate, content::WebContents* web_contents) {
|
||||
return mate::CreateHandle(isolate, new WebContents(web_contents));
|
||||
v8::Isolate* isolate, const mate::Dictionary& options) {
|
||||
auto handle = mate::CreateHandle(isolate, new WebContents(options));
|
||||
g_wrap_web_contents.Run(handle.ToV8());
|
||||
return handle;
|
||||
}
|
||||
|
||||
void SetWrapWebContents(const WrapWebContentsCallback& callback) {
|
||||
g_wrap_web_contents = callback;
|
||||
}
|
||||
|
||||
void ClearWrapWebContents() {
|
||||
g_wrap_web_contents.Reset();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.SetMethod("create", &atom::api::WebContents::Create);
|
||||
dict.SetMethod("_setWrapWebContents", &atom::api::SetWrapWebContents);
|
||||
dict.SetMethod("_clearWrapWebContents", &atom::api::ClearWrapWebContents);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_web_contents, Initialize)
|
||||
|
||||
@@ -1,78 +1,267 @@
|
||||
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_WEB_CONTENTS_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_WEB_CONTENTS_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
#include "content/public/browser/browser_plugin_guest_delegate.h"
|
||||
#include "content/public/common/favicon_url.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "content/public/browser/gpu_data_manager_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
namespace brightray {
|
||||
class InspectableWebContents;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class WebContents : public mate::EventEmitter,
|
||||
public content::WebContentsObserver {
|
||||
public:
|
||||
static mate::Handle<WebContents> Create(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents);
|
||||
// A struct of parameters for SetSize(). The parameters are all declared as
|
||||
// scoped pointers since they are all optional. Null pointers indicate that the
|
||||
// parameter has not been provided, and the last used value should be used. Note
|
||||
// that when |enable_auto_size| is true, providing |normal_size| is not
|
||||
// meaningful. This is because the normal size of the guestview is overridden
|
||||
// whenever autosizing occurs.
|
||||
struct SetSizeParams {
|
||||
SetSizeParams() {}
|
||||
~SetSizeParams() {}
|
||||
|
||||
scoped_ptr<bool> enable_auto_size;
|
||||
scoped_ptr<gfx::Size> min_size;
|
||||
scoped_ptr<gfx::Size> max_size;
|
||||
scoped_ptr<gfx::Size> normal_size;
|
||||
};
|
||||
|
||||
class WebContents : public mate::EventEmitter,
|
||||
public content::BrowserPluginGuestDelegate,
|
||||
public CommonWebContentsDelegate,
|
||||
public content::WebContentsObserver,
|
||||
public content::GpuDataManagerObserver {
|
||||
public:
|
||||
// Create from an existing WebContents.
|
||||
static mate::Handle<WebContents> CreateFrom(
|
||||
v8::Isolate* isolate, brightray::InspectableWebContents* web_contents);
|
||||
static mate::Handle<WebContents> CreateFrom(
|
||||
v8::Isolate* isolate, content::WebContents* web_contents);
|
||||
|
||||
// Create a new WebContents.
|
||||
static mate::Handle<WebContents> Create(
|
||||
v8::Isolate* isolate, const mate::Dictionary& options);
|
||||
|
||||
void Destroy();
|
||||
bool IsAlive() const;
|
||||
void LoadURL(const GURL& url);
|
||||
GURL GetURL() const;
|
||||
string16 GetTitle() const;
|
||||
void LoadURL(const GURL& url, const mate::Dictionary& options);
|
||||
base::string16 GetTitle() const;
|
||||
bool IsLoading() const;
|
||||
bool IsWaitingForResponse() const;
|
||||
void Stop();
|
||||
void Reload();
|
||||
void ReloadIgnoringCache();
|
||||
bool CanGoBack() const;
|
||||
bool CanGoForward() const;
|
||||
bool CanGoToOffset(int offset) const;
|
||||
void GoBack();
|
||||
void GoForward();
|
||||
void GoToIndex(int index);
|
||||
void GoToOffset(int offset);
|
||||
int GetRoutingID() const;
|
||||
int GetProcessID() const;
|
||||
bool IsCrashed() const;
|
||||
void ExecuteJavaScript(const string16& code);
|
||||
bool SendIPCMessage(const string16& channel, const base::ListValue& args);
|
||||
void SetUserAgent(const std::string& user_agent);
|
||||
void InsertCSS(const std::string& css);
|
||||
void ExecuteJavaScript(const base::string16& code);
|
||||
void OpenDevTools(mate::Arguments* args);
|
||||
void CloseDevTools();
|
||||
bool IsDevToolsOpened();
|
||||
void ToggleDevTools();
|
||||
void InspectElement(int x, int y);
|
||||
void InspectServiceWorker();
|
||||
void HasServiceWorker(const base::Callback<void(bool)>&);
|
||||
void UnregisterServiceWorker(const base::Callback<void(bool)>&);
|
||||
|
||||
// Editing commands.
|
||||
void Undo();
|
||||
void Redo();
|
||||
void Cut();
|
||||
void Copy();
|
||||
void Paste();
|
||||
void PasteAndMatchStyle();
|
||||
void Delete();
|
||||
void SelectAll();
|
||||
void Unselect();
|
||||
void Replace(const base::string16& word);
|
||||
void ReplaceMisspelling(const base::string16& word);
|
||||
|
||||
// Sending messages to browser.
|
||||
bool SendIPCMessage(const base::string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
// Used to toggle autosize mode for this GuestView, and set both the automatic
|
||||
// and normal sizes.
|
||||
void SetSize(const SetSizeParams& params);
|
||||
|
||||
// Sets the transparency of the guest.
|
||||
void SetAllowTransparency(bool allow);
|
||||
|
||||
bool IsGuest() const;
|
||||
|
||||
// Returns whether this guest has an associated embedder.
|
||||
bool attached() const { return !!embedder_web_contents_; }
|
||||
|
||||
// Returns the current InspectableWebContents object, nullptr will be returned
|
||||
// if current WebContents can not beinspected, e.g. it is the devtools.
|
||||
brightray::InspectableWebContents* inspectable_web_contents() const {
|
||||
return inspectable_web_contents_;
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit WebContents(brightray::InspectableWebContents* web_contents);
|
||||
explicit WebContents(content::WebContents* web_contents);
|
||||
explicit WebContents(const mate::Dictionary& options);
|
||||
~WebContents();
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) OVERRIDE;
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
// content::WebContentsObserver implementations:
|
||||
virtual void RenderViewDeleted(content::RenderViewHost*) OVERRIDE;
|
||||
virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
|
||||
virtual void DidFinishLoad(
|
||||
int64 frame_id,
|
||||
const GURL& validated_url,
|
||||
bool is_main_frame,
|
||||
content::RenderViewHost* render_view_host) OVERRIDE;
|
||||
virtual void DidStartLoading(
|
||||
content::RenderViewHost* render_view_host) OVERRIDE;
|
||||
virtual void DidStopLoading(
|
||||
content::RenderViewHost* render_view_host) OVERRIDE;
|
||||
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
|
||||
virtual void WebContentsDestroyed(content::WebContents*) OVERRIDE;
|
||||
// content::WebContentsDelegate:
|
||||
bool AddMessageToConsole(content::WebContents* source,
|
||||
int32 level,
|
||||
const base::string16& message,
|
||||
int32 line_no,
|
||||
const base::string16& source_id) override;
|
||||
bool ShouldCreateWebContents(
|
||||
content::WebContents* web_contents,
|
||||
int route_id,
|
||||
int main_frame_route_id,
|
||||
WindowContainerType window_container_type,
|
||||
const base::string16& frame_name,
|
||||
const GURL& target_url,
|
||||
const std::string& partition_id,
|
||||
content::SessionStorageNamespace* session_storage_namespace) override;
|
||||
void CloseContents(content::WebContents* source) override;
|
||||
content::WebContents* OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) override;
|
||||
void HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
void EnterFullscreenModeForTab(content::WebContents* source,
|
||||
const GURL& origin) override;
|
||||
void ExitFullscreenModeForTab(content::WebContents* source) override;
|
||||
|
||||
// content::WebContentsObserver:
|
||||
void RenderViewDeleted(content::RenderViewHost*) override;
|
||||
void RenderProcessGone(base::TerminationStatus status) override;
|
||||
void DocumentLoadedInFrame(
|
||||
content::RenderFrameHost* render_frame_host) override;
|
||||
void DidFinishLoad(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url) override;
|
||||
void DidFailLoad(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url,
|
||||
int error_code,
|
||||
const base::string16& error_description) override;
|
||||
void DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url,
|
||||
int error_code,
|
||||
const base::string16& error_description) override;
|
||||
void DidStartLoading() override;
|
||||
void DidStopLoading() override;
|
||||
void DidGetResourceResponseStart(
|
||||
const content::ResourceRequestDetails& details) override;
|
||||
void DidGetRedirectForResourceRequest(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const content::ResourceRedirectDetails& details) override;
|
||||
void DidNavigateMainFrame(
|
||||
const content::LoadCommittedDetails& details,
|
||||
const content::FrameNavigateParams& params) override;
|
||||
bool OnMessageReceived(const IPC::Message& message) override;
|
||||
void RenderViewReady() override;
|
||||
void WebContentsDestroyed() override;
|
||||
void NavigationEntryCommitted(
|
||||
const content::LoadCommittedDetails& load_details) override;
|
||||
void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override;
|
||||
void DidUpdateFaviconURL(
|
||||
const std::vector<content::FaviconURL>& urls) override;
|
||||
void PluginCrashed(const base::FilePath& plugin_path,
|
||||
base::ProcessId plugin_pid) override;
|
||||
|
||||
// content::BrowserPluginGuestDelegate:
|
||||
void DidAttach(int guest_proxy_routing_id) final;
|
||||
content::WebContents* GetOwnerWebContents() const final;
|
||||
void GuestSizeChanged(const gfx::Size& new_size) final;
|
||||
void SetGuestHost(content::GuestHost* guest_host) final;
|
||||
void WillAttach(content::WebContents* embedder_web_contents,
|
||||
int element_instance_id,
|
||||
bool is_full_page_plugin) final;
|
||||
|
||||
// content::GpuDataManagerObserver:
|
||||
void OnGpuProcessCrashed(base::TerminationStatus exit_code) override;
|
||||
|
||||
private:
|
||||
// Called when received a message from renderer.
|
||||
void OnRendererMessage(const string16& channel, const base::ListValue& args);
|
||||
void OnRendererMessage(const base::string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
// Called when received a synchronous message from renderer.
|
||||
void OnRendererMessageSync(const string16& channel,
|
||||
void OnRendererMessageSync(const base::string16& channel,
|
||||
const base::ListValue& args,
|
||||
IPC::Message* message);
|
||||
|
||||
content::WebContents* web_contents_; // Weak.
|
||||
// This method is invoked when the contents auto-resized to give the container
|
||||
// an opportunity to match it if it wishes.
|
||||
//
|
||||
// This gives the derived class an opportunity to inform its container element
|
||||
// or perform other actions.
|
||||
void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
|
||||
const gfx::Size& new_size);
|
||||
|
||||
// Returns the default size of the guestview.
|
||||
gfx::Size GetDefaultSize() const;
|
||||
|
||||
// Stores whether the contents of the guest can be transparent.
|
||||
bool guest_opaque_;
|
||||
|
||||
// The WebContents that attaches this guest view.
|
||||
content::WebContents* embedder_web_contents_;
|
||||
|
||||
// The size of the container element.
|
||||
gfx::Size element_size_;
|
||||
|
||||
// The size of the guest content. Note: In autosize mode, the container
|
||||
// element may not match the size of the guest.
|
||||
gfx::Size guest_size_;
|
||||
|
||||
// A pointer to the guest_host.
|
||||
content::GuestHost* guest_host_;
|
||||
|
||||
// Indicates whether autosize mode is enabled or not.
|
||||
bool auto_size_enabled_;
|
||||
|
||||
// The maximum size constraints of the container element in autosize mode.
|
||||
gfx::Size max_auto_size_;
|
||||
|
||||
// The minimum size constraints of the container element in autosize mode.
|
||||
gfx::Size min_auto_size_;
|
||||
|
||||
// The size that will be used when autosize mode is disabled.
|
||||
gfx::Size normal_size_;
|
||||
|
||||
// Whether the guest view is inside a plugin document.
|
||||
bool is_full_page_plugin_;
|
||||
|
||||
// Current InspectableWebContents object, can be nullptr for WebContents of
|
||||
// devtools. It is a weak reference.
|
||||
brightray::InspectableWebContents* inspectable_web_contents_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContents);
|
||||
};
|
||||
|
||||
93
atom/browser/api/atom_api_web_view_manager.cc
Normal file
93
atom/browser/api/atom_api_web_view_manager.cc
Normal file
@@ -0,0 +1,93 @@
|
||||
// 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/atom_api_web_contents.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/filename_util.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<content::WebContents*> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
content::WebContents** out) {
|
||||
atom::api::WebContents* contents;
|
||||
if (!Converter<atom::api::WebContents*>::FromV8(isolate, val, &contents))
|
||||
return false;
|
||||
*out = contents->web_contents();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<atom::WebViewManager::WebViewInfo> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
atom::WebViewManager::WebViewInfo* out) {
|
||||
Dictionary options;
|
||||
if (!ConvertFromV8(isolate, val, &options))
|
||||
return false;
|
||||
|
||||
GURL preload_url;
|
||||
if (!options.Get("preloadUrl", &preload_url))
|
||||
return false;
|
||||
|
||||
if (!preload_url.is_empty() &&
|
||||
!net::FileURLToFilePath(preload_url, &(out->preload_script)))
|
||||
return false;
|
||||
|
||||
return options.Get("nodeIntegration", &(out->node_integration)) &&
|
||||
options.Get("plugins", &(out->plugins)) &&
|
||||
options.Get("disableWebSecurity", &(out->disable_web_security));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace {
|
||||
|
||||
atom::WebViewManager* GetWebViewManager(content::WebContents* web_contents) {
|
||||
auto context = web_contents->GetBrowserContext();
|
||||
if (context) {
|
||||
auto manager = context->GetGuestManager();
|
||||
return static_cast<atom::WebViewManager*>(manager);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AddGuest(int guest_instance_id,
|
||||
int element_instance_id,
|
||||
content::WebContents* embedder,
|
||||
content::WebContents* guest_web_contents,
|
||||
atom::WebViewManager::WebViewInfo info) {
|
||||
auto manager = GetWebViewManager(embedder);
|
||||
if (manager) {
|
||||
info.guest_instance_id = guest_instance_id;
|
||||
info.embedder = embedder;
|
||||
manager->AddGuest(guest_instance_id, element_instance_id, embedder,
|
||||
guest_web_contents, info);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveGuest(content::WebContents* embedder, int guest_instance_id) {
|
||||
auto manager = GetWebViewManager(embedder);
|
||||
if (manager)
|
||||
manager->RemoveGuest(guest_instance_id);
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("addGuest", &AddGuest);
|
||||
dict.SetMethod("removeGuest", &RemoveGuest);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_web_view_manager, Initialize)
|
||||
@@ -1,39 +1,45 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_window.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/common/native_mate_converters/function_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/callback.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "native_mate/callback.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/point.h"
|
||||
#include "ui/gfx/rect.h"
|
||||
#include "ui/gfx/size.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace {
|
||||
|
||||
struct PrintSettings {
|
||||
bool silent;
|
||||
bool print_background;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<gfx::Rect> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::Rect* out) {
|
||||
if (!val->IsObject())
|
||||
struct Converter<PrintSettings> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
PrintSettings* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
mate::Dictionary dict(isolate, val->ToObject());
|
||||
int x, y, width, height;
|
||||
if (!dict.Get("x", &x) || !dict.Get("y", &y) ||
|
||||
!dict.Get("width", &width) || !dict.Get("height", &height))
|
||||
return false;
|
||||
*out = gfx::Rect(x, y, width, height);
|
||||
dict.Get("silent", &(out->silent));
|
||||
dict.Get("printBackground", &(out->print_background));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -47,21 +53,18 @@ namespace api {
|
||||
namespace {
|
||||
|
||||
void OnCapturePageDone(
|
||||
const base::Callback<void(v8::Handle<v8::Value>)>& callback,
|
||||
const std::vector<unsigned char>& data) {
|
||||
v8::Locker locker(node_isolate);
|
||||
v8::HandleScope handle_scope(node_isolate);
|
||||
|
||||
v8::Local<v8::Value> buffer = node::Buffer::New(
|
||||
reinterpret_cast<const char*>(data.data()),
|
||||
data.size());
|
||||
callback.Run(buffer);
|
||||
v8::Isolate* isolate,
|
||||
const base::Callback<void(const gfx::Image&)>& callback,
|
||||
const SkBitmap& bitmap) {
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
Window::Window(base::DictionaryValue* options)
|
||||
Window::Window(const mate::Dictionary& options)
|
||||
: window_(NativeWindow::Create(options)) {
|
||||
window_->InitFromOptions(options);
|
||||
window_->AddObserver(this);
|
||||
@@ -70,15 +73,22 @@ Window::Window(base::DictionaryValue* options)
|
||||
Window::~Window() {
|
||||
if (window_)
|
||||
Destroy();
|
||||
|
||||
Emit("destroyed");
|
||||
}
|
||||
|
||||
void Window::OnPageTitleUpdated(bool* prevent_default,
|
||||
const std::string& title) {
|
||||
base::ListValue args;
|
||||
args.AppendString(title);
|
||||
*prevent_default = Emit("page-title-updated", args);
|
||||
*prevent_default = Emit("page-title-updated", title);
|
||||
}
|
||||
|
||||
void Window::WillCreatePopupWindow(const base::string16& frame_name,
|
||||
const GURL& target_url,
|
||||
const std::string& partition_id,
|
||||
WindowOpenDisposition disposition) {
|
||||
Emit("-new-window", target_url, frame_name, static_cast<int>(disposition));
|
||||
}
|
||||
|
||||
void Window::WillNavigate(bool* prevent_default, const GURL& url) {
|
||||
*prevent_default = Emit("-will-navigate", url);
|
||||
}
|
||||
|
||||
void Window::WillCloseWindow(bool* prevent_default) {
|
||||
@@ -95,6 +105,54 @@ void Window::OnWindowBlur() {
|
||||
Emit("blur");
|
||||
}
|
||||
|
||||
void Window::OnWindowFocus() {
|
||||
Emit("focus");
|
||||
}
|
||||
|
||||
void Window::OnWindowMaximize() {
|
||||
Emit("maximize");
|
||||
}
|
||||
|
||||
void Window::OnWindowUnmaximize() {
|
||||
Emit("unmaximize");
|
||||
}
|
||||
|
||||
void Window::OnWindowMinimize() {
|
||||
Emit("minimize");
|
||||
}
|
||||
|
||||
void Window::OnWindowRestore() {
|
||||
Emit("restore");
|
||||
}
|
||||
|
||||
void Window::OnWindowResize() {
|
||||
Emit("resize");
|
||||
}
|
||||
|
||||
void Window::OnWindowMove() {
|
||||
Emit("move");
|
||||
}
|
||||
|
||||
void Window::OnWindowMoved() {
|
||||
Emit("moved");
|
||||
}
|
||||
|
||||
void Window::OnWindowEnterFullScreen() {
|
||||
Emit("enter-full-screen");
|
||||
}
|
||||
|
||||
void Window::OnWindowLeaveFullScreen() {
|
||||
Emit("leave-full-screen");
|
||||
}
|
||||
|
||||
void Window::OnWindowEnterHtmlFullScreen() {
|
||||
Emit("enter-html-full-screen");
|
||||
}
|
||||
|
||||
void Window::OnWindowLeaveHtmlFullScreen() {
|
||||
Emit("leave-html-full-screen");
|
||||
}
|
||||
|
||||
void Window::OnRendererUnresponsive() {
|
||||
Emit("unresponsive");
|
||||
}
|
||||
@@ -103,17 +161,39 @@ void Window::OnRendererResponsive() {
|
||||
Emit("responsive");
|
||||
}
|
||||
|
||||
void Window::OnDevToolsFocus() {
|
||||
Emit("devtools-focused");
|
||||
}
|
||||
|
||||
void Window::OnDevToolsOpened() {
|
||||
Emit("devtools-opened");
|
||||
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
auto handle =
|
||||
WebContents::CreateFrom(isolate, window_->GetDevToolsWebContents());
|
||||
devtools_web_contents_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
|
||||
void Window::OnDevToolsClosed() {
|
||||
Emit("devtools-closed");
|
||||
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
devtools_web_contents_.Reset();
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Wrappable* Window::New(mate::Arguments* args,
|
||||
const base::DictionaryValue& options) {
|
||||
scoped_ptr<base::DictionaryValue> copied_options(options.DeepCopy());
|
||||
Window* window = new Window(copied_options.get());
|
||||
window->Wrap(args->isolate(), args->GetThis());
|
||||
|
||||
// Give js code a chance to do initialization.
|
||||
node::MakeCallback(args->GetThis(), "_init", 0, NULL);
|
||||
|
||||
return window;
|
||||
mate::Wrappable* Window::New(v8::Isolate* isolate,
|
||||
const mate::Dictionary& options) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
node::ThrowError(isolate,
|
||||
"Cannot create BrowserWindow before app is ready");
|
||||
return nullptr;
|
||||
}
|
||||
return new Window(options);
|
||||
}
|
||||
|
||||
void Window::Destroy() {
|
||||
@@ -125,6 +205,10 @@ void Window::Close() {
|
||||
window_->Close();
|
||||
}
|
||||
|
||||
bool Window::IsClosed() {
|
||||
return window_->IsClosed();
|
||||
}
|
||||
|
||||
void Window::Focus() {
|
||||
window_->Focus(true);
|
||||
}
|
||||
@@ -137,6 +221,10 @@ void Window::Show() {
|
||||
window_->Show();
|
||||
}
|
||||
|
||||
void Window::ShowInactive() {
|
||||
window_->ShowInactive();
|
||||
}
|
||||
|
||||
void Window::Hide() {
|
||||
window_->Hide();
|
||||
}
|
||||
@@ -153,6 +241,10 @@ void Window::Unmaximize() {
|
||||
window_->Unmaximize();
|
||||
}
|
||||
|
||||
bool Window::IsMaximized() {
|
||||
return window_->IsMaximized();
|
||||
}
|
||||
|
||||
void Window::Minimize() {
|
||||
window_->Minimize();
|
||||
}
|
||||
@@ -161,14 +253,26 @@ void Window::Restore() {
|
||||
window_->Restore();
|
||||
}
|
||||
|
||||
void Window::SetFullscreen(bool fullscreen) {
|
||||
window_->SetFullscreen(fullscreen);
|
||||
bool Window::IsMinimized() {
|
||||
return window_->IsMinimized();
|
||||
}
|
||||
|
||||
void Window::SetFullScreen(bool fullscreen) {
|
||||
window_->SetFullScreen(fullscreen);
|
||||
}
|
||||
|
||||
bool Window::IsFullscreen() {
|
||||
return window_->IsFullscreen();
|
||||
}
|
||||
|
||||
void Window::SetBounds(const gfx::Rect& bounds) {
|
||||
window_->SetBounds(bounds);
|
||||
}
|
||||
|
||||
gfx::Rect Window::GetBounds() {
|
||||
return window_->GetBounds();
|
||||
}
|
||||
|
||||
void Window::SetSize(int width, int height) {
|
||||
window_->SetSize(gfx::Size(width, height));
|
||||
}
|
||||
@@ -261,6 +365,10 @@ void Window::FlashFrame(bool flash) {
|
||||
window_->FlashFrame(flash);
|
||||
}
|
||||
|
||||
void Window::SetSkipTaskbar(bool skip) {
|
||||
window_->SetSkipTaskbar(skip);
|
||||
}
|
||||
|
||||
void Window::SetKiosk(bool kiosk) {
|
||||
window_->SetKiosk(kiosk);
|
||||
}
|
||||
@@ -269,27 +377,6 @@ bool Window::IsKiosk() {
|
||||
return window_->IsKiosk();
|
||||
}
|
||||
|
||||
void Window::OpenDevTools() {
|
||||
window_->OpenDevTools();
|
||||
}
|
||||
|
||||
void Window::CloseDevTools() {
|
||||
window_->CloseDevTools();
|
||||
}
|
||||
|
||||
bool Window::IsDevToolsOpened() {
|
||||
return window_->IsDevToolsOpened();
|
||||
}
|
||||
|
||||
void Window::InspectElement(int x, int y) {
|
||||
window_->InspectElement(x, y);
|
||||
}
|
||||
|
||||
void Window::DebugDevTools() {
|
||||
if (window_->IsDevToolsOpened())
|
||||
NativeWindow::Debug(window_->GetDevToolsWebContents());
|
||||
}
|
||||
|
||||
void Window::FocusOnWebView() {
|
||||
window_->FocusOnWebView();
|
||||
}
|
||||
@@ -302,9 +389,25 @@ bool Window::IsWebViewFocused() {
|
||||
return window_->IsWebViewFocused();
|
||||
}
|
||||
|
||||
void Window::SetRepresentedFilename(const std::string& filename) {
|
||||
window_->SetRepresentedFilename(filename);
|
||||
}
|
||||
|
||||
std::string Window::GetRepresentedFilename() {
|
||||
return window_->GetRepresentedFilename();
|
||||
}
|
||||
|
||||
void Window::SetDocumentEdited(bool edited) {
|
||||
window_->SetDocumentEdited(edited);
|
||||
}
|
||||
|
||||
bool Window::IsDocumentEdited() {
|
||||
return window_->IsDocumentEdited();
|
||||
}
|
||||
|
||||
void Window::CapturePage(mate::Arguments* args) {
|
||||
gfx::Rect rect;
|
||||
base::Callback<void(v8::Handle<v8::Value>)> callback;
|
||||
base::Callback<void(const gfx::Image&)> callback;
|
||||
|
||||
if (!(args->Length() == 1 && args->GetNext(&callback)) &&
|
||||
!(args->Length() == 2 && args->GetNext(&rect)
|
||||
@@ -313,35 +416,102 @@ void Window::CapturePage(mate::Arguments* args) {
|
||||
return;
|
||||
}
|
||||
|
||||
window_->CapturePage(rect, base::Bind(&OnCapturePageDone, callback));
|
||||
window_->CapturePage(
|
||||
rect, base::Bind(&OnCapturePageDone, args->isolate(), callback));
|
||||
}
|
||||
|
||||
mate::Handle<WebContents> Window::GetWebContents(v8::Isolate* isolate) const {
|
||||
return WebContents::Create(isolate, window_->GetWebContents());
|
||||
void Window::Print(mate::Arguments* args) {
|
||||
PrintSettings settings = { false, false };;
|
||||
if (args->Length() == 1 && !args->GetNext(&settings)) {
|
||||
args->ThrowError();
|
||||
return;
|
||||
}
|
||||
|
||||
window_->Print(settings.silent, settings.print_background);
|
||||
}
|
||||
|
||||
mate::Handle<WebContents> Window::GetDevToolsWebContents(
|
||||
v8::Isolate* isolate) const {
|
||||
return WebContents::Create(isolate, window_->GetDevToolsWebContents());
|
||||
void Window::SetProgressBar(double progress) {
|
||||
window_->SetProgressBar(progress);
|
||||
}
|
||||
|
||||
void Window::SetOverlayIcon(const gfx::Image& overlay,
|
||||
const std::string& description) {
|
||||
window_->SetOverlayIcon(overlay, description);
|
||||
}
|
||||
|
||||
void Window::SetMenu(ui::SimpleMenuModel* menu) {
|
||||
window_->SetMenu(menu);
|
||||
}
|
||||
|
||||
void Window::SetAutoHideMenuBar(bool auto_hide) {
|
||||
window_->SetAutoHideMenuBar(auto_hide);
|
||||
}
|
||||
|
||||
bool Window::IsMenuBarAutoHide() {
|
||||
return window_->IsMenuBarAutoHide();
|
||||
}
|
||||
|
||||
void Window::SetMenuBarVisibility(bool visible) {
|
||||
window_->SetMenuBarVisibility(visible);
|
||||
}
|
||||
|
||||
bool Window::IsMenuBarVisible() {
|
||||
return window_->IsMenuBarVisible();
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void Window::ShowDefinitionForSelection() {
|
||||
window_->ShowDefinitionForSelection();
|
||||
}
|
||||
#endif
|
||||
|
||||
void Window::SetVisibleOnAllWorkspaces(bool visible) {
|
||||
return window_->SetVisibleOnAllWorkspaces(visible);
|
||||
}
|
||||
|
||||
bool Window::IsVisibleOnAllWorkspaces() {
|
||||
return window_->IsVisibleOnAllWorkspaces();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Window::WebContents(v8::Isolate* isolate) {
|
||||
if (web_contents_.IsEmpty()) {
|
||||
auto handle =
|
||||
WebContents::CreateFrom(isolate, window_->managed_web_contents());
|
||||
web_contents_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, web_contents_);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Window::DevToolsWebContents(v8::Isolate* isolate) {
|
||||
if (devtools_web_contents_.IsEmpty())
|
||||
return v8::Null(isolate);
|
||||
else
|
||||
return v8::Local<v8::Value>::New(isolate, devtools_web_contents_);
|
||||
}
|
||||
|
||||
// static
|
||||
void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Handle<v8::ObjectTemplate> prototype) {
|
||||
v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("destroy", &Window::Destroy)
|
||||
.SetMethod("close", &Window::Close)
|
||||
.SetMethod("isClosed", &Window::IsClosed)
|
||||
.SetMethod("focus", &Window::Focus)
|
||||
.SetMethod("isFocused", &Window::IsFocused)
|
||||
.SetMethod("show", &Window::Show)
|
||||
.SetMethod("showInactive", &Window::ShowInactive)
|
||||
.SetMethod("hide", &Window::Hide)
|
||||
.SetMethod("isVisible", &Window::IsVisible)
|
||||
.SetMethod("maximize", &Window::Maximize)
|
||||
.SetMethod("unmaximize", &Window::Unmaximize)
|
||||
.SetMethod("isMaximized", &Window::IsMaximized)
|
||||
.SetMethod("minimize", &Window::Minimize)
|
||||
.SetMethod("restore", &Window::Restore)
|
||||
.SetMethod("setFullScreen", &Window::SetFullscreen)
|
||||
.SetMethod("isMinimized", &Window::IsMinimized)
|
||||
.SetMethod("setFullScreen", &Window::SetFullScreen)
|
||||
.SetMethod("isFullScreen", &Window::IsFullscreen)
|
||||
.SetMethod("getBounds", &Window::GetBounds)
|
||||
.SetMethod("setBounds", &Window::SetBounds)
|
||||
.SetMethod("getSize", &Window::GetSize)
|
||||
.SetMethod("setSize", &Window::SetSize)
|
||||
.SetMethod("getContentSize", &Window::GetContentSize)
|
||||
@@ -360,19 +530,35 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setTitle", &Window::SetTitle)
|
||||
.SetMethod("getTitle", &Window::GetTitle)
|
||||
.SetMethod("flashFrame", &Window::FlashFrame)
|
||||
.SetMethod("setSkipTaskbar", &Window::SetSkipTaskbar)
|
||||
.SetMethod("setKiosk", &Window::SetKiosk)
|
||||
.SetMethod("isKiosk", &Window::IsKiosk)
|
||||
.SetMethod("openDevTools", &Window::OpenDevTools)
|
||||
.SetMethod("closeDevTools", &Window::CloseDevTools)
|
||||
.SetMethod("isDevToolsOpened", &Window::IsDevToolsOpened)
|
||||
.SetMethod("inspectElement", &Window::InspectElement)
|
||||
.SetMethod("debugDevTools", &Window::DebugDevTools)
|
||||
.SetMethod("setRepresentedFilename", &Window::SetRepresentedFilename)
|
||||
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
|
||||
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
|
||||
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
|
||||
.SetMethod("focusOnWebView", &Window::FocusOnWebView)
|
||||
.SetMethod("blurWebView", &Window::BlurWebView)
|
||||
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
|
||||
.SetMethod("capturePage", &Window::CapturePage)
|
||||
.SetMethod("_getWebContents", &Window::GetWebContents)
|
||||
.SetMethod("_getDevToolsWebContents", &Window::GetDevToolsWebContents);
|
||||
.SetMethod("print", &Window::Print)
|
||||
.SetMethod("setProgressBar", &Window::SetProgressBar)
|
||||
.SetMethod("setOverlayIcon", &Window::SetOverlayIcon)
|
||||
.SetMethod("_setMenu", &Window::SetMenu)
|
||||
.SetMethod("setAutoHideMenuBar", &Window::SetAutoHideMenuBar)
|
||||
.SetMethod("isMenuBarAutoHide", &Window::IsMenuBarAutoHide)
|
||||
.SetMethod("setMenuBarVisibility", &Window::SetMenuBarVisibility)
|
||||
.SetMethod("isMenuBarVisible", &Window::IsMenuBarVisible)
|
||||
.SetMethod("setVisibleOnAllWorkspaces",
|
||||
&Window::SetVisibleOnAllWorkspaces)
|
||||
.SetMethod("isVisibleOnAllWorkspaces",
|
||||
&Window::IsVisibleOnAllWorkspaces)
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("showDefinitionForSelection",
|
||||
&Window::ShowDefinitionForSelection)
|
||||
#endif
|
||||
.SetProperty("webContents", &Window::WebContents)
|
||||
.SetProperty("devToolsWebContents", &Window::DevToolsWebContents);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
@@ -382,14 +568,16 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Handle<v8::Object> exports) {
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
using atom::api::Window;
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::Local<v8::Function> constructor = mate::CreateConstructor<Window>(
|
||||
node_isolate, "BrowserWindow", base::Bind(&Window::New));
|
||||
mate::Dictionary dict(v8::Isolate::GetCurrent(), exports);
|
||||
dict.Set("BrowserWindow", static_cast<v8::Handle<v8::Value>>(constructor));
|
||||
isolate, "BrowserWindow", base::Bind(&Window::New));
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("BrowserWindow", static_cast<v8::Local<v8::Value>>(constructor));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE(atom_browser_window, Initialize)
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_window, Initialize)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -9,14 +9,15 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "atom/browser/native_window_observer.h"
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
class GURL;
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
namespace gfx {
|
||||
class Rect;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
@@ -24,6 +25,10 @@ class Arguments;
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace ui {
|
||||
class SimpleMenuModel;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class NativeWindow;
|
||||
@@ -35,42 +40,68 @@ class WebContents;
|
||||
class Window : public mate::EventEmitter,
|
||||
public NativeWindowObserver {
|
||||
public:
|
||||
static mate::Wrappable* New(mate::Arguments* args,
|
||||
const base::DictionaryValue& options);
|
||||
static mate::Wrappable* New(v8::Isolate* isolate,
|
||||
const mate::Dictionary& options);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Handle<v8::ObjectTemplate> prototype);
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
NativeWindow* window() const { return window_.get(); }
|
||||
|
||||
protected:
|
||||
explicit Window(base::DictionaryValue* options);
|
||||
explicit Window(const mate::Dictionary& options);
|
||||
virtual ~Window();
|
||||
|
||||
// Implementations of NativeWindowObserver:
|
||||
virtual void OnPageTitleUpdated(bool* prevent_default,
|
||||
const std::string& title) OVERRIDE;
|
||||
virtual void WillCloseWindow(bool* prevent_default) OVERRIDE;
|
||||
virtual void OnWindowClosed() OVERRIDE;
|
||||
virtual void OnWindowBlur() OVERRIDE;
|
||||
virtual void OnRendererUnresponsive() OVERRIDE;
|
||||
virtual void OnRendererResponsive() OVERRIDE;
|
||||
// NativeWindowObserver:
|
||||
void OnPageTitleUpdated(bool* prevent_default,
|
||||
const std::string& title) override;
|
||||
void WillCreatePopupWindow(const base::string16& frame_name,
|
||||
const GURL& target_url,
|
||||
const std::string& partition_id,
|
||||
WindowOpenDisposition disposition) override;
|
||||
void WillNavigate(bool* prevent_default, const GURL& url) override;
|
||||
void WillCloseWindow(bool* prevent_default) override;
|
||||
void OnWindowClosed() override;
|
||||
void OnWindowBlur() override;
|
||||
void OnWindowFocus() override;
|
||||
void OnWindowMaximize() override;
|
||||
void OnWindowUnmaximize() override;
|
||||
void OnWindowMinimize() override;
|
||||
void OnWindowRestore() override;
|
||||
void OnWindowResize() override;
|
||||
void OnWindowMove() override;
|
||||
void OnWindowMoved() override;
|
||||
void OnWindowEnterFullScreen() override;
|
||||
void OnWindowLeaveFullScreen() override;
|
||||
void OnWindowEnterHtmlFullScreen() override;
|
||||
void OnWindowLeaveHtmlFullScreen() override;
|
||||
void OnRendererUnresponsive() override;
|
||||
void OnRendererResponsive() override;
|
||||
void OnDevToolsFocus() override;
|
||||
void OnDevToolsOpened() override;
|
||||
void OnDevToolsClosed() override;
|
||||
|
||||
private:
|
||||
// APIs for NativeWindow.
|
||||
void Destroy();
|
||||
void Close();
|
||||
bool IsClosed();
|
||||
void Focus();
|
||||
bool IsFocused();
|
||||
void Show();
|
||||
void ShowInactive();
|
||||
void Hide();
|
||||
bool IsVisible();
|
||||
void Maximize();
|
||||
void Unmaximize();
|
||||
bool IsMaximized();
|
||||
void Minimize();
|
||||
void Restore();
|
||||
void SetFullscreen(bool fullscreen);
|
||||
bool IsMinimized();
|
||||
void SetFullScreen(bool fullscreen);
|
||||
bool IsFullscreen();
|
||||
void SetBounds(const gfx::Rect& bounds);
|
||||
gfx::Rect GetBounds();
|
||||
void SetSize(int width, int height);
|
||||
std::vector<int> GetSize();
|
||||
void SetContentSize(int width, int height);
|
||||
@@ -89,21 +120,39 @@ class Window : public mate::EventEmitter,
|
||||
void SetTitle(const std::string& title);
|
||||
std::string GetTitle();
|
||||
void FlashFrame(bool flash);
|
||||
void SetSkipTaskbar(bool skip);
|
||||
void SetKiosk(bool kiosk);
|
||||
bool IsKiosk();
|
||||
void OpenDevTools();
|
||||
void CloseDevTools();
|
||||
bool IsDevToolsOpened();
|
||||
void InspectElement(int x, int y);
|
||||
void DebugDevTools();
|
||||
void FocusOnWebView();
|
||||
void BlurWebView();
|
||||
bool IsWebViewFocused();
|
||||
void SetRepresentedFilename(const std::string& filename);
|
||||
std::string GetRepresentedFilename();
|
||||
void SetDocumentEdited(bool edited);
|
||||
bool IsDocumentEdited();
|
||||
void CapturePage(mate::Arguments* args);
|
||||
void Print(mate::Arguments* args);
|
||||
void SetProgressBar(double progress);
|
||||
void SetOverlayIcon(const gfx::Image& overlay,
|
||||
const std::string& description);
|
||||
void SetMenu(ui::SimpleMenuModel* menu);
|
||||
void SetAutoHideMenuBar(bool auto_hide);
|
||||
bool IsMenuBarAutoHide();
|
||||
void SetMenuBarVisibility(bool visible);
|
||||
bool IsMenuBarVisible();
|
||||
|
||||
// APIs for WebContents.
|
||||
mate::Handle<WebContents> GetWebContents(v8::Isolate* isolate) const;
|
||||
mate::Handle<WebContents> GetDevToolsWebContents(v8::Isolate* isolate) const;
|
||||
#if defined(OS_MACOSX)
|
||||
void ShowDefinitionForSelection();
|
||||
#endif
|
||||
|
||||
void SetVisibleOnAllWorkspaces(bool visible);
|
||||
bool IsVisibleOnAllWorkspaces();
|
||||
|
||||
v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate);
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
v8::Global<v8::Value> devtools_web_contents_;
|
||||
|
||||
scoped_ptr<NativeWindow> window_;
|
||||
|
||||
@@ -119,7 +168,7 @@ namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<atom::NativeWindow*> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
atom::NativeWindow** out) {
|
||||
// null would be tranfered to NULL.
|
||||
if (val->IsNull()) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -11,19 +11,29 @@
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace {
|
||||
|
||||
v8::Persistent<v8::ObjectTemplate> template_;
|
||||
|
||||
} // namespace
|
||||
|
||||
Event::Event()
|
||||
: sender_(NULL),
|
||||
message_(NULL),
|
||||
prevent_default_(false) {
|
||||
message_(NULL) {
|
||||
}
|
||||
|
||||
Event::~Event() {
|
||||
}
|
||||
|
||||
ObjectTemplateBuilder Event::GetObjectTemplateBuilder(v8::Isolate* isolate) {
|
||||
return ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("preventDefault", &Event::PreventDefault)
|
||||
.SetMethod("sendReply", &Event::SendReply);
|
||||
if (template_.IsEmpty())
|
||||
template_.Reset(isolate, ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("preventDefault", &Event::PreventDefault)
|
||||
.SetMethod("sendReply", &Event::SendReply)
|
||||
.Build());
|
||||
|
||||
return ObjectTemplateBuilder(
|
||||
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
|
||||
}
|
||||
|
||||
void Event::SetSenderAndMessage(content::WebContents* sender,
|
||||
@@ -36,16 +46,17 @@ void Event::SetSenderAndMessage(content::WebContents* sender,
|
||||
Observe(sender);
|
||||
}
|
||||
|
||||
void Event::WebContentsDestroyed(content::WebContents* web_contents) {
|
||||
void Event::WebContentsDestroyed() {
|
||||
sender_ = NULL;
|
||||
message_ = NULL;
|
||||
}
|
||||
|
||||
void Event::PreventDefault() {
|
||||
prevent_default_ = true;
|
||||
void Event::PreventDefault(v8::Isolate* isolate) {
|
||||
GetWrapper(isolate)->Set(StringToV8(isolate, "defaultPrevented"),
|
||||
v8::True(isolate));
|
||||
}
|
||||
|
||||
bool Event::SendReply(const string16& json) {
|
||||
bool Event::SendReply(const base::string16& json) {
|
||||
if (message_ == NULL || sender_ == NULL)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -24,31 +24,26 @@ class Event : public Wrappable,
|
||||
void SetSenderAndMessage(content::WebContents* sender, IPC::Message* message);
|
||||
|
||||
// event.PreventDefault().
|
||||
void PreventDefault();
|
||||
void PreventDefault(v8::Isolate* isolate);
|
||||
|
||||
// event.sendReply(json), used for replying synchronous message.
|
||||
bool SendReply(const string16& json);
|
||||
|
||||
// Whether event.preventDefault() is called.
|
||||
bool prevent_default() const { return prevent_default_; }
|
||||
bool SendReply(const base::string16& json);
|
||||
|
||||
protected:
|
||||
Event();
|
||||
virtual ~Event();
|
||||
|
||||
// Wrappable implementations:
|
||||
virtual ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate);
|
||||
ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) override;
|
||||
|
||||
// content::WebContentsObserver implementations:
|
||||
virtual void WebContentsDestroyed(content::WebContents*) OVERRIDE;
|
||||
void WebContentsDestroyed() override;
|
||||
|
||||
private:
|
||||
// Replyer for the synchronous messages.
|
||||
content::WebContents* sender_;
|
||||
IPC::Message* message_;
|
||||
|
||||
bool prevent_default_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Event);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,62 +1,68 @@
|
||||
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event.h"
|
||||
#include "atom/common/native_mate_converters/v8_value_converter.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/values.h"
|
||||
#include "native_mate/arguments.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace {
|
||||
|
||||
v8::Persistent<v8::ObjectTemplate> event_template;
|
||||
|
||||
void PreventDefault(mate::Arguments* args) {
|
||||
args->GetThis()->Set(StringToV8(args->isolate(), "defaultPrevented"),
|
||||
v8::True(args->isolate()));
|
||||
}
|
||||
|
||||
// Create a pure JavaScript Event object.
|
||||
v8::Local<v8::Object> CreateEventObject(v8::Isolate* isolate) {
|
||||
if (event_template.IsEmpty()) {
|
||||
event_template.Reset(isolate, ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("preventDefault", &PreventDefault)
|
||||
.Build());
|
||||
}
|
||||
|
||||
return v8::Local<v8::ObjectTemplate>::New(
|
||||
isolate, event_template)->NewInstance();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
EventEmitter::EventEmitter() {
|
||||
}
|
||||
|
||||
bool EventEmitter::Emit(const base::StringPiece& name) {
|
||||
return Emit(name, base::ListValue());
|
||||
}
|
||||
bool EventEmitter::CallEmit(v8::Isolate* isolate,
|
||||
const base::StringPiece& name,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message,
|
||||
ValueArray args) {
|
||||
v8::Local<v8::Object> event;
|
||||
bool use_native_event = sender && message;
|
||||
|
||||
bool EventEmitter::Emit(const base::StringPiece& name,
|
||||
const base::ListValue& args) {
|
||||
return Emit(name, args, NULL, NULL);
|
||||
}
|
||||
|
||||
bool EventEmitter::Emit(const base::StringPiece& name,
|
||||
const base::ListValue& args,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message) {
|
||||
v8::Locker locker(node_isolate);
|
||||
v8::HandleScope handle_scope(node_isolate);
|
||||
|
||||
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
|
||||
scoped_ptr<atom::V8ValueConverter> converter(new atom::V8ValueConverter);
|
||||
|
||||
mate::Handle<mate::Event> event = mate::Event::Create(node_isolate);
|
||||
if (sender && message)
|
||||
event->SetSenderAndMessage(sender, message);
|
||||
|
||||
// v8_args = [name, event, args...];
|
||||
std::vector<v8::Handle<v8::Value>> v8_args;
|
||||
v8_args.reserve(args.GetSize() + 2);
|
||||
v8_args.push_back(mate::StringToV8(node_isolate, name));
|
||||
v8_args.push_back(event.ToV8());
|
||||
for (size_t i = 0; i < args.GetSize(); i++) {
|
||||
const base::Value* value(NULL);
|
||||
if (args.Get(i, &value))
|
||||
v8_args.push_back(converter->ToV8Value(value, context));
|
||||
if (use_native_event) {
|
||||
mate::Handle<mate::Event> native_event = mate::Event::Create(isolate);
|
||||
native_event->SetSenderAndMessage(sender, message);
|
||||
event = v8::Local<v8::Object>::Cast(native_event.ToV8());
|
||||
} else {
|
||||
event = CreateEventObject(isolate);
|
||||
}
|
||||
|
||||
// this.emit.apply(this, v8_args);
|
||||
node::MakeCallback(
|
||||
GetWrapper(node_isolate), "emit", v8_args.size(), &v8_args[0]);
|
||||
// args = [name, event, args...];
|
||||
args.insert(args.begin(), event);
|
||||
args.insert(args.begin(), mate::StringToV8(isolate, name));
|
||||
|
||||
return event->prevent_default();
|
||||
// this.emit.apply(this, args);
|
||||
node::MakeCallback(isolate, GetWrapper(isolate), "emit", args.size(),
|
||||
&args[0]);
|
||||
|
||||
return event->Get(StringToV8(isolate, "defaultPrevented"))->BooleanValue();
|
||||
}
|
||||
|
||||
} // namespace mate
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_EVENT_EMITTER_H_
|
||||
#define ATOM_BROWSER_API_EVENT_EMITTER_H_
|
||||
|
||||
#include "native_mate/wrappable.h"
|
||||
#include <vector>
|
||||
|
||||
namespace base {
|
||||
class ListValue;
|
||||
}
|
||||
#include "native_mate/wrappable.h"
|
||||
|
||||
namespace content {
|
||||
class WebContents;
|
||||
@@ -23,20 +21,40 @@ namespace mate {
|
||||
|
||||
// Provide helperers to emit event in JavaScript.
|
||||
class EventEmitter : public Wrappable {
|
||||
public:
|
||||
typedef std::vector<v8::Local<v8::Value>> ValueArray;
|
||||
|
||||
protected:
|
||||
EventEmitter();
|
||||
|
||||
// this.emit(name, new Event());
|
||||
bool Emit(const base::StringPiece& name);
|
||||
|
||||
// this.emit(name, new Event(), args...);
|
||||
bool Emit(const base::StringPiece& name, const base::ListValue& args);
|
||||
template<typename... Args>
|
||||
bool Emit(const base::StringPiece& name, const Args&... args) {
|
||||
return EmitWithSender(name, nullptr, nullptr, args...);
|
||||
}
|
||||
|
||||
// this.emit(name, new Event(sender, message), args...);
|
||||
bool Emit(const base::StringPiece& name, const base::ListValue& args,
|
||||
content::WebContents* sender, IPC::Message* message);
|
||||
template<typename... Args>
|
||||
bool EmitWithSender(const base::StringPiece& name,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message,
|
||||
const Args&... args) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
ValueArray converted = { ConvertToV8(isolate, args)... };
|
||||
return CallEmit(isolate, name, sender, message, converted);
|
||||
}
|
||||
|
||||
private:
|
||||
// Lower level implementations.
|
||||
bool CallEmit(v8::Isolate* isolate,
|
||||
const base::StringPiece& name,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message,
|
||||
ValueArray args);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(EventEmitter);
|
||||
};
|
||||
|
||||
|
||||
@@ -5,9 +5,6 @@ bindings = process.atomBinding 'app'
|
||||
app = bindings.app
|
||||
app.__proto__ = EventEmitter.prototype
|
||||
|
||||
app.getHomeDir = ->
|
||||
process.env[if process.platform is 'win32' then 'USERPROFILE' else 'HOME']
|
||||
|
||||
app.setApplicationMenu = (menu) ->
|
||||
require('menu').setApplicationMenu menu
|
||||
|
||||
@@ -24,11 +21,17 @@ if process.platform is 'darwin'
|
||||
cancelBounce: bindings.dockCancelBounce
|
||||
setBadge: bindings.dockSetBadgeText
|
||||
getBadge: bindings.dockGetBadgeText
|
||||
hide: bindings.dockHide
|
||||
show: bindings.dockShow
|
||||
setMenu: bindings.dockSetMenu
|
||||
|
||||
# Be compatible with old API.
|
||||
app.once 'ready', -> app.emit 'finish-launching'
|
||||
app.terminate = app.quit
|
||||
app.exit = process.exit
|
||||
app.getHomeDir = -> app.getPath 'home'
|
||||
app.getDataPath = -> app.getPath 'userData'
|
||||
app.setDataPath = (path) -> app.setPath 'userData', path
|
||||
|
||||
# Only one App object pemitted.
|
||||
module.exports = app
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
IDWeakMap = require 'id-weak-map'
|
||||
app = require 'app'
|
||||
wrapWebContents = require('web-contents').wrap
|
||||
ipc = require 'ipc'
|
||||
|
||||
BrowserWindow = process.atomBinding('window').BrowserWindow
|
||||
BrowserWindow::__proto__ = EventEmitter.prototype
|
||||
@@ -15,50 +15,31 @@ BrowserWindow::_init = ->
|
||||
menu = app.getApplicationMenu()
|
||||
@setMenu menu if menu?
|
||||
|
||||
@webContents = @getWebContents()
|
||||
@webContents.once 'destroyed', => @webContents = null
|
||||
# Remember the window ID.
|
||||
Object.defineProperty this, 'id',
|
||||
value: BrowserWindow.windows.add(this)
|
||||
enumerable: true
|
||||
|
||||
# Define getter for devToolsWebContents.
|
||||
devToolsWebContents = null
|
||||
@__defineGetter__ 'devToolsWebContents', ->
|
||||
if @isDevToolsOpened()
|
||||
# Get a new devToolsWebContents if previous one has been destroyed, it
|
||||
# could happen when the devtools has been closed and then reopened.
|
||||
devToolsWebContents = null unless devToolsWebContents?.isAlive()
|
||||
devToolsWebContents ?= @getDevToolsWebContents()
|
||||
else
|
||||
devToolsWebContents = null
|
||||
# Make new windows requested by links behave like "window.open"
|
||||
@on '-new-window', (event, url, frameName) =>
|
||||
event.sender = @webContents
|
||||
options = show: true, width: 800, height: 600
|
||||
ipc.emit 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, options
|
||||
|
||||
# Remember the window.
|
||||
id = BrowserWindow.windows.add this
|
||||
# Redirect "will-navigate" to webContents.
|
||||
@on '-will-navigate', (event, url) =>
|
||||
@webContents.emit 'will-navigate', event, url
|
||||
|
||||
# Remove the window from weak map immediately when it's destroyed, since we
|
||||
# could be iterating windows before GC happened.
|
||||
@once 'closed', ->
|
||||
BrowserWindow.windows.remove id if BrowserWindow.windows.has id
|
||||
|
||||
# Tell the rpc server that a render view has been deleted and we need to
|
||||
# release all objects owned by it.
|
||||
@webContents.on 'render-view-deleted', (event, processId, routingId) ->
|
||||
process.emit 'ATOM_BROWSER_RELEASE_RENDER_VIEW', "#{processId}-#{routingId}"
|
||||
|
||||
BrowserWindow::toggleDevTools = ->
|
||||
if @isDevToolsOpened() then @closeDevTools() else @openDevTools()
|
||||
|
||||
BrowserWindow::getWebContents = ->
|
||||
wrapWebContents @_getWebContents()
|
||||
|
||||
BrowserWindow::getDevToolsWebContents = ->
|
||||
wrapWebContents @_getDevToolsWebContents()
|
||||
@once 'closed', =>
|
||||
BrowserWindow.windows.remove @id if BrowserWindow.windows.has @id
|
||||
|
||||
BrowserWindow::setMenu = (menu) ->
|
||||
if process.platform is 'darwin'
|
||||
throw new Error('BrowserWindow.setMenu is not available on OS X')
|
||||
|
||||
throw new TypeError('Invalid menu') unless menu?.constructor?.name is 'Menu'
|
||||
throw new TypeError('Invalid menu') unless menu is null or menu?.constructor?.name is 'Menu'
|
||||
|
||||
@menu = menu # Keep a reference of menu in case of GC.
|
||||
@menu.attachToWindow this
|
||||
@_setMenu menu
|
||||
|
||||
BrowserWindow.getAllWindows = ->
|
||||
windows = BrowserWindow.windows
|
||||
@@ -70,11 +51,14 @@ BrowserWindow.getFocusedWindow = ->
|
||||
|
||||
BrowserWindow.fromWebContents = (webContents) ->
|
||||
windows = BrowserWindow.getAllWindows()
|
||||
return window for window in windows when webContents.equal window.webContents
|
||||
return window for window in windows when window.webContents?.equal webContents
|
||||
|
||||
BrowserWindow.fromDevToolsWebContents = (webContents) ->
|
||||
windows = BrowserWindow.getAllWindows()
|
||||
return window for window in windows when webContents.equal window.devToolsWebContents
|
||||
return window for window in windows when window.devToolsWebContents?.equal webContents
|
||||
|
||||
BrowserWindow.fromId = (id) ->
|
||||
BrowserWindow.windows.get id
|
||||
|
||||
# Helpers.
|
||||
BrowserWindow::loadUrl = -> @webContents.loadUrl.apply @webContents, arguments
|
||||
@@ -83,8 +67,8 @@ BrowserWindow::send = -> @webContents.send.apply @webContents, arguments
|
||||
# Be compatible with old API.
|
||||
BrowserWindow::restart = -> @webContents.reload()
|
||||
BrowserWindow::getUrl = -> @webContents.getUrl()
|
||||
BrowserWindow::reload = -> @webContents.reload()
|
||||
BrowserWindow::reloadIgnoringCache = -> @webContents.reloadIgnoringCache()
|
||||
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()
|
||||
@@ -92,7 +76,12 @@ BrowserWindow::stop = -> @webContents.stop()
|
||||
BrowserWindow::getRoutingId = -> @webContents.getRoutingId()
|
||||
BrowserWindow::getProcessId = -> @webContents.getProcessId()
|
||||
BrowserWindow::isCrashed = -> @webContents.isCrashed()
|
||||
BrowserWindow::executeJavaScriptInDevTools = (code) ->
|
||||
@devToolsWebContents.executeJavaScript code
|
||||
BrowserWindow::executeJavaScriptInDevTools = (code) -> @devToolsWebContents?.executeJavaScript code
|
||||
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()
|
||||
|
||||
module.exports = BrowserWindow
|
||||
|
||||
7
atom/browser/api/lib/content-tracing.coffee
Normal file
7
atom/browser/api/lib/content-tracing.coffee
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = process.atomBinding 'content_tracing'
|
||||
|
||||
# Mirrored from content::TracingController::Options
|
||||
module.exports.DEFAULT_OPTIONS = 0
|
||||
module.exports.ENABLE_SYSTRACE = 1 << 0
|
||||
module.exports.ENABLE_SAMPLING = 1 << 1
|
||||
module.exports.RECORD_CONTINUOUSLY = 1 << 2
|
||||
@@ -1,19 +1,35 @@
|
||||
binding = process.atomBinding 'dialog'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
app = require 'app'
|
||||
BrowserWindow = require 'browser-window'
|
||||
|
||||
fileDialogProperties =
|
||||
openFile: 1, openDirectory: 2, multiSelections: 4, createDirectory: 8
|
||||
openFile: 1 << 0
|
||||
openDirectory: 1 << 1
|
||||
multiSelections: 1 << 2
|
||||
createDirectory: 1 << 3
|
||||
|
||||
messageBoxTypes = ['none', 'info', 'warning']
|
||||
|
||||
parseArgs = (window, options, callback) ->
|
||||
unless window is null or window?.constructor is BrowserWindow
|
||||
# Shift.
|
||||
callback = options
|
||||
options = window
|
||||
window = null
|
||||
if not callback? and typeof options is 'function'
|
||||
# Shift.
|
||||
callback = options
|
||||
options = null
|
||||
[window, options, callback]
|
||||
|
||||
checkAppInitialized = ->
|
||||
throw new Error('dialog module can only be used after app is ready') unless app.isReady()
|
||||
|
||||
module.exports =
|
||||
showOpenDialog: (window, options, callback) ->
|
||||
unless window?.constructor is BrowserWindow
|
||||
# Shift.
|
||||
callback = options
|
||||
options = window
|
||||
window = null
|
||||
showOpenDialog: (args...) ->
|
||||
checkAppInitialized()
|
||||
[window, options, callback] = parseArgs args...
|
||||
|
||||
options ?= title: 'Open', properties: ['openFile']
|
||||
options.properties ?= ['openFile']
|
||||
@@ -25,54 +41,67 @@ module.exports =
|
||||
|
||||
options.title ?= ''
|
||||
options.defaultPath ?= ''
|
||||
options.filters ?= []
|
||||
|
||||
wrappedCallback =
|
||||
if typeof callback is 'function'
|
||||
(success, result) -> callback(if success then result)
|
||||
else
|
||||
null
|
||||
|
||||
binding.showOpenDialog String(options.title),
|
||||
String(options.defaultPath),
|
||||
options.filters
|
||||
properties,
|
||||
window,
|
||||
(success, result) -> callback if success then result
|
||||
wrappedCallback
|
||||
|
||||
showSaveDialog: (window, options, callback) ->
|
||||
unless window?.constructor is BrowserWindow
|
||||
# Shift.
|
||||
callback = options
|
||||
options = window
|
||||
window = null
|
||||
showSaveDialog: (args...) ->
|
||||
checkAppInitialized()
|
||||
[window, options, callback] = parseArgs args...
|
||||
|
||||
options ?= title: 'Save'
|
||||
options.title ?= ''
|
||||
options.defaultPath ?= ''
|
||||
options.filters ?= []
|
||||
|
||||
wrappedCallback =
|
||||
if typeof callback is 'function'
|
||||
(success, result) -> callback(if success then result)
|
||||
else
|
||||
null
|
||||
|
||||
binding.showSaveDialog String(options.title),
|
||||
String(options.defaultPath),
|
||||
options.filters
|
||||
window,
|
||||
(success, result) -> callback if success then result
|
||||
wrappedCallback
|
||||
|
||||
showMessageBox: (window, options, callback) ->
|
||||
unless window?.constructor is BrowserWindow
|
||||
# Shift.
|
||||
callback = options
|
||||
options = window
|
||||
window = null
|
||||
showMessageBox: (args...) ->
|
||||
checkAppInitialized()
|
||||
[window, options, callback] = parseArgs args...
|
||||
|
||||
options ?= type: 'none'
|
||||
options.type ?= 'none'
|
||||
options.type = messageBoxTypes.indexOf options.type
|
||||
throw new TypeError('Invalid message box type') unless options.type > -1
|
||||
messageBoxType = messageBoxTypes.indexOf options.type
|
||||
throw new TypeError('Invalid message box type') unless messageBoxType > -1
|
||||
|
||||
throw new TypeError('Buttons need to be array') unless Array.isArray options.buttons
|
||||
|
||||
options.title ?= ''
|
||||
options.message ?= ''
|
||||
options.detail ?= ''
|
||||
options.icon ?= null
|
||||
|
||||
binding.showMessageBox options.type,
|
||||
binding.showMessageBox messageBoxType,
|
||||
options.buttons,
|
||||
String(options.title),
|
||||
String(options.message),
|
||||
String(options.detail),
|
||||
[options.title, options.message, options.detail],
|
||||
options.icon,
|
||||
window,
|
||||
callback
|
||||
|
||||
showErrorBox: (args...) ->
|
||||
binding.showErrorBox args...
|
||||
|
||||
# Mark standard asynchronous functions.
|
||||
v8Util.setHiddenValue f, 'asynchronous', true for k, f of module.exports
|
||||
|
||||
5
atom/browser/api/lib/global-shortcut.coffee
Normal file
5
atom/browser/api/lib/global-shortcut.coffee
Normal file
@@ -0,0 +1,5 @@
|
||||
bindings = process.atomBinding 'global_shortcut'
|
||||
|
||||
globalShortcut = bindings.globalShortcut
|
||||
|
||||
module.exports = globalShortcut
|
||||
@@ -1,4 +1,5 @@
|
||||
BrowserWindow = require 'browser-window'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
|
||||
nextCommandId = 0
|
||||
|
||||
@@ -8,28 +9,41 @@ class MenuItem
|
||||
constructor: (options) ->
|
||||
Menu = require 'menu'
|
||||
|
||||
{click, @selector, @type, @label, @sublabel, @accelerator, @enabled, @visible, @checked, @groupId, @submenu} = options
|
||||
{click, @selector, @type, @label, @sublabel, @accelerator, @icon, @enabled, @visible, @checked, @submenu} = options
|
||||
|
||||
@type = 'submenu' if not @type? and @submenu?
|
||||
throw new Error('Invalid submenu') if @type is 'submenu' and @submenu?.constructor isnt Menu
|
||||
|
||||
@type = @type ? 'normal'
|
||||
@label = @label ? ''
|
||||
@sublabel = @sublabel ? ''
|
||||
@accelerator = @accelerator ? null
|
||||
@enabled = @enabled ? true
|
||||
@visible = @visible ? true
|
||||
@checked = @checked ? false
|
||||
@groupId = @groupId ? null
|
||||
@submenu = @submenu ? null
|
||||
@overrideReadOnlyProperty 'type', 'normal'
|
||||
@overrideReadOnlyProperty 'accelerator'
|
||||
@overrideReadOnlyProperty 'icon'
|
||||
@overrideReadOnlyProperty 'submenu'
|
||||
@overrideProperty 'label', ''
|
||||
@overrideProperty 'sublabel', ''
|
||||
@overrideProperty 'enabled', true
|
||||
@overrideProperty 'visible', true
|
||||
@overrideProperty 'checked', false
|
||||
|
||||
throw new Error('Unknown menu type') if MenuItem.types.indexOf(@type) is -1
|
||||
throw new Error("Unknown menu type #{@type}") if MenuItem.types.indexOf(@type) is -1
|
||||
|
||||
@commandId = ++nextCommandId
|
||||
@click = =>
|
||||
# Manually flip the checked flags when clicked.
|
||||
@checked = !@checked if @type in ['checkbox', 'radio']
|
||||
|
||||
if typeof click is 'function'
|
||||
click this, BrowserWindow.getFocusedWindow()
|
||||
else if typeof @selector is 'string'
|
||||
Menu.sendActionToFirstResponder @selector
|
||||
|
||||
overrideProperty: (name, defaultValue=null) ->
|
||||
this[name] ?= defaultValue
|
||||
|
||||
overrideReadOnlyProperty: (name, defaultValue=null) ->
|
||||
this[name] ?= defaultValue
|
||||
Object.defineProperty this, name,
|
||||
enumerable: true
|
||||
writable: false
|
||||
value: this[name]
|
||||
|
||||
module.exports = MenuItem
|
||||
|
||||
@@ -1,17 +1,88 @@
|
||||
BrowserWindow = require 'browser-window'
|
||||
EventEmitter = require('events').EventEmitter
|
||||
MenuItem = require 'menu-item'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
|
||||
bindings = process.atomBinding 'menu'
|
||||
|
||||
# Automatically generated radio menu item's group id.
|
||||
nextGroupId = 0
|
||||
|
||||
# Search between seperators to find a radio menu item and return its group id,
|
||||
# otherwise generate a group id.
|
||||
generateGroupId = (items, pos) ->
|
||||
if pos > 0
|
||||
for i in [pos - 1..0]
|
||||
item = items[i]
|
||||
return item.groupId if item.type is 'radio'
|
||||
break if item.type is 'separator'
|
||||
else if pos < items.length
|
||||
for i in [pos..items.length - 1]
|
||||
item = items[i]
|
||||
return item.groupId if item.type is 'radio'
|
||||
break if item.type is 'separator'
|
||||
++nextGroupId
|
||||
|
||||
# Returns the index of item according to |id|.
|
||||
indexOfItemById = (items, id) ->
|
||||
return i for item, i in items when item.id is id
|
||||
-1
|
||||
|
||||
# Returns the index of where to insert the item according to |position|.
|
||||
indexToInsertByPosition = (items, position) ->
|
||||
return items.length unless position
|
||||
|
||||
[query, id] = position.split '='
|
||||
insertIndex = indexOfItemById items, id
|
||||
if insertIndex is -1 and query isnt 'endof'
|
||||
console.warn "Item with id '#{id}' is not found"
|
||||
return items.length
|
||||
|
||||
switch query
|
||||
when 'after'
|
||||
insertIndex++
|
||||
when 'endof'
|
||||
# If the |id| doesn't exist, then create a new group with the |id|.
|
||||
if insertIndex is -1
|
||||
items.push id: id, type: 'separator'
|
||||
insertIndex = items.length - 1
|
||||
|
||||
# Find the end of the group.
|
||||
insertIndex++
|
||||
while insertIndex < items.length and items[insertIndex].type isnt 'separator'
|
||||
insertIndex++
|
||||
|
||||
insertIndex
|
||||
|
||||
Menu = bindings.Menu
|
||||
Menu::__proto__ = EventEmitter.prototype
|
||||
|
||||
popup = Menu::popup
|
||||
Menu::popup = (window) ->
|
||||
throw new TypeError('Invalid window') unless window?.constructor is BrowserWindow
|
||||
Menu::_init = ->
|
||||
@commandsMap = {}
|
||||
@groupsMap = {}
|
||||
@items = []
|
||||
@delegate =
|
||||
isCommandIdChecked: (commandId) => @commandsMap[commandId]?.checked
|
||||
isCommandIdEnabled: (commandId) => @commandsMap[commandId]?.enabled
|
||||
isCommandIdVisible: (commandId) => @commandsMap[commandId]?.visible
|
||||
getAcceleratorForCommandId: (commandId) => @commandsMap[commandId]?.accelerator
|
||||
getIconForCommandId: (commandId) => @commandsMap[commandId]?.icon
|
||||
executeCommand: (commandId) => @commandsMap[commandId]?.click()
|
||||
menuWillShow: =>
|
||||
# Make sure radio groups have at least one menu item seleted.
|
||||
for id, group of @groupsMap
|
||||
checked = false
|
||||
for radioItem in group when radioItem.checked
|
||||
checked = true
|
||||
break
|
||||
v8Util.setHiddenValue group[0], 'checked', true unless checked
|
||||
|
||||
popup.call this, window
|
||||
Menu::popup = (window, x, y) ->
|
||||
throw new TypeError('Invalid window') unless window?.constructor is BrowserWindow
|
||||
if x? and y?
|
||||
@_popupAt(window, x, y)
|
||||
else
|
||||
@_popup window
|
||||
|
||||
Menu::append = (item) ->
|
||||
@insert @getItemCount(), item
|
||||
@@ -22,32 +93,49 @@ Menu::insert = (pos, item) ->
|
||||
switch item.type
|
||||
when 'normal' then @insertItem pos, item.commandId, item.label
|
||||
when 'checkbox' then @insertCheckItem pos, item.commandId, item.label
|
||||
when 'radio' then @insertRadioItem pos, item.commandId, item.label, item.groupId
|
||||
when 'separator' then @insertSeparator pos
|
||||
when 'submenu' then @insertSubMenu pos, item.commandId, item.label, item.submenu
|
||||
when 'radio'
|
||||
# Grouping radio menu items.
|
||||
item.overrideReadOnlyProperty 'groupId', generateGroupId(@items, pos)
|
||||
@groupsMap[item.groupId] ?= []
|
||||
@groupsMap[item.groupId].push item
|
||||
|
||||
# Setting a radio menu item should flip other items in the group.
|
||||
v8Util.setHiddenValue item, 'checked', item.checked
|
||||
Object.defineProperty item, 'checked',
|
||||
enumerable: true
|
||||
get: -> v8Util.getHiddenValue item, 'checked'
|
||||
set: (val) =>
|
||||
for otherItem in @groupsMap[item.groupId] when otherItem isnt item
|
||||
v8Util.setHiddenValue otherItem, 'checked', false
|
||||
v8Util.setHiddenValue item, 'checked', true
|
||||
|
||||
@insertRadioItem pos, item.commandId, item.label, item.groupId
|
||||
|
||||
@setSublabel pos, item.sublabel if item.sublabel?
|
||||
@setIcon pos, item.icon if item.icon?
|
||||
|
||||
unless @delegate?
|
||||
@commandsMap = {}
|
||||
@items = []
|
||||
@delegate =
|
||||
isCommandIdChecked: (commandId) => @commandsMap[commandId]?.checked
|
||||
isCommandIdEnabled: (commandId) => @commandsMap[commandId]?.enabled
|
||||
isCommandIdVisible: (commandId) => @commandsMap[commandId]?.visible
|
||||
getAcceleratorForCommandId: (commandId) => @commandsMap[commandId]?.accelerator
|
||||
executeCommand: (commandId) =>
|
||||
activeItem = @commandsMap[commandId]
|
||||
activeItem.click() if activeItem?
|
||||
# Make menu accessable to items.
|
||||
item.overrideReadOnlyProperty 'menu', this
|
||||
|
||||
# Remember the items.
|
||||
@items.splice pos, 0, item
|
||||
@commandsMap[item.commandId] = item
|
||||
|
||||
# Force menuWillShow to be called
|
||||
Menu::_callMenuWillShow = ->
|
||||
@delegate?.menuWillShow()
|
||||
item.submenu._callMenuWillShow() for item in @items when item.submenu?
|
||||
|
||||
applicationMenu = null
|
||||
Menu.setApplicationMenu = (menu) ->
|
||||
throw new TypeError('Invalid menu') unless menu?.constructor is Menu
|
||||
throw new TypeError('Invalid menu') unless menu is null or menu.constructor is Menu
|
||||
applicationMenu = menu # Keep a reference.
|
||||
|
||||
if process.platform is 'darwin'
|
||||
return if menu is null
|
||||
menu._callMenuWillShow()
|
||||
bindings.setApplicationMenu menu
|
||||
else
|
||||
windows = BrowserWindow.getAllWindows()
|
||||
@@ -60,14 +148,25 @@ Menu.sendActionToFirstResponder = bindings.sendActionToFirstResponder
|
||||
Menu.buildFromTemplate = (template) ->
|
||||
throw new TypeError('Invalid template for Menu') unless Array.isArray template
|
||||
|
||||
menu = new Menu
|
||||
positionedTemplate = []
|
||||
insertIndex = 0
|
||||
|
||||
for item in template
|
||||
if item.position
|
||||
insertIndex = indexToInsertByPosition positionedTemplate, item.position
|
||||
else
|
||||
# If no |position| is specified, insert after last item.
|
||||
insertIndex++
|
||||
positionedTemplate.splice insertIndex, 0, item
|
||||
|
||||
menu = new Menu
|
||||
|
||||
for item in positionedTemplate
|
||||
throw new TypeError('Invalid template for MenuItem') unless typeof item is 'object'
|
||||
|
||||
item.submenu = Menu.buildFromTemplate item.submenu if item.submenu?
|
||||
menuItem = new MenuItem(item)
|
||||
menuItem[key] = value for key, value of item when not menuItem[key]?
|
||||
|
||||
menu.append menuItem
|
||||
|
||||
menu
|
||||
|
||||
116
atom/browser/api/lib/navigation-controller.coffee
Normal file
116
atom/browser/api/lib/navigation-controller.coffee
Normal file
@@ -0,0 +1,116 @@
|
||||
ipc = require 'ipc'
|
||||
|
||||
# The history operation in renderer is redirected to browser.
|
||||
ipc.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) ->
|
||||
event.sender[method] args...
|
||||
|
||||
ipc.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.
|
||||
# This helps us avoid Chromium's various optimizations so we can ensure renderer
|
||||
# process is restarted everytime.
|
||||
class NavigationController
|
||||
constructor: (@webContents) ->
|
||||
@clearHistory()
|
||||
|
||||
@webContents.on 'navigation-entry-commited', (event, url, inPage, replaceEntry) =>
|
||||
if @inPageIndex > -1 and not inPage
|
||||
# Navigated to a new page, clear in-page mark.
|
||||
@inPageIndex = -1
|
||||
else if @inPageIndex is -1 and inPage
|
||||
# Started in-page navigations.
|
||||
@inPageIndex = @currentIndex
|
||||
|
||||
if @pendingIndex >= 0 # Go to index.
|
||||
@currentIndex = @pendingIndex
|
||||
@pendingIndex = -1
|
||||
@history[@currentIndex] = url
|
||||
else if replaceEntry # Non-user initialized navigation.
|
||||
@history[@currentIndex] = url
|
||||
else # Normal navigation.
|
||||
@history = @history.slice 0, @currentIndex + 1 # Clear history.
|
||||
currentEntry = @history[@currentIndex]
|
||||
if currentEntry?.url isnt url
|
||||
@currentIndex++
|
||||
@history.push url
|
||||
|
||||
loadUrl: (url, options={}) ->
|
||||
@pendingIndex = -1
|
||||
@webContents._loadUrl url, options
|
||||
|
||||
getUrl: ->
|
||||
if @currentIndex is -1
|
||||
''
|
||||
else
|
||||
@history[@currentIndex]
|
||||
|
||||
stop: ->
|
||||
@pendingIndex = -1
|
||||
@webContents._stop()
|
||||
|
||||
reload: ->
|
||||
@pendingIndex = @currentIndex
|
||||
@webContents._loadUrl @getUrl(), {}
|
||||
|
||||
reloadIgnoringCache: ->
|
||||
@webContents._reloadIgnoringCache() # Rely on WebContents to clear cache.
|
||||
@reload()
|
||||
|
||||
canGoBack: ->
|
||||
@getActiveIndex() > 0
|
||||
|
||||
canGoForward: ->
|
||||
@getActiveIndex() < @history.length - 1
|
||||
|
||||
canGoToIndex: (index) ->
|
||||
index >=0 and index < @history.length
|
||||
|
||||
canGoToOffset: (offset) ->
|
||||
@canGoToIndex @currentIndex + offset
|
||||
|
||||
clearHistory: ->
|
||||
@history = []
|
||||
@currentIndex = -1
|
||||
@pendingIndex = -1
|
||||
@inPageIndex = -1
|
||||
|
||||
goBack: ->
|
||||
return unless @canGoBack()
|
||||
@pendingIndex = @getActiveIndex() - 1
|
||||
if @inPageIndex > -1 and @pendingIndex >= @inPageIndex
|
||||
@webContents._goBack()
|
||||
else
|
||||
@webContents._loadUrl @history[@pendingIndex], {}
|
||||
|
||||
goForward: ->
|
||||
return unless @canGoForward()
|
||||
@pendingIndex = @getActiveIndex() + 1
|
||||
if @inPageIndex > -1 and @pendingIndex >= @inPageIndex
|
||||
@webContents._goForward()
|
||||
else
|
||||
@webContents._loadUrl @history[@pendingIndex], {}
|
||||
|
||||
goToIndex: (index) ->
|
||||
return unless @canGoToIndex index
|
||||
@pendingIndex = index
|
||||
@webContents._loadUrl @history[@pendingIndex], {}
|
||||
|
||||
goToOffset: (offset) ->
|
||||
return unless @canGoToOffset offset
|
||||
pendingIndex = @currentIndex + offset
|
||||
if @inPageIndex > -1 and pendingIndex >= @inPageIndex
|
||||
@pendingIndex = pendingIndex
|
||||
@webContents._goToOffset offset
|
||||
else
|
||||
@goToIndex pendingIndex
|
||||
|
||||
getActiveIndex: ->
|
||||
if @pendingIndex is -1 then @currentIndex else @pendingIndex
|
||||
|
||||
length: ->
|
||||
@history.length
|
||||
|
||||
module.exports = NavigationController
|
||||
@@ -1,3 +1,6 @@
|
||||
app = require 'app'
|
||||
throw new Error('Can not initialize protocol module before app is ready') unless app.isReady()
|
||||
|
||||
protocol = process.atomBinding('protocol').protocol
|
||||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
@@ -13,8 +16,22 @@ class RequestStringJob
|
||||
@charset = charset ? 'UTF-8'
|
||||
@data = String data
|
||||
|
||||
protocol.RequestBufferJob =
|
||||
class RequestBufferJob
|
||||
constructor: ({mimeType, encoding, data}) ->
|
||||
if not data instanceof Buffer
|
||||
throw new TypeError('Data should be Buffer')
|
||||
|
||||
@mimeType = mimeType ? 'application/octet-stream'
|
||||
@encoding = encoding ? 'utf8'
|
||||
@data = new Buffer(data)
|
||||
|
||||
protocol.RequestFileJob =
|
||||
class RequestFileJob
|
||||
constructor: (@path) ->
|
||||
|
||||
protocol.RequestErrorJob =
|
||||
class RequestErrorJob
|
||||
constructor: (@error) ->
|
||||
|
||||
module.exports = protocol
|
||||
|
||||
6
atom/browser/api/lib/screen.coffee
Normal file
6
atom/browser/api/lib/screen.coffee
Normal file
@@ -0,0 +1,6 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
screen = process.atomBinding('screen').screen
|
||||
screen.__proto__ = EventEmitter.prototype
|
||||
|
||||
module.exports = screen
|
||||
10
atom/browser/api/lib/tray.coffee
Normal file
10
atom/browser/api/lib/tray.coffee
Normal file
@@ -0,0 +1,10 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
bindings = process.atomBinding 'tray'
|
||||
|
||||
Tray = bindings.Tray
|
||||
Tray::__proto__ = EventEmitter.prototype
|
||||
Tray::setContextMenu = (menu) ->
|
||||
@_setContextMenu menu
|
||||
@menu = menu # Keep a strong reference of menu.
|
||||
|
||||
module.exports = Tray
|
||||
@@ -1,27 +1,67 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
NavigationController = require './navigation-controller'
|
||||
binding = process.atomBinding 'web_contents'
|
||||
ipc = require 'ipc'
|
||||
|
||||
module.exports.wrap = (webContents) ->
|
||||
return null unless webContents.isAlive()
|
||||
|
||||
wrapWebContents = (webContents) ->
|
||||
# webContents is an EventEmitter.
|
||||
webContents.__proto__ = EventEmitter.prototype
|
||||
|
||||
# WebContents::send(channel, args..)
|
||||
webContents.send = (args...) ->
|
||||
@_send 'ATOM_INTERNAL_MESSAGE', [args...]
|
||||
webContents.send = (channel, args...) ->
|
||||
@_send channel, [args...]
|
||||
|
||||
# Make sure webContents.executeJavaScript would run the code only when the
|
||||
# web contents has been loaded.
|
||||
webContents.loaded = false
|
||||
webContents.once 'did-finish-load', -> @loaded = true
|
||||
webContents.executeJavaScript = (code) ->
|
||||
if @loaded
|
||||
@_executeJavaScript code
|
||||
else
|
||||
webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code)
|
||||
|
||||
# The processId and routingId and identify a webContents.
|
||||
webContents.getId = -> "#{@getProcessId()}-#{@getRoutingId()}"
|
||||
webContents.equal = (other) -> @getId() is other.getId()
|
||||
|
||||
# The navigation controller.
|
||||
controller = new NavigationController(webContents)
|
||||
for name, method of NavigationController.prototype when method instanceof Function
|
||||
do (name, method) ->
|
||||
webContents[name] = -> method.apply controller, arguments
|
||||
|
||||
# Translate |disposition| to string for 'new-window' event.
|
||||
webContents.on '-new-window', (args..., disposition) ->
|
||||
disposition =
|
||||
switch disposition
|
||||
when 2 then 'default'
|
||||
when 4 then 'foreground-tab'
|
||||
when 5 then 'background-tab'
|
||||
when 6, 7 then 'new-window'
|
||||
else 'other'
|
||||
@emit 'new-window', args..., disposition
|
||||
|
||||
# Tell the rpc server that a render view has been deleted and we need to
|
||||
# release all objects owned by it.
|
||||
webContents.on 'render-view-deleted', (event, processId, routingId) ->
|
||||
process.emit 'ATOM_BROWSER_RELEASE_RENDER_VIEW', "#{processId}-#{routingId}"
|
||||
|
||||
# Dispatch IPC messages to the ipc module.
|
||||
webContents.on 'ipc-message', (event, channel, args...) =>
|
||||
webContents.on 'ipc-message', (event, packed) ->
|
||||
[channel, args...] = packed
|
||||
Object.defineProperty event, 'sender', value: webContents
|
||||
ipc.emit channel, event, args...
|
||||
webContents.on 'ipc-message-sync', (event, channel, args...) =>
|
||||
webContents.on 'ipc-message-sync', (event, packed) ->
|
||||
[channel, args...] = packed
|
||||
Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value)
|
||||
Object.defineProperty event, 'sender', value: webContents
|
||||
ipc.emit channel, event, args...
|
||||
|
||||
webContents
|
||||
|
||||
binding._setWrapWebContents wrapWebContents
|
||||
process.once 'exit', binding._clearWrapWebContents
|
||||
|
||||
module.exports.create = (options={}) ->
|
||||
binding.create(options)
|
||||
|
||||
50
atom/browser/atom_access_token_store.cc
Normal file
50
atom/browser/atom_access_token_store.cc
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/atom_access_token_store.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/common/google_api_key.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
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 =
|
||||
"https://www.googleapis.com/geolocation/v1/geolocate?key="
|
||||
GOOGLEAPIS_API_KEY;
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomAccessTokenStore::AtomAccessTokenStore() {
|
||||
}
|
||||
|
||||
AtomAccessTokenStore::~AtomAccessTokenStore() {
|
||||
}
|
||||
|
||||
void AtomAccessTokenStore::LoadAccessTokens(
|
||||
const LoadAccessTokensCallbackType& callback) {
|
||||
AccessTokenSet access_token_set;
|
||||
|
||||
// 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);
|
||||
access_token_set.insert(token_pair);
|
||||
|
||||
callback.Run(access_token_set,
|
||||
AtomBrowserContext::Get()->url_request_context_getter());
|
||||
}
|
||||
|
||||
void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url,
|
||||
const base::string16& access_token) {
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
31
atom/browser/atom_access_token_store.h
Normal file
31
atom/browser/atom_access_token_store.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_ATOM_ACCESS_TOKEN_STORE_H_
|
||||
#define ATOM_BROWSER_ATOM_ACCESS_TOKEN_STORE_H_
|
||||
|
||||
#include "content/public/browser/access_token_store.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserContext;
|
||||
|
||||
class AtomAccessTokenStore : public content::AccessTokenStore {
|
||||
public:
|
||||
AtomAccessTokenStore();
|
||||
virtual ~AtomAccessTokenStore();
|
||||
|
||||
// content::AccessTokenStore:
|
||||
void LoadAccessTokens(
|
||||
const LoadAccessTokensCallbackType& callback) override;
|
||||
void SaveAccessToken(const GURL& server_url,
|
||||
const base::string16& access_token) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomAccessTokenStore);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_ACCESS_TOKEN_STORE_H_
|
||||
@@ -1,61 +1,128 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// 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/atom_browser_client.h"
|
||||
|
||||
#include "atom/browser/atom_access_token_store.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_quota_permission_context.h"
|
||||
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/net/atom_url_request_context_getter.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "chrome/browser/printing/printing_message_filter.h"
|
||||
#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
|
||||
#include "chrome/browser/speech/tts_message_filter.h"
|
||||
#include "content/public/browser/browser_ppapi_host.h"
|
||||
#include "content/public/browser/client_certificate_delegate.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/site_instance.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "webkit/common/webpreferences.h"
|
||||
#include "content/public/common/web_preferences.h"
|
||||
#include "net/cert/x509_certificate.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
struct FindByProcessId {
|
||||
explicit FindByProcessId(int child_process_id)
|
||||
: child_process_id_(child_process_id) {
|
||||
}
|
||||
// The default routing id of WebContents.
|
||||
// In Electron each RenderProcessHost only has one WebContents, so this ID is
|
||||
// same for every WebContents.
|
||||
int kDefaultRoutingID = 2;
|
||||
|
||||
bool operator() (NativeWindow* const window) {
|
||||
int id = window->GetWebContents()->GetRenderProcessHost()->GetID();
|
||||
return id == child_process_id_;
|
||||
}
|
||||
// Next navigation should not restart renderer process.
|
||||
bool g_suppress_renderer_process_restart = false;
|
||||
|
||||
int child_process_id_;
|
||||
// Find out the owner of the child process according to |process_id|.
|
||||
enum ProcessOwner {
|
||||
OWNER_NATIVE_WINDOW,
|
||||
OWNER_GUEST_WEB_CONTENTS,
|
||||
OWNER_NONE, // it might be devtools though.
|
||||
};
|
||||
ProcessOwner GetProcessOwner(int process_id,
|
||||
NativeWindow** window,
|
||||
WebViewManager::WebViewInfo* info) {
|
||||
auto web_contents = content::WebContents::FromRenderViewHost(
|
||||
content::RenderViewHost::FromID(process_id, kDefaultRoutingID));
|
||||
if (!web_contents)
|
||||
return OWNER_NONE;
|
||||
|
||||
// First search for NativeWindow.
|
||||
for (auto native_window : *WindowList::GetInstance())
|
||||
if (web_contents == native_window->GetWebContents()) {
|
||||
*window = native_window;
|
||||
return OWNER_NATIVE_WINDOW;
|
||||
}
|
||||
|
||||
// Then search for guest WebContents.
|
||||
if (WebViewManager::GetInfoForWebContents(web_contents, info))
|
||||
return OWNER_GUEST_WEB_CONTENTS;
|
||||
|
||||
return OWNER_NONE;
|
||||
}
|
||||
|
||||
scoped_refptr<net::X509Certificate> ImportCertFromFile(
|
||||
const base::FilePath& path) {
|
||||
std::string cert_data;
|
||||
if (!base::ReadFileToString(path, &cert_data))
|
||||
return nullptr;
|
||||
|
||||
net::CertificateList certs =
|
||||
net::X509Certificate::CreateCertificateListFromBytes(
|
||||
cert_data.data(), cert_data.size(),
|
||||
net::X509Certificate::FORMAT_AUTO);
|
||||
|
||||
if (certs.empty())
|
||||
return nullptr;
|
||||
|
||||
return certs[0];
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomBrowserClient::AtomBrowserClient()
|
||||
: dying_render_process_(NULL) {
|
||||
// static
|
||||
void AtomBrowserClient::SuppressRendererProcessRestartForOnce() {
|
||||
g_suppress_renderer_process_restart = true;
|
||||
}
|
||||
|
||||
AtomBrowserClient::AtomBrowserClient() {
|
||||
}
|
||||
|
||||
AtomBrowserClient::~AtomBrowserClient() {
|
||||
}
|
||||
|
||||
net::URLRequestContextGetter* AtomBrowserClient::CreateRequestContext(
|
||||
content::BrowserContext* browser_context,
|
||||
content::ProtocolHandlerMap* protocol_handlers) {
|
||||
return static_cast<AtomBrowserContext*>(browser_context)->
|
||||
CreateRequestContext(protocol_handlers);
|
||||
void AtomBrowserClient::RenderProcessWillLaunch(
|
||||
content::RenderProcessHost* host) {
|
||||
int id = host->GetID();
|
||||
host->AddFilter(new printing::PrintingMessageFilter(host->GetID()));
|
||||
host->AddFilter(new TtsMessageFilter(id, host->GetBrowserContext()));
|
||||
}
|
||||
|
||||
content::SpeechRecognitionManagerDelegate*
|
||||
AtomBrowserClient::CreateSpeechRecognitionManagerDelegate() {
|
||||
return new AtomSpeechRecognitionManagerDelegate;
|
||||
}
|
||||
|
||||
content::AccessTokenStore* AtomBrowserClient::CreateAccessTokenStore() {
|
||||
return new AtomAccessTokenStore;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::OverrideWebkitPrefs(
|
||||
content::RenderViewHost* render_view_host,
|
||||
const GURL& url,
|
||||
WebPreferences* prefs) {
|
||||
content::RenderViewHost* host, content::WebPreferences* prefs) {
|
||||
prefs->javascript_enabled = true;
|
||||
prefs->web_security_enabled = true;
|
||||
prefs->javascript_can_open_windows_automatically = true;
|
||||
prefs->plugins_enabled = false;
|
||||
prefs->plugins_enabled = true;
|
||||
prefs->dom_paste_enabled = true;
|
||||
prefs->java_enabled = false;
|
||||
prefs->allow_scripts_to_close_windows = true;
|
||||
@@ -66,59 +133,109 @@ void AtomBrowserClient::OverrideWebkitPrefs(
|
||||
prefs->allow_universal_access_from_file_urls = true;
|
||||
prefs->allow_file_access_from_file_urls = true;
|
||||
prefs->experimental_webgl_enabled = true;
|
||||
prefs->allow_displaying_insecure_content = true;
|
||||
prefs->allow_running_insecure_content = true;
|
||||
prefs->allow_displaying_insecure_content = false;
|
||||
prefs->allow_running_insecure_content = false;
|
||||
|
||||
NativeWindow* window = NativeWindow::FromRenderView(
|
||||
render_view_host->GetProcess()->GetID(),
|
||||
render_view_host->GetRoutingID());
|
||||
// Custom preferences of guest page.
|
||||
auto web_contents = content::WebContents::FromRenderViewHost(host);
|
||||
WebViewManager::WebViewInfo info;
|
||||
if (WebViewManager::GetInfoForWebContents(web_contents, &info)) {
|
||||
prefs->web_security_enabled = !info.disable_web_security;
|
||||
return;
|
||||
}
|
||||
|
||||
NativeWindow* window = NativeWindow::FromWebContents(web_contents);
|
||||
if (window)
|
||||
window->OverrideWebkitPrefs(url, prefs);
|
||||
window->OverrideWebkitPrefs(prefs);
|
||||
}
|
||||
|
||||
bool AtomBrowserClient::ShouldSwapProcessesForNavigation(
|
||||
content::SiteInstance* site_instance,
|
||||
const GURL& current_url,
|
||||
const GURL& new_url) {
|
||||
if (site_instance->HasProcess())
|
||||
dying_render_process_ = site_instance->GetProcess();
|
||||
std::string AtomBrowserClient::GetApplicationLocale() {
|
||||
return l10n_util::GetApplicationLocale("");
|
||||
}
|
||||
|
||||
// Restart renderer process for all navigations, this relies on a patch to
|
||||
// Chromium: http://git.io/_PaNyg.
|
||||
return true;
|
||||
void AtomBrowserClient::OverrideSiteInstanceForNavigation(
|
||||
content::BrowserContext* browser_context,
|
||||
content::SiteInstance* current_instance,
|
||||
const GURL& url,
|
||||
content::SiteInstance** new_instance) {
|
||||
if (g_suppress_renderer_process_restart) {
|
||||
g_suppress_renderer_process_restart = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Restart renderer process for all navigations except "javacript:" scheme.
|
||||
if (url.SchemeIs(url::kJavaScriptScheme))
|
||||
return;
|
||||
|
||||
*new_instance = content::SiteInstance::CreateForURL(browser_context, url);
|
||||
}
|
||||
|
||||
void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
CommandLine* command_line,
|
||||
int child_process_id) {
|
||||
WindowList* list = WindowList::GetInstance();
|
||||
NativeWindow* window = NULL;
|
||||
base::CommandLine* command_line,
|
||||
int process_id) {
|
||||
std::string process_type = command_line->GetSwitchValueASCII("type");
|
||||
if (process_type != "renderer")
|
||||
return;
|
||||
|
||||
// Find the owner of this child process.
|
||||
WindowList::const_iterator iter = std::find_if(
|
||||
list->begin(), list->end(), FindByProcessId(child_process_id));
|
||||
if (iter != list->end())
|
||||
window = *iter;
|
||||
NativeWindow* window;
|
||||
WebViewManager::WebViewInfo info;
|
||||
ProcessOwner owner = GetProcessOwner(process_id, &window, &info);
|
||||
|
||||
// If the render process is a newly started one, which means the window still
|
||||
// uses the old going-to-be-swapped render process, then we try to find the
|
||||
// window from the swapped render process.
|
||||
if (window == NULL && dying_render_process_ != NULL) {
|
||||
child_process_id = dying_render_process_->GetID();
|
||||
WindowList::const_iterator iter = std::find_if(
|
||||
list->begin(), list->end(), FindByProcessId(child_process_id));
|
||||
if (iter != list->end())
|
||||
window = *iter;
|
||||
if (owner == OWNER_NATIVE_WINDOW) {
|
||||
window->AppendExtraCommandLineSwitches(command_line);
|
||||
} else if (owner == OWNER_GUEST_WEB_CONTENTS) {
|
||||
command_line->AppendSwitchASCII(
|
||||
switches::kGuestInstanceID, base::IntToString(info.guest_instance_id));
|
||||
command_line->AppendSwitchASCII(
|
||||
switches::kNodeIntegration, info.node_integration ? "true" : "false");
|
||||
if (info.plugins)
|
||||
command_line->AppendSwitch(switches::kEnablePlugins);
|
||||
if (!info.preload_script.empty())
|
||||
command_line->AppendSwitchPath(
|
||||
switches::kPreloadScript, info.preload_script);
|
||||
}
|
||||
}
|
||||
|
||||
void AtomBrowserClient::DidCreatePpapiPlugin(
|
||||
content::BrowserPpapiHost* browser_host) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (command_line->HasSwitch(switches::kEnablePlugins))
|
||||
browser_host->GetPpapiHost()->AddHostFactoryFilter(
|
||||
scoped_ptr<ppapi::host::HostFactory>(
|
||||
new chrome::ChromeBrowserPepperHostFactory(browser_host)));
|
||||
}
|
||||
|
||||
content::QuotaPermissionContext*
|
||||
AtomBrowserClient::CreateQuotaPermissionContext() {
|
||||
return new AtomQuotaPermissionContext;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::SelectClientCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
scoped_ptr<content::ClientCertificateDelegate> delegate) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto cert_path = command_line->GetSwitchValueNative(
|
||||
switches::kClientCertificate);
|
||||
|
||||
// TODO(zcbenz): allow users to select certificate from
|
||||
// client_cert list. Right now defaults to first certificate
|
||||
// in the list.
|
||||
scoped_refptr<net::X509Certificate> certificate;
|
||||
if (cert_path.empty()) {
|
||||
if (!cert_request_info->client_certs.empty())
|
||||
certificate = cert_request_info->client_certs[0];
|
||||
} else {
|
||||
certificate = ImportCertFromFile(base::FilePath(cert_path));
|
||||
}
|
||||
|
||||
if (window != NULL)
|
||||
window->AppendExtraCommandLineSwitches(command_line, child_process_id);
|
||||
|
||||
dying_render_process_ = NULL;
|
||||
if (certificate.get())
|
||||
delegate->ContinueWithCertificate(certificate.get());
|
||||
}
|
||||
|
||||
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
|
||||
const content::MainFunctionParams&) {
|
||||
v8::V8::Initialize(); // Init V8 before creating main parts.
|
||||
return new AtomBrowserMainParts;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// 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_ATOM_BROWSER_CLIENT_H_
|
||||
#define ATOM_BROWSER_ATOM_BROWSER_CLIENT_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "brightray/browser/browser_client.h"
|
||||
|
||||
namespace content {
|
||||
class QuotaPermissionContext;
|
||||
class ClientCertificateDelegate;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class SSLCertRequestInfo;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserClient : public brightray::BrowserClient {
|
||||
@@ -14,26 +25,35 @@ class AtomBrowserClient : public brightray::BrowserClient {
|
||||
AtomBrowserClient();
|
||||
virtual ~AtomBrowserClient();
|
||||
|
||||
// Don't force renderer process to restart for once.
|
||||
static void SuppressRendererProcessRestartForOnce();
|
||||
|
||||
protected:
|
||||
net::URLRequestContextGetter* CreateRequestContext(
|
||||
// content::ContentBrowserClient:
|
||||
void RenderProcessWillLaunch(content::RenderProcessHost* host) override;
|
||||
content::SpeechRecognitionManagerDelegate*
|
||||
CreateSpeechRecognitionManagerDelegate() override;
|
||||
content::AccessTokenStore* CreateAccessTokenStore() override;
|
||||
void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
|
||||
content::WebPreferences* prefs) override;
|
||||
std::string GetApplicationLocale() override;
|
||||
void OverrideSiteInstanceForNavigation(
|
||||
content::BrowserContext* browser_context,
|
||||
content::ProtocolHandlerMap* protocol_handlers) OVERRIDE;
|
||||
virtual void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
|
||||
const GURL& url,
|
||||
WebPreferences* prefs) OVERRIDE;
|
||||
virtual bool ShouldSwapProcessesForNavigation(
|
||||
content::SiteInstance* site_instance,
|
||||
const GURL& current_url,
|
||||
const GURL& new_url) OVERRIDE;
|
||||
virtual void AppendExtraCommandLineSwitches(CommandLine* command_line,
|
||||
int child_process_id) OVERRIDE;
|
||||
content::SiteInstance* current_instance,
|
||||
const GURL& dest_url,
|
||||
content::SiteInstance** new_instance);
|
||||
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
|
||||
int child_process_id) override;
|
||||
void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override;
|
||||
content::QuotaPermissionContext* CreateQuotaPermissionContext() override;
|
||||
void SelectClientCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
|
||||
|
||||
private:
|
||||
virtual brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
|
||||
const content::MainFunctionParams&) OVERRIDE;
|
||||
|
||||
// The render process which would be swapped out soon.
|
||||
content::RenderProcessHost* dying_render_process_;
|
||||
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
|
||||
const content::MainFunctionParams&) override;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
|
||||
};
|
||||
|
||||
@@ -1,76 +1,109 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// 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/atom_browser_context.h"
|
||||
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/net/atom_url_request_context_getter.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"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/threading/sequenced_worker_pool.h"
|
||||
#include "base/threading/worker_pool.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/resource_context.h"
|
||||
#include "vendor/brightray/browser/network_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "net/ftp/ftp_network_layer.h"
|
||||
#include "net/url_request/data_protocol_handler.h"
|
||||
#include "net/url_request/ftp_protocol_handler.h"
|
||||
#include "net/url_request/url_request_intercepting_job_factory.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "url/url_constants.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
class AtomResourceContext : public content::ResourceContext {
|
||||
public:
|
||||
AtomResourceContext() : getter_(NULL) {}
|
||||
namespace atom {
|
||||
|
||||
void set_url_request_context_getter(AtomURLRequestContextGetter* getter) {
|
||||
getter_ = getter;
|
||||
namespace {
|
||||
|
||||
class NoCacheBackend : public net::HttpCache::BackendFactory {
|
||||
int CreateBackend(net::NetLog* net_log,
|
||||
scoped_ptr<disk_cache::Backend>* backend,
|
||||
const net::CompletionCallback& callback) override {
|
||||
return net::ERR_FAILED;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual net::HostResolver* GetHostResolver() OVERRIDE {
|
||||
DCHECK(getter_);
|
||||
return getter_->host_resolver();
|
||||
}
|
||||
|
||||
virtual net::URLRequestContext* GetRequestContext() OVERRIDE {
|
||||
DCHECK(getter_);
|
||||
return getter_->GetURLRequestContext();
|
||||
}
|
||||
|
||||
virtual bool AllowMicAccess(const GURL& origin) OVERRIDE {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool AllowCameraAccess(const GURL& origin) OVERRIDE {
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
AtomURLRequestContextGetter* getter_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomResourceContext);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomBrowserContext::AtomBrowserContext()
|
||||
: resource_context_(new AtomResourceContext) {
|
||||
: fake_browser_process_(new BrowserProcess),
|
||||
job_factory_(new AtomURLRequestJobFactory) {
|
||||
}
|
||||
|
||||
AtomBrowserContext::~AtomBrowserContext() {
|
||||
}
|
||||
|
||||
AtomURLRequestContextGetter* AtomBrowserContext::CreateRequestContext(
|
||||
content::ProtocolHandlerMap* protocol_handlers) {
|
||||
DCHECK(!url_request_getter_);
|
||||
url_request_getter_ = new AtomURLRequestContextGetter(
|
||||
GetPath(),
|
||||
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
|
||||
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
|
||||
base::Bind(&AtomBrowserContext::CreateNetworkDelegate,
|
||||
base::Unretained(this)),
|
||||
protocol_handlers);
|
||||
net::URLRequestJobFactory* AtomBrowserContext::CreateURLRequestJobFactory(
|
||||
content::ProtocolHandlerMap* handlers,
|
||||
content::URLRequestInterceptorScopedVector* interceptors) {
|
||||
scoped_ptr<AtomURLRequestJobFactory> job_factory(job_factory_);
|
||||
|
||||
resource_context_->set_url_request_context_getter(url_request_getter_.get());
|
||||
return url_request_getter_.get();
|
||||
for (content::ProtocolHandlerMap::iterator it = handlers->begin();
|
||||
it != handlers->end(); ++it)
|
||||
job_factory->SetProtocolHandler(it->first, it->second.release());
|
||||
handlers->clear();
|
||||
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kDataScheme, new net::DataProtocolHandler);
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kFileScheme, new asar::AsarProtocolHandler(
|
||||
BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
|
||||
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kHttpScheme, new HttpProtocolHandler(url::kHttpScheme));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kHttpsScheme, new HttpProtocolHandler(url::kHttpsScheme));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kWsScheme, new HttpProtocolHandler(url::kWsScheme));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kWssScheme, new HttpProtocolHandler(url::kWssScheme));
|
||||
|
||||
auto host_resolver = url_request_context_getter()
|
||||
->GetURLRequestContext()
|
||||
->host_resolver();
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kFtpScheme, new net::FtpProtocolHandler(
|
||||
new net::FtpNetworkLayer(host_resolver)));
|
||||
|
||||
// Set up interceptors in the reverse order.
|
||||
scoped_ptr<net::URLRequestJobFactory> top_job_factory = job_factory.Pass();
|
||||
content::URLRequestInterceptorScopedVector::reverse_iterator it;
|
||||
for (it = interceptors->rbegin(); it != interceptors->rend(); ++it)
|
||||
top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
|
||||
top_job_factory.Pass(), make_scoped_ptr(*it)));
|
||||
interceptors->weak_clear();
|
||||
|
||||
return top_job_factory.release();
|
||||
}
|
||||
|
||||
content::ResourceContext* AtomBrowserContext::GetResourceContext() {
|
||||
return resource_context_.get();
|
||||
net::HttpCache::BackendFactory*
|
||||
AtomBrowserContext::CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path) {
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (command_line->HasSwitch(switches::kDisableHttpCache))
|
||||
return new NoCacheBackend;
|
||||
else
|
||||
return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path);
|
||||
}
|
||||
|
||||
content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() {
|
||||
if (!guest_manager_)
|
||||
guest_manager_.reset(new WebViewManager(this));
|
||||
return guest_manager_.get();
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// 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_ATOM_BROWSER_CONTEXT_H_
|
||||
#define ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "brightray/browser/browser_context.h"
|
||||
|
||||
class BrowserProcess;
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomResourceContext;
|
||||
class AtomURLRequestContextGetter;
|
||||
class AtomURLRequestJobFactory;
|
||||
class WebViewManager;
|
||||
|
||||
class AtomBrowserContext : public brightray::BrowserContext {
|
||||
public:
|
||||
@@ -21,22 +22,24 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
// Returns the browser context singleton.
|
||||
static AtomBrowserContext* Get();
|
||||
|
||||
// Creates or returns the request context.
|
||||
AtomURLRequestContextGetter* CreateRequestContext(
|
||||
content::ProtocolHandlerMap*);
|
||||
// brightray::URLRequestContextGetter::Delegate:
|
||||
net::URLRequestJobFactory* CreateURLRequestJobFactory(
|
||||
content::ProtocolHandlerMap* handlers,
|
||||
content::URLRequestInterceptorScopedVector* interceptors) override;
|
||||
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path) override;
|
||||
|
||||
AtomURLRequestContextGetter* url_request_context_getter() const {
|
||||
DCHECK(url_request_getter_);
|
||||
return url_request_getter_.get();
|
||||
}
|
||||
// content::BrowserContext:
|
||||
content::BrowserPluginGuestManager* GetGuestManager() override;
|
||||
|
||||
protected:
|
||||
// content::BrowserContext implementations:
|
||||
virtual content::ResourceContext* GetResourceContext() OVERRIDE;
|
||||
AtomURLRequestJobFactory* job_factory() const { return job_factory_; }
|
||||
|
||||
private:
|
||||
scoped_ptr<AtomResourceContext> resource_context_;
|
||||
scoped_refptr<AtomURLRequestContextGetter> url_request_getter_;
|
||||
// A fake BrowserProcess object that used to feed the source code from chrome.
|
||||
scoped_ptr<BrowserProcess> fake_browser_process_;
|
||||
scoped_ptr<WebViewManager> guest_manager_;
|
||||
|
||||
AtomURLRequestJobFactory* job_factory_; // Weak reference.
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -7,12 +7,14 @@
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/javascript_environment.h"
|
||||
#include "atom/common/api/atom_bindings.h"
|
||||
#include "atom/common/node_bindings.h"
|
||||
#include "net/proxy/proxy_resolver_v8.h"
|
||||
#include "base/command_line.h"
|
||||
#include "v8/include/v8-debug.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "ui/gfx/win/dpi.h"
|
||||
#if defined(USE_X11)
|
||||
#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
|
||||
#endif
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
@@ -23,9 +25,10 @@ namespace atom {
|
||||
AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL;
|
||||
|
||||
AtomBrowserMainParts::AtomBrowserMainParts()
|
||||
: atom_bindings_(new AtomBindings),
|
||||
browser_(new Browser),
|
||||
node_bindings_(NodeBindings::Create(true)) {
|
||||
: browser_(new Browser),
|
||||
node_bindings_(NodeBindings::Create(true)),
|
||||
atom_bindings_(new AtomBindings),
|
||||
gc_timer_(true, true) {
|
||||
DCHECK(!self_) << "Cannot have two AtomBrowserMainParts";
|
||||
self_ = this;
|
||||
}
|
||||
@@ -46,35 +49,44 @@ brightray::BrowserContext* AtomBrowserMainParts::CreateBrowserContext() {
|
||||
void AtomBrowserMainParts::PostEarlyInitialization() {
|
||||
brightray::BrowserMainParts::PostEarlyInitialization();
|
||||
|
||||
#if defined(USE_X11)
|
||||
SetDPIFromGSettings();
|
||||
#endif
|
||||
|
||||
// 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();
|
||||
|
||||
v8::V8::Initialize();
|
||||
|
||||
// Create context.
|
||||
v8::Locker locker(node_isolate);
|
||||
v8::HandleScope handle_scope(node_isolate);
|
||||
v8::Local<v8::Context> context = v8::Context::New(node_isolate);
|
||||
|
||||
// Create the global environment.
|
||||
global_env = node_bindings_->CreateEnvironment(context);
|
||||
|
||||
// Wrap whole process in one global context.
|
||||
context->Enter();
|
||||
global_env = node_bindings_->CreateEnvironment(js_env_->context());
|
||||
|
||||
// Add atom-shell extended APIs.
|
||||
atom_bindings_->BindTo(global_env->process_object());
|
||||
atom_bindings_->BindTo(js_env_->isolate(), global_env->process_object());
|
||||
|
||||
// Load everything.
|
||||
node_bindings_->LoadEnvironment(global_env);
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
||||
brightray::BrowserMainParts::PreMainMessageLoopRun();
|
||||
|
||||
// Run user's main script before most things get initialized, so we can have
|
||||
// a chance to setup everything.
|
||||
node_bindings_->PrepareMessageLoop();
|
||||
node_bindings_->RunMessageLoop();
|
||||
|
||||
// Make sure the url request job factory is created before the
|
||||
// will-finish-launching event.
|
||||
static_cast<content::BrowserContext*>(AtomBrowserContext::Get())->
|
||||
GetRequestContext();
|
||||
// Start idle gc.
|
||||
gc_timer_.Start(
|
||||
FROM_HERE, base::TimeDelta::FromMinutes(1),
|
||||
base::Bind(base::IgnoreResult(&v8::Isolate::IdleNotification),
|
||||
base::Unretained(js_env_->isolate()),
|
||||
1000));
|
||||
|
||||
brightray::BrowserMainParts::PreMainMessageLoopRun();
|
||||
|
||||
#if defined(USE_X11)
|
||||
libgtk2ui::GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());
|
||||
#endif
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
// The corresponding call in OS X is in AtomApplicationDelegate.
|
||||
@@ -83,19 +95,4 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
||||
#endif
|
||||
}
|
||||
|
||||
int AtomBrowserMainParts::PreCreateThreads() {
|
||||
// Note that we are overriding the PreCreateThreads of brightray, since we
|
||||
// are integrating node in browser, we can just be sure that an V8 instance
|
||||
// would be prepared, while the ProxyResolverV8::CreateIsolate() would
|
||||
// try to create a V8 isolate, which messed everything on Windows, so we
|
||||
// have to override and call RememberDefaultIsolate on Windows instead.
|
||||
net::ProxyResolverV8::RememberDefaultIsolate();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
gfx::EnableHighDPISupport();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// 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_ATOM_BROWSER_MAIN_PARTS_H_
|
||||
#define ATOM_BROWSER_ATOM_BROWSER_MAIN_PARTS_H_
|
||||
|
||||
#include "base/timer/timer.h"
|
||||
#include "brightray/browser/browser_main_parts.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBindings;
|
||||
class Browser;
|
||||
class JavascriptEnvironment;
|
||||
class NodeBindings;
|
||||
|
||||
class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||
@@ -24,21 +26,27 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||
|
||||
protected:
|
||||
// Implementations of brightray::BrowserMainParts.
|
||||
virtual brightray::BrowserContext* CreateBrowserContext() OVERRIDE;
|
||||
brightray::BrowserContext* CreateBrowserContext() override;
|
||||
|
||||
// Implementations of content::BrowserMainParts.
|
||||
virtual void PostEarlyInitialization() OVERRIDE;
|
||||
virtual void PreMainMessageLoopRun() OVERRIDE;
|
||||
virtual int PreCreateThreads() OVERRIDE;
|
||||
void PostEarlyInitialization() override;
|
||||
void PreMainMessageLoopRun() override;
|
||||
#if defined(OS_MACOSX)
|
||||
virtual void PreMainMessageLoopStart() OVERRIDE;
|
||||
virtual void PostDestroyThreads() OVERRIDE;
|
||||
void PreMainMessageLoopStart() override;
|
||||
void PostDestroyThreads() override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
scoped_ptr<AtomBindings> atom_bindings_;
|
||||
#if defined(USE_X11)
|
||||
void SetDPIFromGSettings();
|
||||
#endif
|
||||
|
||||
scoped_ptr<Browser> browser_;
|
||||
scoped_ptr<JavascriptEnvironment> js_env_;
|
||||
scoped_ptr<NodeBindings> node_bindings_;
|
||||
scoped_ptr<AtomBindings> atom_bindings_;
|
||||
|
||||
base::Timer gc_timer_;
|
||||
|
||||
static AtomBrowserMainParts* self_;
|
||||
|
||||
|
||||
73
atom/browser/atom_browser_main_parts_linux.cc
Normal file
73
atom/browser/atom_browser_main_parts_linux.cc
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "ui/gfx/switches.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
const char* kInterfaceSchema = "org.gnome.desktop.interface";
|
||||
const char* kScaleFactor = "scaling-factor";
|
||||
|
||||
bool SchemaExists(const char* schema_name) {
|
||||
const gchar* const* schemas = g_settings_list_schemas();
|
||||
while (*schemas) {
|
||||
if (strcmp(schema_name, static_cast<const char*>(*schemas)) == 0)
|
||||
return true;
|
||||
schemas++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KeyExists(GSettings* client, const char* key) {
|
||||
gchar** keys = g_settings_list_keys(client);
|
||||
if (!keys)
|
||||
return false;
|
||||
|
||||
gchar** iter = keys;
|
||||
while (*iter) {
|
||||
if (strcmp(*iter, key) == 0)
|
||||
break;
|
||||
iter++;
|
||||
}
|
||||
|
||||
bool exists = *iter != NULL;
|
||||
g_strfreev(keys);
|
||||
return exists;
|
||||
}
|
||||
|
||||
void GetDPIFromGSettings(guint* scale_factor) {
|
||||
GSettings* client = nullptr;
|
||||
if (!SchemaExists(kInterfaceSchema) ||
|
||||
!(client = g_settings_new(kInterfaceSchema))) {
|
||||
VLOG(1) << "Cannot create gsettings client.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (KeyExists(client, kScaleFactor))
|
||||
*scale_factor = g_settings_get_uint(client, kScaleFactor);
|
||||
|
||||
g_object_unref(client);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void AtomBrowserMainParts::SetDPIFromGSettings() {
|
||||
guint scale_factor = 1;
|
||||
GetDPIFromGSettings(&scale_factor);
|
||||
if (scale_factor == 0)
|
||||
scale_factor = 1;
|
||||
|
||||
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
|
||||
switches::kForceDeviceScaleFactor, base::UintToString(scale_factor));
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -1,30 +1,28 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// 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/atom_browser_main_parts.h"
|
||||
|
||||
#import "atom/browser/mac/atom_application.h"
|
||||
#import "atom/browser/mac/atom_application_delegate.h"
|
||||
#include "base/files/file_path.h"
|
||||
#import "base/mac/foundation_util.h"
|
||||
#import "vendor/brightray/common/mac/main_application_bundle.h"
|
||||
#include "atom/browser/mac/atom_application.h"
|
||||
#include "atom/browser/mac/atom_application_delegate.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/foundation_util.h"
|
||||
#include "ui/base/l10n/l10n_util_mac.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
void AtomBrowserMainParts::PreMainMessageLoopStart() {
|
||||
// Initialize locale setting.
|
||||
l10n_util::OverrideLocaleWithCocoaLocale();
|
||||
|
||||
// Force the NSApplication subclass to be used.
|
||||
NSApplication* application = [AtomApplication sharedApplication];
|
||||
|
||||
AtomApplicationDelegate* delegate = [AtomApplicationDelegate alloc];
|
||||
[NSApp setDelegate:delegate];
|
||||
AtomApplicationDelegate* delegate = [[AtomApplicationDelegate alloc] init];
|
||||
[NSApp setDelegate:(id<NSFileManagerDelegate>)delegate];
|
||||
|
||||
base::FilePath frameworkPath = brightray::MainApplicationBundlePath()
|
||||
.Append("Contents")
|
||||
.Append("Frameworks")
|
||||
.Append("Atom Framework.framework");
|
||||
NSBundle* frameworkBundle = [NSBundle
|
||||
bundleWithPath:base::mac::FilePathToNSString(frameworkPath)];
|
||||
NSBundle* frameworkBundle = base::mac::FrameworkBundle();
|
||||
NSNib* mainNib = [[NSNib alloc] initWithNibNamed:@"MainMenu"
|
||||
bundle:frameworkBundle];
|
||||
[mainNib instantiateWithOwner:application topLevelObjects:nil];
|
||||
@@ -37,7 +35,8 @@ void AtomBrowserMainParts::PreMainMessageLoopStart() {
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PostDestroyThreads() {
|
||||
[[AtomApplication sharedApplication] setDelegate:nil];
|
||||
[[NSApp delegate] release];
|
||||
[NSApp setDelegate:nil];
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -15,21 +15,20 @@ void AtomJavaScriptDialogManager::RunJavaScriptDialog(
|
||||
const GURL& origin_url,
|
||||
const std::string& accept_lang,
|
||||
content::JavaScriptMessageType javascript_message_type,
|
||||
const string16& message_text,
|
||||
const string16& default_prompt_text,
|
||||
const base::string16& message_text,
|
||||
const base::string16& default_prompt_text,
|
||||
const DialogClosedCallback& callback,
|
||||
bool* did_suppress_message) {
|
||||
callback.Run(false, string16());
|
||||
callback.Run(false, base::string16());
|
||||
}
|
||||
|
||||
void AtomJavaScriptDialogManager::RunBeforeUnloadDialog(
|
||||
content::WebContents* web_contents,
|
||||
const string16& message_text,
|
||||
const base::string16& message_text,
|
||||
bool is_reload,
|
||||
const DialogClosedCallback& callback) {
|
||||
|
||||
bool prevent_reload = message_text.empty() ||
|
||||
message_text == ASCIIToUTF16("false");
|
||||
message_text == base::ASCIIToUTF16("false");
|
||||
callback.Run(!prevent_reload, message_text);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -14,24 +14,23 @@ namespace atom {
|
||||
class AtomJavaScriptDialogManager : public content::JavaScriptDialogManager {
|
||||
public:
|
||||
// content::JavaScriptDialogManager implementations.
|
||||
virtual void RunJavaScriptDialog(
|
||||
void RunJavaScriptDialog(
|
||||
content::WebContents* web_contents,
|
||||
const GURL& origin_url,
|
||||
const std::string& accept_lang,
|
||||
content::JavaScriptMessageType javascript_message_type,
|
||||
const string16& message_text,
|
||||
const string16& default_prompt_text,
|
||||
const base::string16& message_text,
|
||||
const base::string16& default_prompt_text,
|
||||
const DialogClosedCallback& callback,
|
||||
bool* did_suppress_message) OVERRIDE;
|
||||
virtual void RunBeforeUnloadDialog(
|
||||
bool* did_suppress_message) override;
|
||||
void RunBeforeUnloadDialog(
|
||||
content::WebContents* web_contents,
|
||||
const string16& message_text,
|
||||
const base::string16& message_text,
|
||||
bool is_reload,
|
||||
const DialogClosedCallback& callback) OVERRIDE;
|
||||
virtual void CancelActiveAndPendingDialogs(
|
||||
content::WebContents* web_contents) OVERRIDE {}
|
||||
virtual void WebContentsDestroyed(
|
||||
content::WebContents* web_contents) OVERRIDE {}
|
||||
const DialogClosedCallback& callback) override;
|
||||
void CancelActiveAndPendingDialogs(
|
||||
content::WebContents* web_contents) override {}
|
||||
void ResetDialogState(content::WebContents* web_contents) override {};
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
24
atom/browser/atom_quota_permission_context.cc
Normal file
24
atom/browser/atom_quota_permission_context.cc
Normal file
@@ -0,0 +1,24 @@
|
||||
// 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/atom_quota_permission_context.h"
|
||||
|
||||
#include "storage/common/quota/quota_types.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomQuotaPermissionContext::AtomQuotaPermissionContext() {
|
||||
}
|
||||
|
||||
AtomQuotaPermissionContext::~AtomQuotaPermissionContext() {
|
||||
}
|
||||
|
||||
void AtomQuotaPermissionContext::RequestQuotaPermission(
|
||||
const content::StorageQuotaParams& params,
|
||||
int render_process_id,
|
||||
const PermissionCallback& callback) {
|
||||
callback.Run(response::QUOTA_PERMISSION_RESPONSE_ALLOW);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
31
atom/browser/atom_quota_permission_context.h
Normal file
31
atom/browser/atom_quota_permission_context.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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_ATOM_QUOTA_PERMISSION_CONTEXT_H_
|
||||
#define ATOM_BROWSER_ATOM_QUOTA_PERMISSION_CONTEXT_H_
|
||||
|
||||
#include "content/public/browser/quota_permission_context.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomQuotaPermissionContext : public content::QuotaPermissionContext {
|
||||
public:
|
||||
typedef content::QuotaPermissionContext::QuotaPermissionResponse response;
|
||||
|
||||
AtomQuotaPermissionContext();
|
||||
virtual ~AtomQuotaPermissionContext();
|
||||
|
||||
// content::QuotaPermissionContext:
|
||||
void RequestQuotaPermission(
|
||||
const content::StorageQuotaParams& params,
|
||||
int render_process_id,
|
||||
const PermissionCallback& callback) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomQuotaPermissionContext);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_QUOTA_PERMISSION_CONTEXT_H_
|
||||
74
atom/browser/atom_speech_recognition_manager_delegate.cc
Normal file
74
atom/browser/atom_speech_recognition_manager_delegate.cc
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/callback.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomSpeechRecognitionManagerDelegate::AtomSpeechRecognitionManagerDelegate() {
|
||||
}
|
||||
|
||||
AtomSpeechRecognitionManagerDelegate::~AtomSpeechRecognitionManagerDelegate() {
|
||||
}
|
||||
|
||||
void AtomSpeechRecognitionManagerDelegate::OnRecognitionStart(int session_id) {
|
||||
}
|
||||
|
||||
void AtomSpeechRecognitionManagerDelegate::OnAudioStart(int session_id) {
|
||||
}
|
||||
|
||||
void AtomSpeechRecognitionManagerDelegate::OnEnvironmentEstimationComplete(
|
||||
int session_id) {
|
||||
}
|
||||
|
||||
void AtomSpeechRecognitionManagerDelegate::OnSoundStart(int session_id) {
|
||||
}
|
||||
|
||||
void AtomSpeechRecognitionManagerDelegate::OnSoundEnd(int session_id) {
|
||||
}
|
||||
|
||||
void AtomSpeechRecognitionManagerDelegate::OnAudioEnd(int session_id) {
|
||||
}
|
||||
|
||||
void AtomSpeechRecognitionManagerDelegate::OnRecognitionEnd(int session_id) {
|
||||
}
|
||||
|
||||
void AtomSpeechRecognitionManagerDelegate::OnRecognitionResults(
|
||||
int session_id, const content::SpeechRecognitionResults& result) {
|
||||
}
|
||||
|
||||
void AtomSpeechRecognitionManagerDelegate::OnRecognitionError(
|
||||
int session_id, const content::SpeechRecognitionError& error) {
|
||||
}
|
||||
|
||||
void AtomSpeechRecognitionManagerDelegate::OnAudioLevelsChange(
|
||||
int session_id, float volume, float noise_volume) {
|
||||
}
|
||||
|
||||
void AtomSpeechRecognitionManagerDelegate::GetDiagnosticInformation(
|
||||
bool* can_report_metrics, std::string* hardware_info) {
|
||||
*can_report_metrics = false;
|
||||
}
|
||||
|
||||
void AtomSpeechRecognitionManagerDelegate::CheckRecognitionIsAllowed(
|
||||
int session_id,
|
||||
base::Callback<void(bool ask_user, bool is_allowed)> callback) {
|
||||
callback.Run(true, true);
|
||||
}
|
||||
|
||||
content::SpeechRecognitionEventListener*
|
||||
AtomSpeechRecognitionManagerDelegate::GetEventListener() {
|
||||
return this;
|
||||
}
|
||||
|
||||
bool AtomSpeechRecognitionManagerDelegate::FilterProfanities(
|
||||
int render_process_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
52
atom/browser/atom_speech_recognition_manager_delegate.h
Normal file
52
atom/browser/atom_speech_recognition_manager_delegate.h
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_ATOM_SPEECH_RECOGNITION_MANAGER_DELEGATE_H_
|
||||
#define ATOM_BROWSER_ATOM_SPEECH_RECOGNITION_MANAGER_DELEGATE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "content/public/browser/speech_recognition_event_listener.h"
|
||||
#include "content/public/browser/speech_recognition_manager_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomSpeechRecognitionManagerDelegate
|
||||
: public content::SpeechRecognitionManagerDelegate,
|
||||
public content::SpeechRecognitionEventListener {
|
||||
public:
|
||||
AtomSpeechRecognitionManagerDelegate();
|
||||
virtual ~AtomSpeechRecognitionManagerDelegate();
|
||||
|
||||
// content::SpeechRecognitionEventListener:
|
||||
void OnRecognitionStart(int session_id) override;
|
||||
void OnAudioStart(int session_id) override;
|
||||
void OnEnvironmentEstimationComplete(int session_id) override;
|
||||
void OnSoundStart(int session_id) override;
|
||||
void OnSoundEnd(int session_id) override;
|
||||
void OnAudioEnd(int session_id) override;
|
||||
void OnRecognitionEnd(int session_id) override;
|
||||
void OnRecognitionResults(
|
||||
int session_id, const content::SpeechRecognitionResults& result) override;
|
||||
void OnRecognitionError(
|
||||
int session_id, const content::SpeechRecognitionError& error) override;
|
||||
void OnAudioLevelsChange(int session_id, float volume,
|
||||
float noise_volume) override;
|
||||
|
||||
// content::SpeechRecognitionManagerDelegate:
|
||||
void GetDiagnosticInformation(bool* can_report_metrics,
|
||||
std::string* hardware_info) override;
|
||||
void CheckRecognitionIsAllowed(
|
||||
int session_id,
|
||||
base::Callback<void(bool ask_user, bool is_allowed)> callback) override;
|
||||
content::SpeechRecognitionEventListener* GetEventListener() override;
|
||||
bool FilterProfanities(int render_process_id) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomSpeechRecognitionManagerDelegate);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_SPEECH_RECOGNITION_MANAGER_DELEGATE_H_
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -36,23 +36,31 @@ void RelaunchToInstallUpdate() {
|
||||
// static
|
||||
void AutoUpdater::SetFeedURL(const std::string& feed) {
|
||||
if (g_updater == nil) {
|
||||
// Initialize the SQRLUpdater.
|
||||
NSURL* url = [NSURL URLWithString:base::SysUTF8ToNSString(feed)];
|
||||
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:url];
|
||||
g_updater = [[SQRLUpdater alloc] initWithUpdateRequest:urlRequest];
|
||||
|
||||
AutoUpdaterDelegate* delegate = GetDelegate();
|
||||
if (!delegate)
|
||||
return;
|
||||
|
||||
// Initialize the SQRLUpdater.
|
||||
NSURL* url = [NSURL URLWithString:base::SysUTF8ToNSString(feed)];
|
||||
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:url];
|
||||
|
||||
@try {
|
||||
g_updater = [[SQRLUpdater alloc] initWithUpdateRequest:urlRequest];
|
||||
} @catch (NSException* error) {
|
||||
delegate->OnError(base::SysNSStringToUTF8(error.reason));
|
||||
return;
|
||||
}
|
||||
|
||||
[[g_updater rac_valuesForKeyPath:@"state" observer:g_updater]
|
||||
subscribeNext:^(NSNumber *stateNumber) {
|
||||
int state = [stateNumber integerValue];
|
||||
if (state == SQRLUpdaterStateCheckingForUpdate) {
|
||||
delegate->OnCheckingForUpdate();
|
||||
} else if (state == SQRLUpdaterStateDownloadingUpdate) {
|
||||
delegate->OnUpdateAvailable();
|
||||
}
|
||||
// Dispatching the event on main thread.
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (state == SQRLUpdaterStateCheckingForUpdate)
|
||||
delegate->OnCheckingForUpdate();
|
||||
else if (state == SQRLUpdaterStateDownloadingUpdate)
|
||||
delegate->OnUpdateAvailable();
|
||||
});
|
||||
}];
|
||||
}
|
||||
}
|
||||
@@ -86,7 +94,10 @@ void AutoUpdater::CheckForUpdates() {
|
||||
delegate->OnUpdateNotAvailable();
|
||||
}
|
||||
} error:^(NSError *error) {
|
||||
delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription));
|
||||
delegate->OnError(base::SysNSStringToUTF8(
|
||||
[NSString stringWithFormat:@"%@: %@",
|
||||
error.localizedDescription, error.localizedFailureReason]));
|
||||
}];
|
||||
}
|
||||
|
||||
} // namespace auto_updater
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
namespace atom {
|
||||
|
||||
Browser::Browser()
|
||||
: is_quiting_(false) {
|
||||
: is_quiting_(false),
|
||||
is_ready_(false) {
|
||||
WindowList::AddObserver(this);
|
||||
}
|
||||
|
||||
@@ -27,7 +28,9 @@ Browser* Browser::Get() {
|
||||
}
|
||||
|
||||
void Browser::Quit() {
|
||||
is_quiting_ = true;
|
||||
is_quiting_ = HandleBeforeQuit();
|
||||
if (!is_quiting_)
|
||||
return;
|
||||
|
||||
atom::WindowList* window_list = atom::WindowList::GetInstance();
|
||||
if (window_list->size() == 0)
|
||||
@@ -37,6 +40,8 @@ void Browser::Quit() {
|
||||
}
|
||||
|
||||
void Browser::Shutdown() {
|
||||
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnQuit());
|
||||
|
||||
is_quiting_ = true;
|
||||
base::MessageLoop::current()->Quit();
|
||||
}
|
||||
@@ -67,6 +72,10 @@ 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) {
|
||||
@@ -91,6 +100,7 @@ void Browser::WillFinishLaunching() {
|
||||
}
|
||||
|
||||
void Browser::DidFinishLaunching() {
|
||||
is_ready_ = true;
|
||||
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching());
|
||||
}
|
||||
|
||||
@@ -106,6 +116,15 @@ void Browser::NotifyAndShutdown() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool Browser::HandleBeforeQuit() {
|
||||
bool prevent_default = false;
|
||||
FOR_EACH_OBSERVER(BrowserObserver,
|
||||
observers_,
|
||||
OnBeforeQuit(&prevent_default));
|
||||
|
||||
return !prevent_default;
|
||||
}
|
||||
|
||||
void Browser::OnWindowCloseCancelled(NativeWindow* window) {
|
||||
if (is_quiting_)
|
||||
// Once a beforeunload handler has prevented the closing, we think the quit
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define ATOM_BROWSER_BROWSER_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/compiler_specific.h"
|
||||
@@ -13,6 +14,19 @@
|
||||
#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 {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace ui {
|
||||
class MenuModel;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
// This class is used for control application-wide operations.
|
||||
@@ -44,6 +58,12 @@ class Browser : public WindowListObserver {
|
||||
// Overrides the application name.
|
||||
void SetName(const std::string& name);
|
||||
|
||||
// Add the |path| to recent documents list.
|
||||
void AddRecentDocument(const base::FilePath& path);
|
||||
|
||||
// Clear the recent documents list.
|
||||
void ClearRecentDocuments();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// Bounce the dock icon.
|
||||
enum BounceType {
|
||||
@@ -56,8 +76,32 @@ class Browser : public WindowListObserver {
|
||||
// Set/Get dock's badge text.
|
||||
void DockSetBadgeText(const std::string& label);
|
||||
std::string DockGetBadgeText();
|
||||
|
||||
// Hide/Show dock.
|
||||
void DockHide();
|
||||
void DockShow();
|
||||
|
||||
// Set docks' menu.
|
||||
void DockSetMenu(ui::MenuModel* model);
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
#if defined(OS_WIN)
|
||||
struct UserTask {
|
||||
base::FilePath program;
|
||||
base::string16 arguments;
|
||||
base::string16 title;
|
||||
base::string16 description;
|
||||
base::FilePath icon_path;
|
||||
int icon_index;
|
||||
};
|
||||
|
||||
// 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);
|
||||
#endif
|
||||
|
||||
// Tell the application to open a file.
|
||||
bool OpenFile(const std::string& file_path);
|
||||
|
||||
@@ -80,6 +124,7 @@ class Browser : public WindowListObserver {
|
||||
}
|
||||
|
||||
bool is_quiting() const { return is_quiting_; }
|
||||
bool is_ready() const { return is_ready_; }
|
||||
|
||||
protected:
|
||||
// Returns the version of application bundle or executable file.
|
||||
@@ -91,19 +136,29 @@ class Browser : public WindowListObserver {
|
||||
// Send the will-quit message and then shutdown the application.
|
||||
void NotifyAndShutdown();
|
||||
|
||||
// Send the before-quit message and start closing windows.
|
||||
bool HandleBeforeQuit();
|
||||
|
||||
bool is_quiting_;
|
||||
|
||||
private:
|
||||
// WindowListObserver implementations:
|
||||
virtual void OnWindowCloseCancelled(NativeWindow* window) OVERRIDE;
|
||||
virtual void OnWindowAllClosed() OVERRIDE;
|
||||
void OnWindowCloseCancelled(NativeWindow* window) override;
|
||||
void OnWindowAllClosed() override;
|
||||
|
||||
// Observers of the browser.
|
||||
ObserverList<BrowserObserver> observers_;
|
||||
|
||||
// Whether "ready" event has been emitted.
|
||||
bool is_ready_;
|
||||
|
||||
std::string version_override_;
|
||||
std::string name_override_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
base::string16 app_user_model_id_;
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Browser);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -24,12 +25,18 @@ void Browser::Focus() {
|
||||
}
|
||||
}
|
||||
|
||||
void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||
}
|
||||
|
||||
void Browser::ClearRecentDocuments() {
|
||||
}
|
||||
|
||||
std::string Browser::GetExecutableFileVersion() const {
|
||||
return ATOM_VERSION_STRING;
|
||||
return brightray::GetApplicationVersion();
|
||||
}
|
||||
|
||||
std::string Browser::GetExecutableFileProductName() const {
|
||||
return "Atom-Shell";
|
||||
return brightray::GetApplicationName();
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// 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/browser.h"
|
||||
|
||||
#import "base/mac/bundle_locations.h"
|
||||
#include "atom/browser/mac/atom_application.h"
|
||||
#include "atom/browser/mac/atom_application_delegate.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "base/mac/foundation_util.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#import "atom/browser/mac/atom_application.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -14,20 +18,24 @@ void Browser::Focus() {
|
||||
[[AtomApplication sharedApplication] activateIgnoringOtherApps:YES];
|
||||
}
|
||||
|
||||
void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||
NSURL* u = [NSURL fileURLWithPath:base::mac::FilePathToNSString(path)];
|
||||
[[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:u];
|
||||
}
|
||||
|
||||
void Browser::ClearRecentDocuments() {
|
||||
}
|
||||
|
||||
std::string Browser::GetExecutableFileVersion() const {
|
||||
NSDictionary* infoDictionary = base::mac::OuterBundle().infoDictionary;
|
||||
NSString *version = [infoDictionary objectForKey:@"CFBundleVersion"];
|
||||
return base::SysNSStringToUTF8(version);
|
||||
return brightray::GetApplicationVersion();
|
||||
}
|
||||
|
||||
std::string Browser::GetExecutableFileProductName() const {
|
||||
NSDictionary* infoDictionary = base::mac::OuterBundle().infoDictionary;
|
||||
NSString *version = [infoDictionary objectForKey:@"CFBundleName"];
|
||||
return base::SysNSStringToUTF8(version);
|
||||
return brightray::GetApplicationName();
|
||||
}
|
||||
|
||||
int Browser::DockBounce(BounceType type) {
|
||||
return [[AtomApplication sharedApplication] requestUserAttention:type];
|
||||
return [[AtomApplication sharedApplication] requestUserAttention:(NSRequestUserAttentionType)type];
|
||||
}
|
||||
|
||||
void Browser::DockCancelBounce(int rid) {
|
||||
@@ -44,4 +52,23 @@ std::string Browser::DockGetBadgeText() {
|
||||
return base::SysNSStringToUTF8([tile badgeLabel]);
|
||||
}
|
||||
|
||||
void Browser::DockHide() {
|
||||
WindowList* list = WindowList::GetInstance();
|
||||
for (WindowList::iterator it = list->begin(); it != list->end(); ++it)
|
||||
[(*it)->GetNativeWindow() setCanHide:NO];
|
||||
|
||||
ProcessSerialNumber psn = { 0, kCurrentProcess };
|
||||
TransformProcessType(&psn, kProcessTransformToUIElementApplication);
|
||||
}
|
||||
|
||||
void Browser::DockShow() {
|
||||
ProcessSerialNumber psn = { 0, kCurrentProcess };
|
||||
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
||||
}
|
||||
|
||||
void Browser::DockSetMenu(ui::MenuModel* model) {
|
||||
AtomApplicationDelegate* delegate = (AtomApplicationDelegate*)[NSApp delegate];
|
||||
[delegate setApplicationDockMenu:model];
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -11,6 +11,9 @@ namespace atom {
|
||||
|
||||
class BrowserObserver {
|
||||
public:
|
||||
// The browser is about to close all windows.
|
||||
virtual void OnBeforeQuit(bool* prevent_default) {}
|
||||
|
||||
// The browser has closed all windows and will quit.
|
||||
virtual void OnWillQuit(bool* prevent_default) {}
|
||||
|
||||
@@ -18,6 +21,9 @@ class BrowserObserver {
|
||||
// method will not be called, instead it will call OnWillQuit.
|
||||
virtual void OnWindowAllClosed() {}
|
||||
|
||||
// The browser is quitting.
|
||||
virtual void OnQuit() {}
|
||||
|
||||
// The browser has opened a file by double clicking in Finder or dragging the
|
||||
// file to the Dock icon. (OS X only)
|
||||
virtual void OnOpenFile(bool* prevent_default,
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// 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/browser.h"
|
||||
|
||||
#include <atlbase.h>
|
||||
#include <propkey.h>
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#include <shobjidl.h>
|
||||
|
||||
#include "base/base_paths.h"
|
||||
#include "base/file_version_info.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/win/win_util.h"
|
||||
#include "base/win/windows_version.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -39,12 +46,89 @@ void Browser::Focus() {
|
||||
EnumWindows(&WindowsEnumerationHandler, reinterpret_cast<LPARAM>(&pid));
|
||||
}
|
||||
|
||||
void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||
if (base::win::GetVersion() < base::win::VERSION_WIN7)
|
||||
return;
|
||||
|
||||
CComPtr<IShellItem> item;
|
||||
HRESULT hr = SHCreateItemFromParsingName(
|
||||
path.value().c_str(), NULL, IID_PPV_ARGS(&item));
|
||||
if (SUCCEEDED(hr)) {
|
||||
SHARDAPPIDINFO info;
|
||||
info.psi = item;
|
||||
info.pszAppID = app_user_model_id_.c_str();
|
||||
SHAddToRecentDocs(SHARD_APPIDINFO, &info);
|
||||
}
|
||||
}
|
||||
|
||||
void Browser::ClearRecentDocuments() {
|
||||
CComPtr<IApplicationDestinations> destinations;
|
||||
if (FAILED(destinations.CoCreateInstance(CLSID_ApplicationDestinations,
|
||||
NULL, CLSCTX_INPROC_SERVER)))
|
||||
return;
|
||||
if (FAILED(destinations->SetAppID(app_user_model_id_.c_str())))
|
||||
return;
|
||||
destinations->RemoveAllDestinations();
|
||||
}
|
||||
|
||||
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())))
|
||||
return;
|
||||
|
||||
// Start a transaction that updates the JumpList of this application.
|
||||
UINT max_slots;
|
||||
CComPtr<IObjectArray> removed;
|
||||
if (FAILED(destinations->BeginList(&max_slots, IID_PPV_ARGS(&removed))))
|
||||
return;
|
||||
|
||||
CComPtr<IObjectCollection> collection;
|
||||
if (FAILED(collection.CoCreateInstance(CLSID_EnumerableObjectCollection)))
|
||||
return;
|
||||
|
||||
for (auto& task : tasks) {
|
||||
CComPtr<IShellLink> link;
|
||||
if (FAILED(link.CoCreateInstance(CLSID_ShellLink)) ||
|
||||
FAILED(link->SetPath(task.program.value().c_str())) ||
|
||||
FAILED(link->SetArguments(task.arguments.c_str())) ||
|
||||
FAILED(link->SetDescription(task.description.c_str())))
|
||||
return;
|
||||
|
||||
if (!task.icon_path.empty() &&
|
||||
FAILED(link->SetIconLocation(task.icon_path.value().c_str(),
|
||||
task.icon_index)))
|
||||
return;
|
||||
|
||||
CComQIPtr<IPropertyStore> property_store = link;
|
||||
if (!base::win::SetStringValueForPropertyStore(property_store, PKEY_Title,
|
||||
task.title.c_str()))
|
||||
return;
|
||||
|
||||
if (FAILED(collection->AddObject(link)))
|
||||
return;
|
||||
}
|
||||
|
||||
// When the list is empty "AddUserTasks" could fail, so we don't check return
|
||||
// value for it.
|
||||
CComQIPtr<IObjectArray> task_array = collection;
|
||||
destinations->AddUserTasks(task_array);
|
||||
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());
|
||||
}
|
||||
|
||||
std::string Browser::GetExecutableFileVersion() const {
|
||||
base::FilePath path;
|
||||
if (PathService::Get(base::FILE_EXE, &path)) {
|
||||
scoped_ptr<FileVersionInfo> version_info(
|
||||
FileVersionInfo::CreateFileVersionInfo(path));
|
||||
return UTF16ToUTF8(version_info->product_version());
|
||||
return base::UTF16ToUTF8(version_info->product_version());
|
||||
}
|
||||
|
||||
return ATOM_VERSION_STRING;
|
||||
@@ -55,10 +139,10 @@ std::string Browser::GetExecutableFileProductName() const {
|
||||
if (PathService::Get(base::FILE_EXE, &path)) {
|
||||
scoped_ptr<FileVersionInfo> version_info(
|
||||
FileVersionInfo::CreateFileVersionInfo(path));
|
||||
return UTF16ToUTF8(version_info->product_name());
|
||||
return base::UTF16ToUTF8(version_info->product_name());
|
||||
}
|
||||
|
||||
return "Atom-Shell";
|
||||
return ATOM_PRODUCT_NAME;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
335
atom/browser/common_web_contents_delegate.cc
Normal file
335
atom/browser/common_web_contents_delegate.cc
Normal file
@@ -0,0 +1,335 @@
|
||||
// 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/common_web_contents_delegate.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/atom_javascript_dialog_manager.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "atom/browser/web_dialog_helper.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "chrome/browser/ui/browser_dialogs.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "storage/browser/fileapi/isolated_context.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
struct FileSystem {
|
||||
FileSystem() {
|
||||
}
|
||||
FileSystem(const std::string& file_system_name,
|
||||
const std::string& root_url,
|
||||
const std::string& file_system_path)
|
||||
: file_system_name(file_system_name),
|
||||
root_url(root_url),
|
||||
file_system_path(file_system_path) {
|
||||
}
|
||||
|
||||
std::string file_system_name;
|
||||
std::string root_url;
|
||||
std::string file_system_path;
|
||||
};
|
||||
|
||||
std::string RegisterFileSystem(content::WebContents* web_contents,
|
||||
const base::FilePath& path,
|
||||
std::string* registered_name) {
|
||||
auto isolated_context = storage::IsolatedContext::GetInstance();
|
||||
std::string file_system_id = isolated_context->RegisterFileSystemForPath(
|
||||
storage::kFileSystemTypeNativeLocal,
|
||||
std::string(),
|
||||
path,
|
||||
registered_name);
|
||||
|
||||
content::ChildProcessSecurityPolicy* policy =
|
||||
content::ChildProcessSecurityPolicy::GetInstance();
|
||||
content::RenderViewHost* render_view_host = web_contents->GetRenderViewHost();
|
||||
int renderer_id = render_view_host->GetProcess()->GetID();
|
||||
policy->GrantReadFileSystem(renderer_id, file_system_id);
|
||||
policy->GrantWriteFileSystem(renderer_id, file_system_id);
|
||||
policy->GrantCreateFileForFileSystem(renderer_id, file_system_id);
|
||||
policy->GrantDeleteFromFileSystem(renderer_id, file_system_id);
|
||||
|
||||
if (!policy->CanReadFile(renderer_id, path))
|
||||
policy->GrantReadFile(renderer_id, path);
|
||||
|
||||
return file_system_id;
|
||||
}
|
||||
|
||||
FileSystem CreateFileSystemStruct(
|
||||
content::WebContents* web_contents,
|
||||
const std::string& file_system_id,
|
||||
const std::string& registered_name,
|
||||
const std::string& file_system_path) {
|
||||
const GURL origin = web_contents->GetURL().GetOrigin();
|
||||
std::string file_system_name =
|
||||
storage::GetIsolatedFileSystemName(origin, file_system_id);
|
||||
std::string root_url = storage::GetIsolatedFileSystemRootURIString(
|
||||
origin, file_system_id, registered_name);
|
||||
return FileSystem(file_system_name, root_url, file_system_path);
|
||||
}
|
||||
|
||||
base::DictionaryValue* CreateFileSystemValue(const FileSystem& file_system) {
|
||||
base::DictionaryValue* file_system_value = new base::DictionaryValue();
|
||||
file_system_value->SetString("fileSystemName", file_system.file_system_name);
|
||||
file_system_value->SetString("rootURL", file_system.root_url);
|
||||
file_system_value->SetString("fileSystemPath", file_system.file_system_path);
|
||||
return file_system_value;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CommonWebContentsDelegate::CommonWebContentsDelegate(bool is_guest)
|
||||
: is_guest_(is_guest),
|
||||
owner_window_(nullptr),
|
||||
html_fullscreen_(false),
|
||||
native_fullscreen_(false) {
|
||||
}
|
||||
|
||||
CommonWebContentsDelegate::~CommonWebContentsDelegate() {
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::InitWithWebContents(
|
||||
content::WebContents* web_contents,
|
||||
NativeWindow* owner_window) {
|
||||
owner_window_ = owner_window;
|
||||
web_contents->SetDelegate(this);
|
||||
|
||||
// Create InspectableWebContents.
|
||||
web_contents_.reset(brightray::InspectableWebContents::Create(web_contents));
|
||||
web_contents_->SetDelegate(this);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DestroyWebContents() {
|
||||
web_contents_.reset();
|
||||
}
|
||||
|
||||
content::WebContents* CommonWebContentsDelegate::GetWebContents() const {
|
||||
if (!web_contents_)
|
||||
return nullptr;
|
||||
return web_contents_->GetWebContents();
|
||||
}
|
||||
|
||||
content::WebContents*
|
||||
CommonWebContentsDelegate::GetDevToolsWebContents() const {
|
||||
if (!web_contents_)
|
||||
return nullptr;
|
||||
return web_contents_->GetDevToolsWebContents();
|
||||
}
|
||||
|
||||
content::WebContents* CommonWebContentsDelegate::OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) {
|
||||
content::NavigationController::LoadURLParams load_url_params(params.url);
|
||||
load_url_params.referrer = params.referrer;
|
||||
load_url_params.transition_type = params.transition;
|
||||
load_url_params.extra_headers = params.extra_headers;
|
||||
load_url_params.should_replace_current_entry =
|
||||
params.should_replace_current_entry;
|
||||
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
|
||||
load_url_params.transferred_global_request_id =
|
||||
params.transferred_global_request_id;
|
||||
load_url_params.should_clear_history_list = true;
|
||||
|
||||
source->GetController().LoadURLWithParams(load_url_params);
|
||||
return source;
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::RequestToLockMouse(
|
||||
content::WebContents* web_contents,
|
||||
bool user_gesture,
|
||||
bool last_unlocked_by_target) {
|
||||
GetWebContents()->GotResponseToLockMouseRequest(true);
|
||||
}
|
||||
|
||||
bool CommonWebContentsDelegate::CanOverscrollContent() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CommonWebContentsDelegate::IsPopupOrPanel(
|
||||
const content::WebContents* source) const {
|
||||
return !is_guest_;
|
||||
}
|
||||
|
||||
content::JavaScriptDialogManager*
|
||||
CommonWebContentsDelegate::GetJavaScriptDialogManager(
|
||||
content::WebContents* source) {
|
||||
if (!dialog_manager_)
|
||||
dialog_manager_.reset(new AtomJavaScriptDialogManager);
|
||||
|
||||
return dialog_manager_.get();
|
||||
}
|
||||
|
||||
content::ColorChooser* CommonWebContentsDelegate::OpenColorChooser(
|
||||
content::WebContents* web_contents,
|
||||
SkColor color,
|
||||
const std::vector<content::ColorSuggestion>& suggestions) {
|
||||
return chrome::ShowColorChooser(web_contents, color);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::RunFileChooser(
|
||||
content::WebContents* guest,
|
||||
const content::FileChooserParams& params) {
|
||||
if (!web_dialog_helper_)
|
||||
web_dialog_helper_.reset(new WebDialogHelper(owner_window_));
|
||||
web_dialog_helper_->RunFileChooser(guest, params);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::EnumerateDirectory(content::WebContents* guest,
|
||||
int request_id,
|
||||
const base::FilePath& path) {
|
||||
if (!web_dialog_helper_)
|
||||
web_dialog_helper_.reset(new WebDialogHelper(owner_window_));
|
||||
web_dialog_helper_->EnumerateDirectory(guest, request_id, path);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::EnterFullscreenModeForTab(
|
||||
content::WebContents* source, const GURL& origin) {
|
||||
if (!owner_window_)
|
||||
return;
|
||||
SetHtmlApiFullscreen(true);
|
||||
owner_window_->NotifyWindowEnterHtmlFullScreen();
|
||||
source->GetRenderViewHost()->WasResized();
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::ExitFullscreenModeForTab(
|
||||
content::WebContents* source) {
|
||||
if (!owner_window_)
|
||||
return;
|
||||
SetHtmlApiFullscreen(false);
|
||||
owner_window_->NotifyWindowLeaveHtmlFullScreen();
|
||||
source->GetRenderViewHost()->WasResized();
|
||||
}
|
||||
|
||||
bool CommonWebContentsDelegate::IsFullscreenForTabOrPending(
|
||||
const content::WebContents* source) const {
|
||||
return html_fullscreen_;
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsSaveToFile(
|
||||
const std::string& url, const std::string& content, bool save_as) {
|
||||
base::FilePath path;
|
||||
PathsMap::iterator it = saved_files_.find(url);
|
||||
if (it != saved_files_.end() && !save_as) {
|
||||
path = it->second;
|
||||
} else {
|
||||
file_dialog::Filters filters;
|
||||
base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url));
|
||||
if (!file_dialog::ShowSaveDialog(owner_window_, url, default_path,
|
||||
filters, &path)) {
|
||||
base::StringValue url_value(url);
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.canceledSaveURL", &url_value, nullptr, nullptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
saved_files_[url] = path;
|
||||
base::WriteFile(path, content.data(), content.size());
|
||||
|
||||
// Notify devtools.
|
||||
base::StringValue url_value(url);
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.savedURL", &url_value, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsAppendToFile(
|
||||
const std::string& url, const std::string& content) {
|
||||
PathsMap::iterator it = saved_files_.find(url);
|
||||
if (it == saved_files_.end())
|
||||
return;
|
||||
base::AppendToFile(it->second, content.data(), content.size());
|
||||
|
||||
// Notify devtools.
|
||||
base::StringValue url_value(url);
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.appendedToURL", &url_value, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsAddFileSystem() {
|
||||
file_dialog::Filters filters;
|
||||
base::FilePath default_path;
|
||||
std::vector<base::FilePath> paths;
|
||||
int flag = file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
|
||||
if (!file_dialog::ShowOpenDialog(owner_window_, "", default_path,
|
||||
filters, flag, &paths))
|
||||
return;
|
||||
|
||||
base::FilePath path = paths[0];
|
||||
std::string registered_name;
|
||||
std::string file_system_id = RegisterFileSystem(GetDevToolsWebContents(),
|
||||
path,
|
||||
®istered_name);
|
||||
|
||||
WorkspaceMap::iterator it = saved_paths_.find(file_system_id);
|
||||
if (it != saved_paths_.end())
|
||||
return;
|
||||
|
||||
saved_paths_[file_system_id] = path;
|
||||
|
||||
FileSystem file_system = CreateFileSystemStruct(GetDevToolsWebContents(),
|
||||
file_system_id,
|
||||
registered_name,
|
||||
path.AsUTF8Unsafe());
|
||||
|
||||
scoped_ptr<base::StringValue> error_string_value(
|
||||
new base::StringValue(std::string()));
|
||||
scoped_ptr<base::DictionaryValue> file_system_value;
|
||||
if (!file_system.file_system_path.empty())
|
||||
file_system_value.reset(CreateFileSystemValue(file_system));
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.fileSystemAdded",
|
||||
error_string_value.get(),
|
||||
file_system_value.get(),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsRemoveFileSystem(
|
||||
const std::string& file_system_path) {
|
||||
if (!web_contents_)
|
||||
return;
|
||||
|
||||
base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path);
|
||||
storage::IsolatedContext::GetInstance()->RevokeFileSystemByPath(path);
|
||||
|
||||
for (auto it = saved_paths_.begin(); it != saved_paths_.end(); ++it)
|
||||
if (it->second == path) {
|
||||
saved_paths_.erase(it);
|
||||
break;
|
||||
}
|
||||
|
||||
base::StringValue file_system_path_value(file_system_path);
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.fileSystemRemoved",
|
||||
&file_system_path_value,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::SetHtmlApiFullscreen(bool enter_fullscreen) {
|
||||
// Window is already in fullscreen mode, save the state.
|
||||
if (enter_fullscreen && owner_window_->IsFullscreen()) {
|
||||
native_fullscreen_ = true;
|
||||
html_fullscreen_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Exit html fullscreen state but not window's fullscreen mode.
|
||||
if (!enter_fullscreen && native_fullscreen_) {
|
||||
html_fullscreen_ = false;
|
||||
return;
|
||||
}
|
||||
|
||||
owner_window_->SetFullScreen(enter_fullscreen);
|
||||
html_fullscreen_ = enter_fullscreen;
|
||||
native_fullscreen_ = false;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
124
atom/browser/common_web_contents_delegate.h
Normal file
124
atom/browser/common_web_contents_delegate.h
Normal file
@@ -0,0 +1,124 @@
|
||||
// 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_COMMON_WEB_CONTENTS_DELEGATE_H_
|
||||
#define ATOM_BROWSER_COMMON_WEB_CONTENTS_DELEGATE_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "brightray/browser/default_web_contents_delegate.h"
|
||||
#include "brightray/browser/inspectable_web_contents_impl.h"
|
||||
#include "brightray/browser/inspectable_web_contents_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomJavaScriptDialogManager;
|
||||
class NativeWindow;
|
||||
class WebDialogHelper;
|
||||
|
||||
class CommonWebContentsDelegate
|
||||
: public brightray::DefaultWebContentsDelegate,
|
||||
public brightray::InspectableWebContentsDelegate {
|
||||
public:
|
||||
explicit CommonWebContentsDelegate(bool is_guest);
|
||||
virtual ~CommonWebContentsDelegate();
|
||||
|
||||
// Create a InspectableWebContents object and takes onwership of
|
||||
// |web_contents|.
|
||||
void InitWithWebContents(content::WebContents* web_contents,
|
||||
NativeWindow* owner_window);
|
||||
|
||||
// Destroy the managed InspectableWebContents object.
|
||||
void DestroyWebContents();
|
||||
|
||||
// Returns the WebContents managed by this delegate.
|
||||
content::WebContents* GetWebContents() const;
|
||||
|
||||
// Returns the WebContents of devtools.
|
||||
content::WebContents* GetDevToolsWebContents() const;
|
||||
|
||||
brightray::InspectableWebContents* managed_web_contents() const {
|
||||
return web_contents_.get();
|
||||
}
|
||||
|
||||
bool is_guest() const { return is_guest_; }
|
||||
|
||||
protected:
|
||||
// content::WebContentsDelegate:
|
||||
content::WebContents* OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) override;
|
||||
void RequestToLockMouse(content::WebContents* web_contents,
|
||||
bool user_gesture,
|
||||
bool last_unlocked_by_target) override;
|
||||
bool CanOverscrollContent() const override;
|
||||
bool IsPopupOrPanel(const content::WebContents* source) const override;
|
||||
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
|
||||
content::WebContents* source) override;
|
||||
content::ColorChooser* OpenColorChooser(
|
||||
content::WebContents* web_contents,
|
||||
SkColor color,
|
||||
const std::vector<content::ColorSuggestion>& suggestions) override;
|
||||
void RunFileChooser(content::WebContents* web_contents,
|
||||
const content::FileChooserParams& params) override;
|
||||
void EnumerateDirectory(content::WebContents* web_contents,
|
||||
int request_id,
|
||||
const base::FilePath& path) override;
|
||||
void EnterFullscreenModeForTab(content::WebContents* source,
|
||||
const GURL& origin) override;
|
||||
void ExitFullscreenModeForTab(content::WebContents* source) override;
|
||||
bool IsFullscreenForTabOrPending(
|
||||
const content::WebContents* source) const override;
|
||||
|
||||
// brightray::InspectableWebContentsDelegate:
|
||||
void DevToolsSaveToFile(const std::string& url,
|
||||
const std::string& content,
|
||||
bool save_as) override;
|
||||
void DevToolsAppendToFile(const std::string& url,
|
||||
const std::string& content) override;
|
||||
void DevToolsAddFileSystem() override;
|
||||
void DevToolsRemoveFileSystem(const std::string& file_system_path) override;
|
||||
|
||||
private:
|
||||
// Set fullscreen mode triggered by html api.
|
||||
void SetHtmlApiFullscreen(bool enter_fullscreen);
|
||||
|
||||
// Whether this is guest WebContents or NativeWindow.
|
||||
const bool is_guest_;
|
||||
|
||||
// The window that this WebContents belongs to.
|
||||
NativeWindow* owner_window_;
|
||||
|
||||
// Whether window is fullscreened by HTML5 api.
|
||||
bool html_fullscreen_;
|
||||
|
||||
// Whether window is fullscreened by window api.
|
||||
bool native_fullscreen_;
|
||||
|
||||
scoped_ptr<WebDialogHelper> web_dialog_helper_;
|
||||
scoped_ptr<AtomJavaScriptDialogManager> dialog_manager_;
|
||||
|
||||
// The stored InspectableWebContents object.
|
||||
// Notice that web_contents_ must be placed after dialog_manager_, so we can
|
||||
// make sure web_contents_ is destroyed before dialog_manager_, otherwise a
|
||||
// crash would happen.
|
||||
scoped_ptr<brightray::InspectableWebContents> web_contents_;
|
||||
|
||||
// Maps url to file path, used by the file requests sent from devtools.
|
||||
typedef std::map<std::string, base::FilePath> PathsMap;
|
||||
PathsMap saved_files_;
|
||||
|
||||
// Maps file system id to file path, used by the file system requests
|
||||
// sent from devtools.
|
||||
typedef std::map<std::string, base::FilePath> WorkspaceMap;
|
||||
WorkspaceMap saved_paths_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CommonWebContentsDelegate);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_COMMON_WEB_CONTENTS_DELEGATE_H_
|
||||
@@ -1,10 +1,7 @@
|
||||
var app = require('app');
|
||||
var Menu = require('menu');
|
||||
var MenuItem = require('menu-item');
|
||||
var BrowserWindow = require('browser-window');
|
||||
|
||||
var mainWindow = null;
|
||||
var menu = null;
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function() {
|
||||
@@ -12,172 +9,12 @@ app.on('window-all-closed', function() {
|
||||
});
|
||||
|
||||
app.on('ready', function() {
|
||||
app.commandLine.appendSwitch('js-flags', '--harmony_collections');
|
||||
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
'auto-hide-menu-bar': true,
|
||||
'use-content-size': true,
|
||||
});
|
||||
mainWindow.loadUrl('file://' + __dirname + '/index.html');
|
||||
|
||||
if (process.platform == 'darwin') {
|
||||
var template = [
|
||||
{
|
||||
label: 'Atom Shell',
|
||||
submenu: [
|
||||
{
|
||||
label: 'About Atom Shell',
|
||||
selector: 'orderFrontStandardAboutPanel:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Hide Atom Shell',
|
||||
accelerator: 'Command+H',
|
||||
selector: 'hide:'
|
||||
},
|
||||
{
|
||||
label: 'Hide Others',
|
||||
accelerator: 'Command+Shift+H',
|
||||
selector: 'hideOtherApplications:'
|
||||
},
|
||||
{
|
||||
label: 'Show All',
|
||||
selector: 'unhideAllApplications:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'Command+Q',
|
||||
click: function() { app.quit(); }
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Undo',
|
||||
accelerator: 'Command+Z',
|
||||
selector: 'undo:'
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
accelerator: 'Shift+Command+Z',
|
||||
selector: 'redo:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Cut',
|
||||
accelerator: 'Command+X',
|
||||
selector: 'cut:'
|
||||
},
|
||||
{
|
||||
label: 'Copy',
|
||||
accelerator: 'Command+C',
|
||||
selector: 'copy:'
|
||||
},
|
||||
{
|
||||
label: 'Paste',
|
||||
accelerator: 'Command+V',
|
||||
selector: 'paste:'
|
||||
},
|
||||
{
|
||||
label: 'Select All',
|
||||
accelerator: 'Command+A',
|
||||
selector: 'selectAll:'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'Command+R',
|
||||
click: function() { mainWindow.restart(); }
|
||||
},
|
||||
{
|
||||
label: 'Enter Fullscreen',
|
||||
click: function() { mainWindow.setFullscreen(true); }
|
||||
},
|
||||
{
|
||||
label: 'Toggle DevTools',
|
||||
accelerator: 'Alt+Command+I',
|
||||
click: function() { mainWindow.toggleDevTools(); }
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Window',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Minimize',
|
||||
accelerator: 'Command+M',
|
||||
selector: 'performMiniaturize:'
|
||||
},
|
||||
{
|
||||
label: 'Close',
|
||||
accelerator: 'Command+W',
|
||||
selector: 'performClose:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Bring All to Front',
|
||||
selector: 'arrangeInFront:'
|
||||
},
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
menu = Menu.buildFromTemplate(template);
|
||||
Menu.setApplicationMenu(menu);
|
||||
} else {
|
||||
var template = [
|
||||
{
|
||||
label: 'File',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Open',
|
||||
accelerator: 'Ctrl+O',
|
||||
},
|
||||
{
|
||||
label: 'Close',
|
||||
accelerator: 'Ctrl+W',
|
||||
click: function() { mainWindow.close(); }
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'Ctrl+R',
|
||||
click: function() { mainWindow.restart(); }
|
||||
},
|
||||
{
|
||||
label: 'Enter Fullscreen',
|
||||
click: function() { mainWindow.setFullScreen(true); }
|
||||
},
|
||||
{
|
||||
label: 'Toggle DevTools',
|
||||
accelerator: 'Alt+Ctrl+I',
|
||||
click: function() { mainWindow.toggleDevTools(); }
|
||||
},
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
menu = Menu.buildFromTemplate(template);
|
||||
mainWindow.setMenu(menu);
|
||||
}
|
||||
mainWindow.focus();
|
||||
});
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Atom Shell</title>
|
||||
<title>Electron</title>
|
||||
<style>
|
||||
html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #555;
|
||||
font-family: 'Open Sans',Helvetica,Arial,sans-serif;
|
||||
@@ -78,19 +72,19 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<h2>Welcome to Atom Shell</h2>
|
||||
<h2 style="-webkit-app-region: drag">Welcome to Electron</h2>
|
||||
|
||||
<p>
|
||||
To run your app with atom-shell, execute the following command under your
|
||||
To run your app with Electron, execute the following command under your
|
||||
Console (or Terminal):
|
||||
</p>
|
||||
|
||||
<script>document.write('<pre>' + command + '</pre>')</script>
|
||||
|
||||
<p>
|
||||
The <code>path-to-your-app</code> should be the path to your own atom-shell
|
||||
app, you can read the <a href='https://github.com/atom/atom-shell/blob/master/docs/tutorial/quick-start.md'>quick start</a>
|
||||
guide in atom-shell's <a href='https://github.com/atom/atom-shell/blob/master/docs'>docs</a>
|
||||
The <code>path-to-your-app</code> should be the path to your own Electron
|
||||
app, you can read the <a href='https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md'>quick start</a>
|
||||
guide in Electron's <a href='https://github.com/atom/electron/blob/master/docs'>docs</a>
|
||||
on how to write one.
|
||||
</p>
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
var app = require('app');
|
||||
var dialog = require('dialog');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var optimist = require('optimist');
|
||||
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() {
|
||||
@@ -9,31 +11,309 @@ app.on('window-all-closed', function() {
|
||||
app.quit();
|
||||
});
|
||||
|
||||
var argv = optimist(process.argv.slice(1)).boolean('ci').argv;
|
||||
// Parse command line options.
|
||||
var argv = process.argv.slice(1);
|
||||
var option = { file: null, help: null, version: null, webdriver: null };
|
||||
for (var i in argv) {
|
||||
if (argv[i] == '--version' || argv[i] == '-v') {
|
||||
option.version = true;
|
||||
break;
|
||||
} else if (argv[i] == '--help' || argv[i] == '-h') {
|
||||
option.help = true;
|
||||
break;
|
||||
} else if (argv[i] == '--test-type=webdriver') {
|
||||
option.webdriver = true;
|
||||
} else if (argv[i][0] == '-') {
|
||||
continue;
|
||||
} else {
|
||||
option.file = argv[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create default menu.
|
||||
app.once('ready', function() {
|
||||
var template;
|
||||
if (process.platform == 'darwin') {
|
||||
template = [
|
||||
{
|
||||
label: 'Electron',
|
||||
submenu: [
|
||||
{
|
||||
label: 'About Electron',
|
||||
selector: 'orderFrontStandardAboutPanel:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Services',
|
||||
submenu: []
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Hide Electron',
|
||||
accelerator: 'Command+H',
|
||||
selector: 'hide:'
|
||||
},
|
||||
{
|
||||
label: 'Hide Others',
|
||||
accelerator: 'Command+Shift+H',
|
||||
selector: 'hideOtherApplications:'
|
||||
},
|
||||
{
|
||||
label: 'Show All',
|
||||
selector: 'unhideAllApplications:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'Command+Q',
|
||||
click: function() { app.quit(); }
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Undo',
|
||||
accelerator: 'Command+Z',
|
||||
selector: 'undo:'
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
accelerator: 'Shift+Command+Z',
|
||||
selector: 'redo:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Cut',
|
||||
accelerator: 'Command+X',
|
||||
selector: 'cut:'
|
||||
},
|
||||
{
|
||||
label: 'Copy',
|
||||
accelerator: 'Command+C',
|
||||
selector: 'copy:'
|
||||
},
|
||||
{
|
||||
label: 'Paste',
|
||||
accelerator: 'Command+V',
|
||||
selector: 'paste:'
|
||||
},
|
||||
{
|
||||
label: 'Select All',
|
||||
accelerator: 'Command+A',
|
||||
selector: 'selectAll:'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'Command+R',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.reload();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle Full Screen',
|
||||
accelerator: 'Ctrl+Command+F',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle Developer Tools',
|
||||
accelerator: 'Alt+Command+I',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.toggleDevTools();
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Window',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Minimize',
|
||||
accelerator: 'Command+M',
|
||||
selector: 'performMiniaturize:'
|
||||
},
|
||||
{
|
||||
label: 'Close',
|
||||
accelerator: 'Command+W',
|
||||
selector: 'performClose:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Bring All to Front',
|
||||
selector: 'arrangeInFront:'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click: function() { require('shell').openExternal('http://electron.atom.io') }
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
click: function() { require('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') }
|
||||
},
|
||||
{
|
||||
label: 'Search Issues',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') }
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
} else {
|
||||
template = [
|
||||
{
|
||||
label: '&File',
|
||||
submenu: [
|
||||
{
|
||||
label: '&Open',
|
||||
accelerator: 'Ctrl+O',
|
||||
},
|
||||
{
|
||||
label: '&Close',
|
||||
accelerator: 'Ctrl+W',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.close();
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '&View',
|
||||
submenu: [
|
||||
{
|
||||
label: '&Reload',
|
||||
accelerator: 'Ctrl+R',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.reload();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle &Full Screen',
|
||||
accelerator: 'F11',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle &Developer Tools',
|
||||
accelerator: 'Alt+Ctrl+I',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.toggleDevTools();
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click: function() { require('shell').openExternal('http://electron.atom.io') }
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
click: function() { require('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') }
|
||||
},
|
||||
{
|
||||
label: 'Search Issues',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') }
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
var menu = Menu.buildFromTemplate(template);
|
||||
Menu.setApplicationMenu(menu);
|
||||
});
|
||||
|
||||
// Start the specified app if there is one specified in command line, otherwise
|
||||
// start the default app.
|
||||
if (argv._.length > 0) {
|
||||
if (option.file && !option.webdriver) {
|
||||
try {
|
||||
require(path.resolve(argv._[0]));
|
||||
// Override app name and version.
|
||||
var packagePath = path.resolve(option.file);
|
||||
var packageJsonPath = path.join(packagePath, 'package.json');
|
||||
if (fs.existsSync(packageJsonPath)) {
|
||||
var packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
|
||||
if (packageJson.version)
|
||||
app.setVersion(packageJson.version);
|
||||
if (packageJson.productName)
|
||||
app.setName(packageJson.productName);
|
||||
else if (packageJson.name)
|
||||
app.setName(packageJson.name);
|
||||
app.setPath('userData', path.join(app.getPath('appData'), app.getName()));
|
||||
app.setPath('userCache', path.join(app.getPath('cache'), app.getName()));
|
||||
}
|
||||
|
||||
// Run the app.
|
||||
require('module')._load(packagePath, module, true);
|
||||
} catch(e) {
|
||||
if (e.code == 'MODULE_NOT_FOUND') {
|
||||
app.focus();
|
||||
dialog.showMessageBox({
|
||||
type: 'warning',
|
||||
buttons: ['OK'],
|
||||
title: 'Error opening app',
|
||||
message: 'The app provided is not a valid atom-shell app, please read the docs on how to write one:',
|
||||
detail: 'https://github.com/atom/atom-shell/tree/master/docs'
|
||||
});
|
||||
dialog.showErrorBox('Error opening app', 'The app provided is not a valid electron app, please read the docs on how to write one:\nhttps://github.com/atom/electron/tree/master/docs\n\n' + e.toString());
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.error('App throwed an error when running', e);
|
||||
console.error('App threw an error when running', e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} else if (argv.version) {
|
||||
console.log('v' + process.versions['atom-shell']);
|
||||
} else if (option.version) {
|
||||
console.log('v' + process.versions.electron);
|
||||
process.exit(0);
|
||||
} else if (option.help) {
|
||||
var helpMessage = "Electron v" + process.versions.electron + " - Cross Platform Desktop Application Shell\n\n";
|
||||
helpMessage += "Usage: electron [options] [path]\n\n";
|
||||
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 += " -h, --help Print this usage message.\n";
|
||||
helpMessage += " -v, --version Print the version.";
|
||||
console.log(helpMessage);
|
||||
process.exit(0);
|
||||
} else {
|
||||
require('./default_app.js');
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user