mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
4696 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0528c5049 | ||
|
|
5de1b20935 | ||
|
|
7884a2319c | ||
|
|
6f944ad49b | ||
|
|
94e5018a47 | ||
|
|
4a64d1d946 | ||
|
|
004d3ced53 | ||
|
|
109d8352e1 | ||
|
|
01f0643142 | ||
|
|
a0638fe801 | ||
|
|
ecefd3540b | ||
|
|
06cc133959 | ||
|
|
da57a3101f | ||
|
|
fc422e5d55 | ||
|
|
10731de9d6 | ||
|
|
c73d1ce6c7 | ||
|
|
83481a369a | ||
|
|
1879392c7b | ||
|
|
39695cdb85 | ||
|
|
0861d5d44b | ||
|
|
62604708d1 | ||
|
|
e3fab8b5b3 | ||
|
|
497732fb6f | ||
|
|
fe2d9ee0f6 | ||
|
|
5d26bc08ee | ||
|
|
5ca5c4fb92 | ||
|
|
576257470b | ||
|
|
269f70c12a | ||
|
|
9e90ea8734 | ||
|
|
9b1fa04988 | ||
|
|
d621755f13 | ||
|
|
e3ec705c80 | ||
|
|
b0e5039951 | ||
|
|
22e6f15795 | ||
|
|
1520ebfe1f | ||
|
|
142702866d | ||
|
|
334c28d128 | ||
|
|
057c77341a | ||
|
|
706deae1b0 | ||
|
|
f8f8db7e88 | ||
|
|
6c01cec8d2 | ||
|
|
d8062ab9e1 | ||
|
|
748b1387d2 | ||
|
|
6c8a9cb072 | ||
|
|
7165aa5467 | ||
|
|
8bfa3cba63 | ||
|
|
f2fa0e96eb | ||
|
|
d0d71efb0b | ||
|
|
486f16fffa | ||
|
|
e499bb14de | ||
|
|
4521db459b | ||
|
|
de41890196 | ||
|
|
a6b7dd22e8 | ||
|
|
f06f8ae73b | ||
|
|
9cbdde2eba | ||
|
|
f07fea1936 | ||
|
|
7c65d05b02 | ||
|
|
619a397ec9 | ||
|
|
889d7c1e02 | ||
|
|
4cccce6bfe | ||
|
|
4a91972037 | ||
|
|
42515c6f41 | ||
|
|
eccb5e7590 | ||
|
|
008af00044 | ||
|
|
325feca864 | ||
|
|
5ef9c7e1a1 | ||
|
|
22168bc6d8 | ||
|
|
62d64e7528 | ||
|
|
477103191f | ||
|
|
57bf0cb615 | ||
|
|
01a3bf5881 | ||
|
|
a69c9600ce | ||
|
|
a567d7a0b6 | ||
|
|
7807d878d2 | ||
|
|
a69121fc24 | ||
|
|
be600fda55 | ||
|
|
35fc8885de | ||
|
|
717e0f9821 | ||
|
|
997ac91fe0 | ||
|
|
4391e81dfe | ||
|
|
d0ee30101d | ||
|
|
dd38131704 | ||
|
|
40b861bc9c | ||
|
|
5ec74451ef | ||
|
|
87b9b0bc31 | ||
|
|
76b7cd0908 | ||
|
|
c626ee6e92 | ||
|
|
94b6b92e4c | ||
|
|
6cf6cb9a79 | ||
|
|
7bb9595b81 | ||
|
|
f716d47e54 | ||
|
|
353cdd967a | ||
|
|
32bff05208 | ||
|
|
b8d50f3a3a | ||
|
|
7b2980434c | ||
|
|
ff0e15bf58 | ||
|
|
1e918480b4 | ||
|
|
573892c112 | ||
|
|
86f523d3c1 | ||
|
|
42863e4700 | ||
|
|
9e7de78231 | ||
|
|
c550546ff1 | ||
|
|
5a599cb6ff | ||
|
|
84ce441fb6 | ||
|
|
d7bac5a10b | ||
|
|
ec90d03d74 | ||
|
|
ee0d48dc5a | ||
|
|
15394b9a3b | ||
|
|
5aa7cf7a30 | ||
|
|
7dc7ee1c41 | ||
|
|
96d35ec29e | ||
|
|
91796e7095 | ||
|
|
75b0d0cd6c | ||
|
|
6b875110ed | ||
|
|
1348e18a81 | ||
|
|
c700c58793 | ||
|
|
a46cb8cebb | ||
|
|
01ed2c4222 | ||
|
|
d28789b509 | ||
|
|
2be6bdcf4a | ||
|
|
5604655d54 | ||
|
|
93639a080c | ||
|
|
e30dd943db | ||
|
|
a386bb4edf | ||
|
|
ce8eb4a32c | ||
|
|
e73c655d65 | ||
|
|
e3c64d7971 | ||
|
|
9fd5a64cd8 | ||
|
|
ec7ea3005d | ||
|
|
3f881e8617 | ||
|
|
cb13d8bdc7 | ||
|
|
11ee2c47d0 | ||
|
|
7b75b29265 | ||
|
|
b9c274929b | ||
|
|
842ec3d11b | ||
|
|
244e184b7e | ||
|
|
a3a9bbb979 | ||
|
|
57c910faef | ||
|
|
90064eeddd | ||
|
|
08f5c32306 | ||
|
|
69cc3ab5ef | ||
|
|
5269380b6d | ||
|
|
d8f77e5134 | ||
|
|
ceef06b344 | ||
|
|
a3e9ff67b0 | ||
|
|
ae776b523c | ||
|
|
10b1ea7244 | ||
|
|
6615787775 | ||
|
|
cf6008a05e | ||
|
|
f1787d747a | ||
|
|
eced01eb9d | ||
|
|
357c7af3c0 | ||
|
|
817363b955 | ||
|
|
311a5456ec | ||
|
|
3cf34fe40f | ||
|
|
2a3a65f67c | ||
|
|
c9ee6b4caf | ||
|
|
b72a5884f2 | ||
|
|
97857aa152 | ||
|
|
fe2219a635 | ||
|
|
c99ec368b3 | ||
|
|
9652ed6508 | ||
|
|
dc59b4fa06 | ||
|
|
a1ccfdf777 | ||
|
|
40d93ce55a | ||
|
|
377e7ee3a7 | ||
|
|
8a8b11cf10 | ||
|
|
e656d8428c | ||
|
|
238d4add99 | ||
|
|
3bf73bc455 | ||
|
|
9134b9cf43 | ||
|
|
dd7036035a | ||
|
|
6bae0bada0 | ||
|
|
f140f35910 | ||
|
|
a5dc911a05 | ||
|
|
5d8f1dd404 | ||
|
|
409b0b54e0 | ||
|
|
c006c4efa4 | ||
|
|
3ad5d17612 | ||
|
|
4d28fbf561 | ||
|
|
1533d97e16 | ||
|
|
ca8943c4ba | ||
|
|
8534ff4526 | ||
|
|
c346fcb326 | ||
|
|
9e7b67802c | ||
|
|
9d366e6c5c | ||
|
|
d2e52fb6bb | ||
|
|
baacc939f6 | ||
|
|
3bd16a5ecd | ||
|
|
7c3d3e4a87 | ||
|
|
e388163d33 | ||
|
|
654626305c | ||
|
|
989799633d | ||
|
|
bf01112acd | ||
|
|
af5262630a | ||
|
|
a1cd806955 | ||
|
|
ff67fae9ef | ||
|
|
b80aab3cf2 | ||
|
|
750d3e979c | ||
|
|
c3664463ab | ||
|
|
c6395c2197 | ||
|
|
39bd10d1ef | ||
|
|
9eca0f82de | ||
|
|
4b8472d3b4 | ||
|
|
aae2d82c28 | ||
|
|
6cfe43a644 | ||
|
|
2ac2392a6b | ||
|
|
7c287d565d | ||
|
|
31775aa049 | ||
|
|
9ca85a7859 | ||
|
|
b861a174ca | ||
|
|
92f7899c60 | ||
|
|
572199068b | ||
|
|
32a66fa94e | ||
|
|
60522e0d68 | ||
|
|
708526baec | ||
|
|
ae2f754d10 | ||
|
|
143453b603 | ||
|
|
d4cbf7cadb | ||
|
|
3ee854d9a3 | ||
|
|
442b0d5df3 | ||
|
|
c8954ff32c | ||
|
|
6321a3898c | ||
|
|
70af2e0bee | ||
|
|
626c7d1090 | ||
|
|
1497e7e2ac | ||
|
|
69769f9319 | ||
|
|
f807a8f1e7 | ||
|
|
b2af370249 | ||
|
|
c29a2e4992 | ||
|
|
279fd0a461 | ||
|
|
1a35d6bda6 | ||
|
|
5593717d78 | ||
|
|
6abc4fb255 | ||
|
|
e9712e2998 | ||
|
|
ce49bba2fc | ||
|
|
5089929be8 | ||
|
|
590be75fa9 | ||
|
|
0046970805 | ||
|
|
9dc6cfc1e9 | ||
|
|
749a1a3e9a | ||
|
|
93bbc0bca9 | ||
|
|
9d51da505e | ||
|
|
e48f5ea1aa | ||
|
|
e5496d9ac0 | ||
|
|
c2b2a2072f | ||
|
|
446235c8cd | ||
|
|
530b040ade | ||
|
|
375ac3e6ec | ||
|
|
a200718944 | ||
|
|
ba02e19fae | ||
|
|
8e1979a6a5 | ||
|
|
e5386cf8ea | ||
|
|
e597229750 | ||
|
|
8b3ed9067e | ||
|
|
40d4c65866 | ||
|
|
1ca6534dcd | ||
|
|
830bb54d6a | ||
|
|
785eb9657b | ||
|
|
21bd578935 | ||
|
|
1e0facc103 | ||
|
|
db3e27ceaa | ||
|
|
b521e45ef8 | ||
|
|
ad6e67fdfa | ||
|
|
564b74b19c | ||
|
|
62b1034c6b | ||
|
|
4412a89270 | ||
|
|
d4aa2308cd | ||
|
|
8912b404a9 | ||
|
|
d7ec0b99fd | ||
|
|
87e02f2858 | ||
|
|
66f7f2e6f2 | ||
|
|
13722e26cd | ||
|
|
e365cb6b1c | ||
|
|
46b2b91a27 | ||
|
|
24bbe5dabf | ||
|
|
3717f5b7f2 | ||
|
|
10bc0c20b1 | ||
|
|
0a4fb2ec4f | ||
|
|
8cc1046992 | ||
|
|
3669113ad2 | ||
|
|
aad1f5082f | ||
|
|
f56d715104 | ||
|
|
cd12dbd47e | ||
|
|
5830532a45 | ||
|
|
4537d88a58 | ||
|
|
342e0c6cf7 | ||
|
|
512f89910d | ||
|
|
e2bd1abce6 | ||
|
|
5eb0bedbbc | ||
|
|
2454dccde0 | ||
|
|
0b1a3f3ef3 | ||
|
|
fafb28e41a | ||
|
|
ba25bed45b | ||
|
|
3773f81fd5 | ||
|
|
f2bdca31b3 | ||
|
|
9c235509a6 | ||
|
|
b1afe538ee | ||
|
|
0b97d58a6f | ||
|
|
880dce950d | ||
|
|
39975378bb | ||
|
|
96771c7098 | ||
|
|
0e92a3e333 | ||
|
|
dd871812b7 | ||
|
|
81d423c547 | ||
|
|
943fe2c22d | ||
|
|
38e948f55b | ||
|
|
3e4ad4c696 | ||
|
|
0bc8e7b787 | ||
|
|
a8d56df41e | ||
|
|
41e1555cf4 | ||
|
|
dcbd8316df | ||
|
|
1a1b45e088 | ||
|
|
b980650b6e | ||
|
|
b9da81ee6a | ||
|
|
b797804fd9 | ||
|
|
0577e911b3 | ||
|
|
619c77f409 | ||
|
|
6c5c202a99 | ||
|
|
090c817ac9 | ||
|
|
f91a7e6d04 | ||
|
|
5d6ac2296b | ||
|
|
26dea993df | ||
|
|
eb8ac2b5d8 | ||
|
|
44528ce60e | ||
|
|
e72e09719a | ||
|
|
6f9d822472 | ||
|
|
67026cccc8 | ||
|
|
30c714a27f | ||
|
|
05031a38e5 | ||
|
|
ae8ffae59e | ||
|
|
587a9f1c5b | ||
|
|
bd264aa1ba | ||
|
|
9557ce523a | ||
|
|
f1e5a99881 | ||
|
|
03ba9533fb | ||
|
|
8f59c0b642 | ||
|
|
da5bac42f3 | ||
|
|
150b540e72 | ||
|
|
5189147021 | ||
|
|
d180d3b168 | ||
|
|
3f546e6bab | ||
|
|
c65ccb6857 | ||
|
|
e3504b2b24 | ||
|
|
53b9d61831 | ||
|
|
2c3751e287 | ||
|
|
4a81300100 | ||
|
|
73af4c017d | ||
|
|
2734d67a38 | ||
|
|
c81de98d22 | ||
|
|
599e9b90bb | ||
|
|
c1d7ad9631 | ||
|
|
ee0dc0d926 | ||
|
|
4254eb279f | ||
|
|
262b66b93a | ||
|
|
45491ca7ab | ||
|
|
1db843244d | ||
|
|
992aada90f | ||
|
|
c01d2fbbcd | ||
|
|
f75458f78d | ||
|
|
d6daea12af | ||
|
|
28e5258a96 | ||
|
|
f6d6a2a4c3 | ||
|
|
c56b78f0fa | ||
|
|
27b77a06ed | ||
|
|
357dea506a | ||
|
|
c2dcccf7c7 | ||
|
|
28764b0f77 | ||
|
|
66a1405d2b | ||
|
|
b3eb6dc32b | ||
|
|
3af2540fad | ||
|
|
2f41641139 | ||
|
|
131cd9cff6 | ||
|
|
bd20104e5a | ||
|
|
2e5a539f57 | ||
|
|
159b6ca611 | ||
|
|
3914ff2ac5 | ||
|
|
f12ccac17e | ||
|
|
f8d40a88fb | ||
|
|
e78db6ae07 | ||
|
|
e71d2bd8e7 | ||
|
|
ba7ddd66a1 | ||
|
|
f5f3278ffa | ||
|
|
bfa33de792 | ||
|
|
ae3ff4e1e3 | ||
|
|
0fa0aedd86 | ||
|
|
e6265ec405 | ||
|
|
6bce5b560b | ||
|
|
009b27f5f1 | ||
|
|
7d07f10c25 | ||
|
|
d830badc57 | ||
|
|
dbcd0a4235 | ||
|
|
47d103af72 | ||
|
|
91c75d73dd | ||
|
|
2ead38b03f | ||
|
|
dd2ed559cf | ||
|
|
ab726ec1f5 | ||
|
|
2c47532702 | ||
|
|
95133af0ee | ||
|
|
17cc43152d | ||
|
|
0cb20c48f6 | ||
|
|
4e7f56846f | ||
|
|
4062ca5f68 | ||
|
|
e043ea9c20 | ||
|
|
10b53f7f73 | ||
|
|
7acd3c1973 | ||
|
|
889c982918 | ||
|
|
c70513f7ce | ||
|
|
691d8dd9ab | ||
|
|
316210d6c4 | ||
|
|
dddb598818 | ||
|
|
50bfe9e335 | ||
|
|
a03df3ac5a | ||
|
|
05d0f17447 | ||
|
|
f31848563f | ||
|
|
d9c3830df7 | ||
|
|
cb4558e75b | ||
|
|
be73388918 | ||
|
|
6a2bd80a9a | ||
|
|
52916f70ed | ||
|
|
a5234224a6 | ||
|
|
c6269bf77a | ||
|
|
0e4ae6f864 | ||
|
|
96bb9b2757 | ||
|
|
e0a57a0a47 | ||
|
|
8cf1bc8457 | ||
|
|
eb3769f98e | ||
|
|
afff32dc8d | ||
|
|
ddee9f3e75 | ||
|
|
3dd3fd9200 | ||
|
|
625ee387f3 | ||
|
|
c59c0bd5b3 | ||
|
|
ebedb60684 | ||
|
|
9ecc4bcb7d | ||
|
|
b205bd381e | ||
|
|
af52eda0eb | ||
|
|
aed487ef40 | ||
|
|
50c7985ee2 | ||
|
|
00136a221f | ||
|
|
a6b86e924a | ||
|
|
ed01698444 | ||
|
|
6459531bef | ||
|
|
49b15bd4f3 | ||
|
|
c67268a74f | ||
|
|
2c79e9fd41 | ||
|
|
29c865f0e1 | ||
|
|
e0542945ce | ||
|
|
842ba6aea6 | ||
|
|
009e228218 | ||
|
|
d93b6c1cae | ||
|
|
2206279846 | ||
|
|
1e5b7af490 | ||
|
|
cb62afca23 | ||
|
|
254cdc0e6c | ||
|
|
2c6210cf9c | ||
|
|
3d4f0dfc44 | ||
|
|
874367e2c5 | ||
|
|
22652860a2 | ||
|
|
87db1e8802 | ||
|
|
8b6f3dc0aa | ||
|
|
9c46be9d47 | ||
|
|
9ee063ca14 | ||
|
|
eab88ea09c | ||
|
|
cfc5ecb05d | ||
|
|
8757da6c47 | ||
|
|
39e3506add | ||
|
|
0f2ef3feb2 | ||
|
|
82d801ab9e | ||
|
|
955ae78e33 | ||
|
|
8d40714f78 | ||
|
|
2c3ed90ff3 | ||
|
|
b1fc18f405 | ||
|
|
e8a04981bb | ||
|
|
a2cc936a3b | ||
|
|
e6e09a8a7c | ||
|
|
50736296a7 | ||
|
|
b759999272 | ||
|
|
a5969fd076 | ||
|
|
91150839be | ||
|
|
83aa9df1ee | ||
|
|
a38d34d368 | ||
|
|
e8461b6f90 | ||
|
|
33a19f9071 | ||
|
|
58081ca9e9 | ||
|
|
8ee91bce44 | ||
|
|
dbc1855b42 | ||
|
|
dd28a2ef14 | ||
|
|
609961a1de | ||
|
|
852d982057 | ||
|
|
6277a65bb7 | ||
|
|
26f7f2ab21 | ||
|
|
aa03fddb62 | ||
|
|
bbf2cbb6f6 | ||
|
|
221eff7fec | ||
|
|
c2073a3c45 | ||
|
|
71d257b190 | ||
|
|
0684d9da6d | ||
|
|
5337d8c23f | ||
|
|
b7d80e792d | ||
|
|
d02ced87b8 | ||
|
|
4bc9bf7654 | ||
|
|
f74d7d71e6 | ||
|
|
195be931a4 | ||
|
|
4a7d5fa769 | ||
|
|
16a0185ab5 | ||
|
|
8a09cf5369 | ||
|
|
c91ab5ec7c | ||
|
|
37244c3b08 | ||
|
|
7889e2750f | ||
|
|
63eb4b72e2 | ||
|
|
64e8ce0c07 | ||
|
|
e4c01f3187 | ||
|
|
bd64f5ced2 | ||
|
|
f7c75d36ba | ||
|
|
e99b8c3a2b | ||
|
|
0ddf90815b | ||
|
|
e432638b7d | ||
|
|
134ccb550c | ||
|
|
573c959a75 | ||
|
|
e7791a5486 | ||
|
|
a1a6ea6fe1 | ||
|
|
04d8f3218f | ||
|
|
ab859067aa | ||
|
|
9cdefb6069 | ||
|
|
a6c21666f4 | ||
|
|
3dad645619 | ||
|
|
292ffffa14 | ||
|
|
a1f17069ec | ||
|
|
71f46c0287 | ||
|
|
a34a16653e | ||
|
|
f96c76584f | ||
|
|
ade5b142f8 | ||
|
|
ed8f143427 | ||
|
|
586b407103 | ||
|
|
715a88026e | ||
|
|
3001ef7980 | ||
|
|
0a4144e67a | ||
|
|
71fa87e4ed | ||
|
|
4e781eb042 | ||
|
|
5f1897713c | ||
|
|
38b519ceb5 | ||
|
|
71f74f4042 | ||
|
|
c282d4c0ff | ||
|
|
00de81771c | ||
|
|
bc909ddf5e | ||
|
|
840095b444 | ||
|
|
be18a114e2 | ||
|
|
3e5449561f | ||
|
|
7f67cfb6a0 | ||
|
|
2b051e3884 | ||
|
|
290b221d79 | ||
|
|
c441dd1436 | ||
|
|
fcecd091da | ||
|
|
ac84f56e36 | ||
|
|
5a8f60fe32 | ||
|
|
aeb37941bb | ||
|
|
28a4069520 | ||
|
|
1aab23ece7 | ||
|
|
eea04e513d | ||
|
|
73c9241a17 | ||
|
|
fcf2be78cb | ||
|
|
ecb1625756 | ||
|
|
2592d2cfcd | ||
|
|
50cbb5744b | ||
|
|
aef4acb2e6 | ||
|
|
f4783772c5 | ||
|
|
ba9c47eb7e | ||
|
|
76416d5e47 | ||
|
|
1065374db4 | ||
|
|
65046b05af | ||
|
|
638bb9b0b1 | ||
|
|
864c8df639 | ||
|
|
81ed608b9c | ||
|
|
474f92e41b | ||
|
|
6a7113e3ce | ||
|
|
d2288815f8 | ||
|
|
2c7ccffe1a | ||
|
|
a67767dbea | ||
|
|
703ced32db | ||
|
|
c9965f0ffd | ||
|
|
291a60444a | ||
|
|
a1ef09a243 | ||
|
|
da10df3a9a | ||
|
|
5dc5f52f32 | ||
|
|
ce0509a665 | ||
|
|
1c9088ce7d | ||
|
|
a14739bde9 | ||
|
|
b479aa3d45 | ||
|
|
102d3966af | ||
|
|
1518ff6d22 | ||
|
|
5a37f96434 | ||
|
|
dddfe902a3 | ||
|
|
3740161caa | ||
|
|
7a158773f3 | ||
|
|
7f72207e66 | ||
|
|
f74ce9cc1c | ||
|
|
5018fe1e17 | ||
|
|
90392e9231 | ||
|
|
7a23add23b | ||
|
|
d87c8a8291 | ||
|
|
9b84dc4e1a | ||
|
|
37044f6fd4 | ||
|
|
33737498ec | ||
|
|
a0fea28632 | ||
|
|
23d1a80c04 | ||
|
|
29c39a3245 | ||
|
|
d7fda9c8cc | ||
|
|
f05ee4205d | ||
|
|
1964bb2acc | ||
|
|
04967de2ed | ||
|
|
6c984fac7c | ||
|
|
3f52a91312 | ||
|
|
acc0c616c4 | ||
|
|
c686fc4d6b | ||
|
|
9232620023 | ||
|
|
b1406fbad9 | ||
|
|
79c602c3cc | ||
|
|
db2f0a68e8 | ||
|
|
d7cf460918 | ||
|
|
68a98d5dc2 | ||
|
|
7c32378a73 | ||
|
|
9212a1db8e | ||
|
|
a839f70a99 | ||
|
|
d931a49e89 | ||
|
|
61b7a3afe3 | ||
|
|
cf6a904f95 | ||
|
|
00e5290dc8 | ||
|
|
627fe75a6a | ||
|
|
bc5ebb9911 | ||
|
|
1bd8a9869a | ||
|
|
0ee6e5334a | ||
|
|
c18ec7f5bc | ||
|
|
5f663dbf0a | ||
|
|
c566ba575f | ||
|
|
e016100860 | ||
|
|
82fc98848a | ||
|
|
ec18c2f354 | ||
|
|
b4da15bba8 | ||
|
|
993a5fda41 | ||
|
|
01921ee6fa | ||
|
|
ad24c11f32 | ||
|
|
351dc4ed6b | ||
|
|
e628c7b37d | ||
|
|
8cc602ff94 | ||
|
|
715fdc8614 | ||
|
|
b1ffd1b02a | ||
|
|
cf6415bf84 | ||
|
|
f386342a7c | ||
|
|
2bc087b5d5 | ||
|
|
172cc22d90 | ||
|
|
454413f69a | ||
|
|
714745cdd7 | ||
|
|
624b6b9762 | ||
|
|
12672cf50b | ||
|
|
4e6dc49646 | ||
|
|
129d92b30a | ||
|
|
69e1e3c0bd | ||
|
|
0efdb448b6 | ||
|
|
7842a90c5e | ||
|
|
7c62cfba33 | ||
|
|
acffc713e0 | ||
|
|
d3db178182 | ||
|
|
763dcc545d | ||
|
|
6f25996fa1 | ||
|
|
e296f6daa2 | ||
|
|
092f9d2c46 | ||
|
|
7d97bb6fe0 | ||
|
|
86eb0a5eaa | ||
|
|
62d5c89f62 | ||
|
|
a88f951b2f | ||
|
|
467ba6b7a9 | ||
|
|
02714d466c | ||
|
|
741c8f3d98 | ||
|
|
773e932e98 | ||
|
|
374d83ed9c | ||
|
|
05fd81ebdc | ||
|
|
777f99193f | ||
|
|
d0ef43bd12 | ||
|
|
78171e2072 | ||
|
|
94c1fb32a7 | ||
|
|
d9b845fcdf | ||
|
|
225321b580 | ||
|
|
f493eb34ae | ||
|
|
1f2d7d1cd8 | ||
|
|
ebb1ddc0df | ||
|
|
d2681d2ba1 | ||
|
|
337460cdc2 | ||
|
|
ee51e37db7 | ||
|
|
96d53d279e | ||
|
|
1a5269e51b | ||
|
|
8f32f9f5cb | ||
|
|
1e9eaba423 | ||
|
|
a8681b0072 | ||
|
|
e6a2b0a479 | ||
|
|
0f990d40cc | ||
|
|
2dc533c4b9 | ||
|
|
bc06195409 | ||
|
|
e43c63ae08 | ||
|
|
cc34bc844d | ||
|
|
7423c89968 | ||
|
|
4337c07425 | ||
|
|
5c57f92ba5 | ||
|
|
c5e540823b | ||
|
|
28093a4d2d | ||
|
|
4e3187fbbd | ||
|
|
f9fee9174a | ||
|
|
0e8a585157 | ||
|
|
11ffb9dfb6 | ||
|
|
46c7ba734b | ||
|
|
fc4031ec26 | ||
|
|
d003b1bb57 | ||
|
|
8fda175264 | ||
|
|
d08392a0c4 | ||
|
|
48ccb0f2ab | ||
|
|
b4e836bf2e | ||
|
|
a296b4ef33 | ||
|
|
140ba2858a | ||
|
|
3379641fe2 | ||
|
|
0644129fbe | ||
|
|
c295979270 | ||
|
|
e4a7352b62 | ||
|
|
33eadad139 | ||
|
|
225140bd64 | ||
|
|
58dee04d5c | ||
|
|
4b9ff309ec | ||
|
|
a3f3a35fd1 | ||
|
|
aa03eb5b6c | ||
|
|
ebe70435ef | ||
|
|
0a49dcc623 | ||
|
|
52d07eb30f | ||
|
|
70be04a2d3 | ||
|
|
eaaf52483e | ||
|
|
ebfd03570f | ||
|
|
40c7e6e179 | ||
|
|
de441916d6 | ||
|
|
850edd546c | ||
|
|
b67070f0ae | ||
|
|
c495088390 | ||
|
|
ab1b4c46b2 | ||
|
|
bec7a399cb | ||
|
|
0bf5effe58 | ||
|
|
b65e089028 | ||
|
|
c51f349dfa | ||
|
|
1bb0dde360 | ||
|
|
5c18d89453 | ||
|
|
2ff104d012 | ||
|
|
3402871741 | ||
|
|
74fa2c809d | ||
|
|
ab44edd294 | ||
|
|
5d3445cebb | ||
|
|
24ba712aa5 | ||
|
|
fb60f7946f | ||
|
|
744059b8bd | ||
|
|
8864498065 | ||
|
|
454085eb95 | ||
|
|
6e75af5c0f | ||
|
|
8da7803f3e | ||
|
|
2d6f8350cb | ||
|
|
958658513c | ||
|
|
a28f70e85c | ||
|
|
8f8c3aef87 | ||
|
|
39af10cc8d | ||
|
|
d175a68586 | ||
|
|
f740684f41 | ||
|
|
20a8e7838f | ||
|
|
2f1cb8b52a | ||
|
|
0a7a4c0d0a | ||
|
|
6b8d4a43a3 | ||
|
|
78eac4116c | ||
|
|
5a2f94f415 | ||
|
|
2f04f76e69 | ||
|
|
b8d364f11e | ||
|
|
5871428c83 | ||
|
|
1505dc207b | ||
|
|
dfd076a3e5 | ||
|
|
ad01a1731a | ||
|
|
97ab780305 | ||
|
|
54af048f04 | ||
|
|
488a69d461 | ||
|
|
bbd6c927b1 | ||
|
|
adbb909b39 | ||
|
|
58b1172025 | ||
|
|
438a5acc0f | ||
|
|
58c0486236 | ||
|
|
1c4f50b2df | ||
|
|
dc60bfa885 | ||
|
|
3b05b135a5 | ||
|
|
6b65a66119 | ||
|
|
97c15c463e | ||
|
|
50f226e34e | ||
|
|
2d18f91e57 | ||
|
|
7910fe7785 | ||
|
|
613e5c77ea | ||
|
|
c872b1a770 | ||
|
|
db58048077 | ||
|
|
14803e4cf8 | ||
|
|
1347c61c8e | ||
|
|
69b20d25ee | ||
|
|
9642cd286e | ||
|
|
2a30520799 | ||
|
|
039d4aaecb | ||
|
|
9e922dd0c7 | ||
|
|
4ac59e2674 | ||
|
|
7c5d443284 | ||
|
|
666a2233a7 | ||
|
|
7c75329b18 | ||
|
|
e135bcb5b7 | ||
|
|
d455232eb1 | ||
|
|
c8a794ac34 | ||
|
|
c0ce8723d4 | ||
|
|
9dab6e02ca | ||
|
|
9fb03d584c | ||
|
|
428ad20807 | ||
|
|
92af275f98 | ||
|
|
c7d1f4f6b2 | ||
|
|
ddf2cfd48d | ||
|
|
c69002b0dd | ||
|
|
92ea533aee | ||
|
|
239d535cac | ||
|
|
2eaaad610d | ||
|
|
e0a117414b | ||
|
|
2ab079dc7d | ||
|
|
03e03a5daa | ||
|
|
be24d3e78c | ||
|
|
0e779e20c3 | ||
|
|
2d5c0ac9ee | ||
|
|
8d09f13bad | ||
|
|
b68356b9b9 | ||
|
|
764a6e1d76 | ||
|
|
bbce2c7e2f | ||
|
|
0f648f4468 | ||
|
|
05def654c3 | ||
|
|
2ded7497b6 | ||
|
|
90bd32c680 | ||
|
|
f9d5915542 | ||
|
|
643ed27fd4 | ||
|
|
f154da38e6 | ||
|
|
046a8e8a08 | ||
|
|
80f45f6226 | ||
|
|
898a838ad7 | ||
|
|
b311969f0e | ||
|
|
d719244d1e | ||
|
|
1d0568dd5b | ||
|
|
77a8a3d33c | ||
|
|
d5893d8c9f | ||
|
|
409c6155c2 | ||
|
|
b786772819 | ||
|
|
b2f03fc2d8 | ||
|
|
3e1a5b229c | ||
|
|
8d22eeb3be | ||
|
|
625143426a | ||
|
|
f40155645c | ||
|
|
877830e4a1 | ||
|
|
45f5a10d5d | ||
|
|
d42fd6fc7e | ||
|
|
74248253f5 | ||
|
|
15273c1f7a | ||
|
|
fc92ceb0b6 | ||
|
|
9afa94f4b8 | ||
|
|
edde653d60 | ||
|
|
66553eea1a | ||
|
|
2c97cd64cf | ||
|
|
ff6b9d0907 | ||
|
|
c500c9b289 | ||
|
|
9afb973498 | ||
|
|
1bc49487ad | ||
|
|
f485a9894c | ||
|
|
c140077d53 | ||
|
|
42ce91323c | ||
|
|
0ca9dfbc12 | ||
|
|
b08af89473 | ||
|
|
b9cf0f2126 | ||
|
|
11589a7bde | ||
|
|
b10560a5b0 | ||
|
|
f4d8e32c9f | ||
|
|
617bff8ec8 | ||
|
|
a44f14d76e | ||
|
|
74b4522195 | ||
|
|
99a8f29de9 | ||
|
|
51111430b3 | ||
|
|
9211109088 | ||
|
|
ad7e4a77db | ||
|
|
faf10183d8 | ||
|
|
59c3efd44b | ||
|
|
f2b2c58758 | ||
|
|
b6f6bf9778 | ||
|
|
b0e73532de | ||
|
|
7f0cb0ce1b | ||
|
|
fef53d18c4 | ||
|
|
2aa17debc8 | ||
|
|
0700f08d6d | ||
|
|
1a074bb148 | ||
|
|
74f2e9f102 | ||
|
|
f53995d555 | ||
|
|
9eeebedf5f | ||
|
|
5e61974c24 | ||
|
|
d485cfbca3 | ||
|
|
70feb08f84 | ||
|
|
75b08f510e | ||
|
|
08383a69ce | ||
|
|
7ceca9f426 | ||
|
|
720dc92efe | ||
|
|
73ded9d378 | ||
|
|
48975d04e0 | ||
|
|
417e97eef0 | ||
|
|
b52c07f650 | ||
|
|
1a93b1db52 | ||
|
|
b547772c68 | ||
|
|
4de4ef1ccc | ||
|
|
d822e0d720 | ||
|
|
29c574cf0f | ||
|
|
3840a10da6 | ||
|
|
9bb87af66b | ||
|
|
9ec60cd585 | ||
|
|
959f5d61b7 | ||
|
|
d9ee8519e9 | ||
|
|
8960aa956c | ||
|
|
63258f9f53 | ||
|
|
8b4815fd95 | ||
|
|
32b84bd3f9 | ||
|
|
adab769700 | ||
|
|
d138c2970c | ||
|
|
452619990e | ||
|
|
de17894fce | ||
|
|
6c44553456 | ||
|
|
cc2a9f617d | ||
|
|
1578d2fda9 | ||
|
|
da724d65d7 | ||
|
|
eb92e9cdd8 | ||
|
|
5a980497e8 | ||
|
|
72eb87a631 | ||
|
|
df35700b94 | ||
|
|
ea1b89c699 | ||
|
|
a8658b7dca | ||
|
|
e64fbe3529 | ||
|
|
97c90d31d3 | ||
|
|
a1ec07e07e | ||
|
|
d701e1aa40 | ||
|
|
6d25c81bd1 | ||
|
|
58f1907579 | ||
|
|
3250764e72 | ||
|
|
462e6e0a82 | ||
|
|
59269a70a0 | ||
|
|
8df8b5731e | ||
|
|
dbab889fcc | ||
|
|
891d107a51 | ||
|
|
3ea878941b | ||
|
|
f25cf7481f | ||
|
|
d342c9a6df | ||
|
|
a1f0c24bf4 | ||
|
|
a11d8ea558 | ||
|
|
f6263f8c6b | ||
|
|
d3055a5ca0 | ||
|
|
73790fcef5 | ||
|
|
5010c15ffc | ||
|
|
6656afd57f | ||
|
|
0b7a1a1eef | ||
|
|
72d332dfa0 | ||
|
|
8cf9df2d8d | ||
|
|
3145c78b61 | ||
|
|
de3ccc4b98 | ||
|
|
d0c6176640 | ||
|
|
7cdfa44438 | ||
|
|
10faf314d4 | ||
|
|
378e81ffaa | ||
|
|
423ea00263 | ||
|
|
666aca7803 | ||
|
|
135aca02af | ||
|
|
7ab8134613 | ||
|
|
57244e4718 | ||
|
|
8eb87c5d2b | ||
|
|
02cadde8de | ||
|
|
88ab23def9 | ||
|
|
db6d8de5dc | ||
|
|
652843f447 | ||
|
|
21e5054fac | ||
|
|
a2c26b8c74 | ||
|
|
2cd6ad1a97 | ||
|
|
78e55414d4 | ||
|
|
17628b3e40 | ||
|
|
736fe0c1db | ||
|
|
ed4c69343f | ||
|
|
4421fbf9f3 | ||
|
|
002eb1a326 | ||
|
|
4baaf03ac7 | ||
|
|
c2bfc60a59 | ||
|
|
f78dcfb8e0 | ||
|
|
91bfd1f77c | ||
|
|
9ee0d46734 | ||
|
|
ca2cb9c9ba | ||
|
|
00c484c68b | ||
|
|
38c33d69ae | ||
|
|
5ad3fff6a0 | ||
|
|
cca4f4abd5 | ||
|
|
e54fda6b34 | ||
|
|
b524914008 | ||
|
|
26163e5812 | ||
|
|
0dfcc7a9b3 | ||
|
|
e510384375 | ||
|
|
eb81810a52 | ||
|
|
3b2f3c3152 | ||
|
|
de5bc32d0b | ||
|
|
1e9eccf959 | ||
|
|
4b06c0645c | ||
|
|
c6f870d4e4 | ||
|
|
053594eae8 | ||
|
|
1615c97ce8 | ||
|
|
940db1d1dd | ||
|
|
56dfef8d0d | ||
|
|
3ffd774405 | ||
|
|
076942ca7a | ||
|
|
b6e8420bf2 | ||
|
|
096439dce7 | ||
|
|
346fb745f2 | ||
|
|
020ccd8018 | ||
|
|
ce24226128 | ||
|
|
b3c51e46e7 | ||
|
|
886db7a3f2 | ||
|
|
6c5dde60a3 | ||
|
|
7f06072420 | ||
|
|
5708b7fbec | ||
|
|
5863ed4c33 | ||
|
|
14388feb23 | ||
|
|
e5f852d7d5 | ||
|
|
83e8ceceda | ||
|
|
3ef54147c9 | ||
|
|
f8df377631 | ||
|
|
868dee55de | ||
|
|
7dba4d1d8d | ||
|
|
6840d424cd | ||
|
|
34819140c3 | ||
|
|
9e8a118d10 | ||
|
|
0c7c6ddcc9 | ||
|
|
eadd2f8de6 | ||
|
|
04606a9f97 | ||
|
|
cb4309bbd9 | ||
|
|
1249196118 | ||
|
|
d6ae874038 | ||
|
|
e0e4c1b54c | ||
|
|
628fb5f5e9 | ||
|
|
967c273ddb | ||
|
|
a24d2921af | ||
|
|
5ae57baf11 | ||
|
|
7a390bdd4c | ||
|
|
72f4884127 | ||
|
|
6383eb876e | ||
|
|
c56b3425a9 | ||
|
|
2d3e938a7f | ||
|
|
260ec96edd | ||
|
|
4379d24e9d | ||
|
|
fedf764b7b | ||
|
|
39c6e2d2e5 | ||
|
|
35aaad68d7 | ||
|
|
779583adf5 | ||
|
|
a0784bd038 | ||
|
|
fc9612a5ed | ||
|
|
2cd5fb5694 | ||
|
|
da00329d78 | ||
|
|
fb99bfac52 | ||
|
|
7b19b6b4f2 | ||
|
|
d661099322 | ||
|
|
ea63a04388 | ||
|
|
6f92141587 | ||
|
|
078bd7fb5b | ||
|
|
1703a6f20e | ||
|
|
001b4a3179 | ||
|
|
aab78db8b8 | ||
|
|
9793473b10 | ||
|
|
a89e5592f2 | ||
|
|
989351a41d | ||
|
|
6fb8b2ce4f | ||
|
|
f0be4025a5 | ||
|
|
49da74f976 | ||
|
|
1146441c2a | ||
|
|
d01c200345 | ||
|
|
b7cdb00d09 | ||
|
|
cb92df687d | ||
|
|
2e51afcd9e | ||
|
|
fdc01b8ba8 | ||
|
|
e0528655a8 | ||
|
|
08983e1ba9 | ||
|
|
7d456d3556 | ||
|
|
df4b5f4ede | ||
|
|
fb537d91fc | ||
|
|
b158427271 | ||
|
|
083d0b8b60 | ||
|
|
a2857d2dca | ||
|
|
a90a994a89 | ||
|
|
a2d1ec2c1f | ||
|
|
9b25c16980 | ||
|
|
810f14aecb | ||
|
|
e627592eed | ||
|
|
3e6394a004 | ||
|
|
02e28ea758 | ||
|
|
b98cdf71c4 | ||
|
|
8fca1f52d3 | ||
|
|
1ff00281f3 | ||
|
|
7bcbad925e | ||
|
|
3fa1f3ca6f | ||
|
|
5e7f1ce383 | ||
|
|
79b0fe967b | ||
|
|
d3204e9a9d | ||
|
|
808ceb8811 | ||
|
|
74603624df | ||
|
|
0c0446e254 | ||
|
|
41c1a34b4f | ||
|
|
519b51f055 | ||
|
|
5e2481e631 | ||
|
|
f8786e9d17 | ||
|
|
85a4ff83da | ||
|
|
7231de7c2b | ||
|
|
ae52af3870 | ||
|
|
1569dfa2e8 | ||
|
|
54dac0f37a | ||
|
|
9cf09b8850 | ||
|
|
ae3b47aa75 | ||
|
|
99e8238f90 | ||
|
|
f5a1ffcbd4 | ||
|
|
7042054913 | ||
|
|
16fd56c083 | ||
|
|
9afc016ff9 | ||
|
|
3064afbac4 | ||
|
|
1979b42ee7 | ||
|
|
68155e5fb7 | ||
|
|
9f0571772d | ||
|
|
07cf2eac4e | ||
|
|
822efa2f97 | ||
|
|
0e888ccf22 | ||
|
|
f5b502186b | ||
|
|
4e94e0c82f | ||
|
|
3315e6bda5 | ||
|
|
506d6688e0 | ||
|
|
c7518f84f8 | ||
|
|
cb3e758bc6 | ||
|
|
2bcf8c7bc2 | ||
|
|
bea45867d2 | ||
|
|
70987a9029 | ||
|
|
5c85c2e5d5 | ||
|
|
6f137d62c7 | ||
|
|
3533be2f9f | ||
|
|
a1b28c362d | ||
|
|
26525d6b0f | ||
|
|
16acd669a7 | ||
|
|
a3463119e8 | ||
|
|
9159b06835 | ||
|
|
4c76112698 | ||
|
|
d158dbdb68 | ||
|
|
dadd34249a | ||
|
|
173babc18b | ||
|
|
64c0e0dfdc | ||
|
|
7576de639b | ||
|
|
bdbb994c72 | ||
|
|
ffb1732607 | ||
|
|
02f3d7a25e | ||
|
|
518ec36511 | ||
|
|
12233d704b | ||
|
|
2717556a92 | ||
|
|
7288581393 | ||
|
|
f87a4b9a04 | ||
|
|
b30709f133 | ||
|
|
20e9abe26a | ||
|
|
89b22db618 | ||
|
|
e95ee4775e | ||
|
|
f5ae3111ba | ||
|
|
6b7d3a070a | ||
|
|
e4530e6e32 | ||
|
|
1212e45a6e | ||
|
|
82153eb75f | ||
|
|
960b279419 | ||
|
|
f99cd4d05a | ||
|
|
a720e52568 | ||
|
|
83ee7a464d | ||
|
|
8e5a434560 | ||
|
|
8f06bd6f3e | ||
|
|
fe877da61f | ||
|
|
a1bb0d4d66 | ||
|
|
a6073113a1 | ||
|
|
6902b876a8 | ||
|
|
7d2866f3a7 | ||
|
|
52ba6a25df | ||
|
|
25e15869ec | ||
|
|
b3c76f3904 | ||
|
|
8de9c75caf | ||
|
|
33109a2718 | ||
|
|
cab1b75c41 | ||
|
|
1e9af82bf6 | ||
|
|
ddaf005c2b | ||
|
|
558a612d37 | ||
|
|
5ccc909f2f | ||
|
|
a367934b95 | ||
|
|
2078e5736e | ||
|
|
f0eac9d828 | ||
|
|
8110f2f221 | ||
|
|
c76d87719d | ||
|
|
9bdefa6f1f | ||
|
|
b261c5f87c | ||
|
|
f569617d24 | ||
|
|
88b71b9633 | ||
|
|
f2daeb9d70 | ||
|
|
6088af623e | ||
|
|
57262dd5ef | ||
|
|
2de5ae9991 | ||
|
|
3a094e9802 | ||
|
|
62a5159e72 | ||
|
|
7b955fe829 | ||
|
|
14bc544d89 | ||
|
|
a04bfbbc4b | ||
|
|
69ef175ac5 | ||
|
|
cbac7179fd | ||
|
|
d6e25af59a | ||
|
|
c01a79de6b | ||
|
|
4214b62551 | ||
|
|
88eb5283a0 | ||
|
|
af05f5b329 | ||
|
|
1b3a8435e5 | ||
|
|
432bab3107 | ||
|
|
e15b05603d | ||
|
|
b1db947def | ||
|
|
3d88d56965 | ||
|
|
fdf7452ba9 | ||
|
|
bceac2ab7f | ||
|
|
dcd10d1e4b | ||
|
|
783e4bc591 | ||
|
|
11cfe20395 | ||
|
|
dbb6723dfa | ||
|
|
ee3ac608cf | ||
|
|
565a500320 | ||
|
|
b5c5cce725 | ||
|
|
fcf4da1097 | ||
|
|
ebfbbc0801 | ||
|
|
b508346ed8 | ||
|
|
04de1aa51d | ||
|
|
1c907ffa36 | ||
|
|
1e514620b5 | ||
|
|
4b4654ec71 | ||
|
|
a79fcac047 | ||
|
|
572d4c5687 | ||
|
|
a8d58ea448 | ||
|
|
19daed9479 | ||
|
|
ebb031dafe | ||
|
|
bf5b084945 | ||
|
|
637b642837 | ||
|
|
e6f3c4c22b | ||
|
|
b5ff77ef0d | ||
|
|
bff66caaa6 | ||
|
|
aa20f75335 | ||
|
|
143a5e1178 | ||
|
|
a96ff85005 | ||
|
|
80e02d945c | ||
|
|
edf60b8529 | ||
|
|
7fd60294f9 | ||
|
|
a3ec50437d | ||
|
|
5b5393e82b | ||
|
|
ffd9c743de | ||
|
|
09c2317ae6 | ||
|
|
58efb3c018 | ||
|
|
528e0f3efb | ||
|
|
2a2158e0e3 | ||
|
|
cde7c6a4ef | ||
|
|
210417b428 | ||
|
|
1509aca788 | ||
|
|
b98154431c | ||
|
|
55a8862374 | ||
|
|
c2290ad058 | ||
|
|
cec6895e67 | ||
|
|
794f89abf5 | ||
|
|
37d18d512b | ||
|
|
d98cece115 | ||
|
|
0fbd908fb6 | ||
|
|
c15a9e7d5c | ||
|
|
1418fdbc02 | ||
|
|
9f52b11761 | ||
|
|
01dc0f973c | ||
|
|
b2a8678c47 | ||
|
|
9974a238c2 | ||
|
|
62c44ee47b | ||
|
|
e41b0d4d2c | ||
|
|
eb370ba22a | ||
|
|
afa9f30aac | ||
|
|
2ea2413752 | ||
|
|
fb5fe7a714 | ||
|
|
5236b0c067 | ||
|
|
081a4597e9 | ||
|
|
4b61683cdf | ||
|
|
19ca011735 | ||
|
|
2bfa9da82e | ||
|
|
2532318bee | ||
|
|
87f44c42df | ||
|
|
b822a83bc2 | ||
|
|
7d05a12ee9 | ||
|
|
bd4d6dcda2 | ||
|
|
9b9108f789 | ||
|
|
f198148c79 | ||
|
|
8c83dfe918 | ||
|
|
f93d50c380 | ||
|
|
cc8b22b5ff | ||
|
|
28d1fb8cad | ||
|
|
5e62b5975b | ||
|
|
c2f14e6053 | ||
|
|
0ebd4d04ad | ||
|
|
1023b67d59 | ||
|
|
552a12d2ee | ||
|
|
7f0658efa7 | ||
|
|
15f350edcb | ||
|
|
d02413de00 | ||
|
|
cd93b9412c | ||
|
|
13784e6551 | ||
|
|
b8cf9a2788 | ||
|
|
09a6e37a09 | ||
|
|
ea69e91e49 | ||
|
|
ab6ed823d1 | ||
|
|
33c2768a77 | ||
|
|
1f3a73e802 | ||
|
|
4359eb4472 | ||
|
|
3b762fddfb | ||
|
|
93fb70b62f | ||
|
|
6d9ca4f52b | ||
|
|
77dbec305f | ||
|
|
8f429bc25a | ||
|
|
42e21d15bf | ||
|
|
78459b913b | ||
|
|
197a9b4165 | ||
|
|
1f97cee7c9 | ||
|
|
015ef3e014 | ||
|
|
2d65c3bcd0 | ||
|
|
52789ab96f | ||
|
|
89c7028ed1 | ||
|
|
b3905e867e | ||
|
|
aba517d4fd | ||
|
|
4f6e70a75c | ||
|
|
7b542b88f0 | ||
|
|
3519dd96ee | ||
|
|
1ce86b6dfc | ||
|
|
19963bfcd1 | ||
|
|
2fca10ac98 | ||
|
|
f51103f44a | ||
|
|
339496a361 | ||
|
|
30dfd54575 | ||
|
|
532f75fcab | ||
|
|
7ee2a703d9 | ||
|
|
7c5afdd388 | ||
|
|
f73e1f9188 | ||
|
|
d50db378d7 | ||
|
|
db23d1165c | ||
|
|
bafbee805c | ||
|
|
ef59f4f243 | ||
|
|
83fe340b98 | ||
|
|
b4f90c8c81 | ||
|
|
a1cbd11b5b | ||
|
|
befdfceada | ||
|
|
49e1316f7f | ||
|
|
c164da5a38 | ||
|
|
969916442f | ||
|
|
99bfc9b7f5 | ||
|
|
245dc01e33 | ||
|
|
4818e76ad9 | ||
|
|
98adcac5df | ||
|
|
19e96cc212 | ||
|
|
cfffe39151 | ||
|
|
0dfd00f664 | ||
|
|
dbbc2f19f4 | ||
|
|
cb1d9f60ec | ||
|
|
db2042f561 | ||
|
|
91f3b3955a | ||
|
|
923296b4ee | ||
|
|
e209312459 | ||
|
|
b47fae7393 | ||
|
|
8e05fe3350 | ||
|
|
e6341ceaaa | ||
|
|
0120be5b8c | ||
|
|
19436358fb | ||
|
|
2cb1aa6639 | ||
|
|
2f36f5ca78 | ||
|
|
25a7bcef82 | ||
|
|
c8eaaaea83 | ||
|
|
beb2853bbf | ||
|
|
f76b60f295 | ||
|
|
663a48ee38 | ||
|
|
db8ffe1dc7 | ||
|
|
ad59393641 | ||
|
|
a751f4c689 | ||
|
|
b3e9d35667 | ||
|
|
c2aa7d538f | ||
|
|
1d41903779 | ||
|
|
92f3371118 | ||
|
|
543c4d5597 | ||
|
|
e07f5cd53f | ||
|
|
66c4c7e77b | ||
|
|
274854876c | ||
|
|
81db8e098e | ||
|
|
af05f26a5f | ||
|
|
0b35d97821 | ||
|
|
8a56ab3947 | ||
|
|
82b1607c1e | ||
|
|
16348fc895 | ||
|
|
1eba552a8d | ||
|
|
47eac062f6 | ||
|
|
57580e00f9 | ||
|
|
93bbc6c810 | ||
|
|
894f9c0cb0 | ||
|
|
f22662ffb2 | ||
|
|
559eb20e7f | ||
|
|
ccbe554ec0 | ||
|
|
93243ef223 | ||
|
|
47439cd77c | ||
|
|
ac62871645 | ||
|
|
ab40da3f31 | ||
|
|
6e099af5fe | ||
|
|
c0a6cb69bf | ||
|
|
2597ded985 | ||
|
|
10da361db1 | ||
|
|
36fa4da252 | ||
|
|
68005f9ad4 | ||
|
|
bf5d448e37 | ||
|
|
600077996c | ||
|
|
cef177abc4 | ||
|
|
8572ccb807 | ||
|
|
ce8bbb689c | ||
|
|
9cf9229308 | ||
|
|
7ffa7042b1 | ||
|
|
b360f7d86a | ||
|
|
44f8bfc550 | ||
|
|
bd704dd8aa | ||
|
|
7b3fc14023 | ||
|
|
193f95a888 | ||
|
|
b03f44df10 | ||
|
|
bf9af4d45b | ||
|
|
8181e9a0ef | ||
|
|
d9db657b43 | ||
|
|
e96119fc32 | ||
|
|
8aa559fe51 | ||
|
|
a5e2f8e79e | ||
|
|
2b3a80ecda | ||
|
|
7da3e84369 | ||
|
|
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 | ||
|
|
754abbd39c | ||
|
|
b89ef80481 | ||
|
|
b2abeb9beb | ||
|
|
59293bc938 | ||
|
|
c1e2348695 | ||
|
|
9754050598 | ||
|
|
6358fd1a4b | ||
|
|
a83787ea42 | ||
|
|
8f9e0d8d59 | ||
|
|
d5171ab941 | ||
|
|
a0e1174304 | ||
|
|
6799fe5393 | ||
|
|
6b51dad973 | ||
|
|
8ae66cab9d | ||
|
|
0b202a2df1 | ||
|
|
ee336b4218 | ||
|
|
1b3fc53a95 | ||
|
|
4d9f19f660 | ||
|
|
c407588821 | ||
|
|
037ca07847 | ||
|
|
75ce386065 | ||
|
|
a5e49c0c6f | ||
|
|
30f6ddf113 | ||
|
|
bbeb3beecd | ||
|
|
cb324181ad | ||
|
|
0dc3e6ac7c | ||
|
|
bef22e80c8 | ||
|
|
64da04777e | ||
|
|
5150fd6946 | ||
|
|
511a49f6fb | ||
|
|
76cc3eeb6d | ||
|
|
8d5fbe525d | ||
|
|
074ac051d2 | ||
|
|
e22a8d0a49 | ||
|
|
f2281957ce | ||
|
|
d38bc95f04 | ||
|
|
b243aea5c8 | ||
|
|
1f0116af13 | ||
|
|
2dfbe0b5d3 | ||
|
|
08115d57fd | ||
|
|
afd927f749 | ||
|
|
cfeb00e629 | ||
|
|
e415c66f68 | ||
|
|
0798896936 | ||
|
|
b2c25a3efd | ||
|
|
e1fbe7d886 | ||
|
|
75fcafa013 | ||
|
|
59ecf7bb50 | ||
|
|
0521663076 | ||
|
|
d42dc9baba | ||
|
|
64bc157d1a | ||
|
|
cf887379e1 | ||
|
|
90477321fe | ||
|
|
47cbcd5278 | ||
|
|
7c77ab060a | ||
|
|
ff9450305e | ||
|
|
e72e21f481 | ||
|
|
2416056444 | ||
|
|
d98ba5f2b3 | ||
|
|
ecbb46344c | ||
|
|
74c517d186 | ||
|
|
257964d13e | ||
|
|
9e0b1b864b | ||
|
|
d9e1861aff | ||
|
|
42c2f87217 | ||
|
|
77d6bb2c3f | ||
|
|
3e6df19eff | ||
|
|
a070f0fdb6 | ||
|
|
146ce284de | ||
|
|
6c76d9751f | ||
|
|
1321fb8151 | ||
|
|
d10292d95c | ||
|
|
676b1e0bc7 | ||
|
|
6483cd0b43 | ||
|
|
123e20c688 | ||
|
|
7c9c3170f5 | ||
|
|
90a472cd1d | ||
|
|
ed744bf1d2 | ||
|
|
72f6575fc4 | ||
|
|
90538d0e16 | ||
|
|
2b5a0e28e3 | ||
|
|
d940330a7c | ||
|
|
d26b226bd2 | ||
|
|
b4890512a9 | ||
|
|
1bce2ec0e9 | ||
|
|
1b3658171f | ||
|
|
53faf2bde4 | ||
|
|
831c7f5924 | ||
|
|
c12ba5d221 | ||
|
|
f263a8e9d5 | ||
|
|
a69c312389 | ||
|
|
f280590adf | ||
|
|
779e7765ae | ||
|
|
f25480dec5 | ||
|
|
70194d2632 | ||
|
|
a67c54869f | ||
|
|
c841d90529 | ||
|
|
d0b8b478fc | ||
|
|
f25caabe9a | ||
|
|
abe4b73d43 | ||
|
|
d0e255816d | ||
|
|
0c9794eefa | ||
|
|
2a22a47322 | ||
|
|
38178fb3c8 | ||
|
|
ca845aa35e | ||
|
|
de5939456f | ||
|
|
da0eee6298 | ||
|
|
444a094eda | ||
|
|
d2f3d83678 | ||
|
|
5eb2b33018 | ||
|
|
5b5651882e | ||
|
|
856bb9060c | ||
|
|
71d82f7ff8 | ||
|
|
2e5de25383 | ||
|
|
bed0408ed0 | ||
|
|
da30e3348e | ||
|
|
3a78b5fa13 | ||
|
|
1515ff1a08 | ||
|
|
9e80010e1a | ||
|
|
e5e3a6837a | ||
|
|
0d39249025 | ||
|
|
0e7c7ca34b | ||
|
|
f0e5cae9bb | ||
|
|
f943f54ad5 | ||
|
|
c6448d0607 | ||
|
|
84bf956725 | ||
|
|
854295c0a6 | ||
|
|
a132d2e5a0 | ||
|
|
5c55b9412f | ||
|
|
5933947000 | ||
|
|
3c0ec73d75 | ||
|
|
fae3cf9a55 | ||
|
|
37275c64cd | ||
|
|
de0be312be | ||
|
|
4da509f928 | ||
|
|
f176b2c58f | ||
|
|
9b9cfcfeaa | ||
|
|
8a8048a629 | ||
|
|
69821cdb96 | ||
|
|
98a49fa155 | ||
|
|
aa54df7e44 | ||
|
|
a9748f6cc6 | ||
|
|
f7cf3ad867 | ||
|
|
a85db2d780 | ||
|
|
19698fc739 | ||
|
|
8342c7cfe1 | ||
|
|
6df86afef8 | ||
|
|
ac31dc9672 | ||
|
|
dc9778f0f2 | ||
|
|
4addd8d227 | ||
|
|
b6fa1141fe | ||
|
|
ec63cc09db | ||
|
|
d15bb62f72 | ||
|
|
042d90c047 | ||
|
|
739484f1d1 | ||
|
|
dc35586be1 | ||
|
|
9afcf80d02 | ||
|
|
a60fa6989a | ||
|
|
b69db7ff67 | ||
|
|
f762ce5d06 | ||
|
|
97f0314589 | ||
|
|
6337888a34 | ||
|
|
3ccd90a690 | ||
|
|
97006bcbc3 | ||
|
|
3584d48dbe | ||
|
|
85f6edb815 | ||
|
|
1fd8deaca7 | ||
|
|
1bba15cb7f | ||
|
|
23ccad4915 | ||
|
|
c0875864dc | ||
|
|
1815f8b40d | ||
|
|
272effd470 | ||
|
|
c8a82e6e50 | ||
|
|
e70d195cde | ||
|
|
4135040449 | ||
|
|
744895f9d8 | ||
|
|
859606e88c | ||
|
|
9eeec9aa0b | ||
|
|
b02bcc0016 | ||
|
|
c5f8fbf471 | ||
|
|
00ed814962 | ||
|
|
79babe858d | ||
|
|
26e93e8798 | ||
|
|
486dd9edfa | ||
|
|
11e02d6bbc | ||
|
|
0b3b621f81 | ||
|
|
d3cda97d50 | ||
|
|
83debe2e43 | ||
|
|
9091a34675 | ||
|
|
822bc2fd52 | ||
|
|
e8bf798b52 | ||
|
|
a365e0b032 | ||
|
|
d67295888d | ||
|
|
3d267fc743 | ||
|
|
0c9aea3308 | ||
|
|
297ccbbe58 | ||
|
|
babfbe40d2 | ||
|
|
f6cca0df48 | ||
|
|
f3961a8007 | ||
|
|
0eb982a972 | ||
|
|
1cb23a958c | ||
|
|
8417f158b4 | ||
|
|
db39910455 | ||
|
|
bccbc5e821 | ||
|
|
5037daadfb | ||
|
|
5a316c0c41 | ||
|
|
a040a96652 | ||
|
|
ef5342b86e | ||
|
|
3b8f959ddf | ||
|
|
7e1c86a105 | ||
|
|
2efed6f910 | ||
|
|
a13c29f0e6 | ||
|
|
dd6caba082 | ||
|
|
e5176d6a0a | ||
|
|
1dd57bd3a4 | ||
|
|
499c9bc3b9 | ||
|
|
8f2b998718 | ||
|
|
f36569c3b9 | ||
|
|
da483ba7f3 | ||
|
|
7c50393c72 | ||
|
|
7106a36ccb | ||
|
|
77cccc2db6 | ||
|
|
5dae7b8658 | ||
|
|
84397052fd | ||
|
|
a2407c6b02 | ||
|
|
aa1efe70e2 | ||
|
|
6e2bf824f0 | ||
|
|
1ae30328d6 | ||
|
|
8162689014 | ||
|
|
338d11ef01 | ||
|
|
16e3397c32 | ||
|
|
c25911db0d | ||
|
|
d9cd50c219 | ||
|
|
4a7e392301 | ||
|
|
e42433cf9a | ||
|
|
16af53237c | ||
|
|
4fa9970eff | ||
|
|
96b23830cd | ||
|
|
b0b5d1b1b0 | ||
|
|
b994ae8174 | ||
|
|
6f4aed83f0 | ||
|
|
d654afde5f | ||
|
|
5c5cf3c66e | ||
|
|
84d458687a | ||
|
|
2ab5d6e35a | ||
|
|
d6079782d1 | ||
|
|
e576d4c014 | ||
|
|
a16ea1fbf2 | ||
|
|
f0d9ee4ca9 | ||
|
|
538bd1116d | ||
|
|
5ead4f655a | ||
|
|
b975d4c41f | ||
|
|
cca0d8d583 | ||
|
|
d7a54cf3a6 | ||
|
|
a50d3bde5c | ||
|
|
7f496f1994 | ||
|
|
395eb067d1 | ||
|
|
98fcc93862 | ||
|
|
b21e5a6300 | ||
|
|
ac11c95da6 | ||
|
|
5bbf749693 | ||
|
|
3d518c2105 | ||
|
|
839f875045 | ||
|
|
2369f6cc41 | ||
|
|
ff88535cd5 | ||
|
|
7a38307d1f | ||
|
|
877277d837 | ||
|
|
d4e7fe3eb8 | ||
|
|
03e6d564d7 | ||
|
|
f5fc26d8fc | ||
|
|
86ebd6e8e3 | ||
|
|
a80fe40f56 | ||
|
|
b1f0c2d174 | ||
|
|
ac794c8085 | ||
|
|
663ab8e0bf | ||
|
|
d2162bf9f4 | ||
|
|
b7a71b885e | ||
|
|
9aefb9c2d3 | ||
|
|
a3e1fa3350 | ||
|
|
bf6fb3872e | ||
|
|
84307dd329 | ||
|
|
c814803c94 | ||
|
|
61d54f0558 | ||
|
|
9d0a11580f | ||
|
|
7a6db019e8 | ||
|
|
fdecf09d99 | ||
|
|
7e7f0888e5 | ||
|
|
5a837f5850 | ||
|
|
d3e6166de6 | ||
|
|
c6f0968d17 | ||
|
|
abea550a4d | ||
|
|
d7261073e7 | ||
|
|
01a9ac21a5 | ||
|
|
8b41e78245 | ||
|
|
9ab3b5293c | ||
|
|
7a83b16cc4 | ||
|
|
679959eeb5 | ||
|
|
e96a3abdf9 | ||
|
|
788ed588c9 | ||
|
|
35229255bb | ||
|
|
f4b648385c | ||
|
|
eb1675a90f | ||
|
|
f7854e0b4c | ||
|
|
630e1b54e8 | ||
|
|
1740355855 | ||
|
|
239f061ffd | ||
|
|
5402b1b432 | ||
|
|
83ff6b607f | ||
|
|
caa553c563 | ||
|
|
e3434b5cde | ||
|
|
5dd5f18edf | ||
|
|
6285e26972 | ||
|
|
b6ac06c022 | ||
|
|
375228f266 | ||
|
|
eaab9b295b | ||
|
|
b1f4a47b5b | ||
|
|
2d808d30a2 | ||
|
|
bbef33a33a | ||
|
|
68cb6ee861 | ||
|
|
516d46444d | ||
|
|
26ddbbb0ee | ||
|
|
467b9122e9 | ||
|
|
cdf6f3ade9 | ||
|
|
b1bb4d911f | ||
|
|
834d02d65b | ||
|
|
47b1a90dd7 | ||
|
|
66fe74de29 | ||
|
|
60b686ff51 | ||
|
|
ef4fb8bfe0 | ||
|
|
e3a3c342de | ||
|
|
5e2c975758 | ||
|
|
c88673d6ba | ||
|
|
23ebfa2955 | ||
|
|
4e4e0f5d4d | ||
|
|
6939e325df | ||
|
|
a941c20af4 | ||
|
|
cde4017c7b | ||
|
|
af301e682e | ||
|
|
09ebabfc45 | ||
|
|
6248aeb1ea | ||
|
|
6fe9d0fdc5 | ||
|
|
b3f9a36a77 | ||
|
|
4c63307ae7 | ||
|
|
637a99ea66 | ||
|
|
434065bcdf | ||
|
|
52958d5d3f | ||
|
|
516551623a | ||
|
|
be28ffa028 | ||
|
|
c2cff39bc5 | ||
|
|
1ebbf32f29 | ||
|
|
7c3ac01fd3 | ||
|
|
676a48ae28 | ||
|
|
5f215cfa6b | ||
|
|
4d175b8f81 | ||
|
|
df692f164c | ||
|
|
e30fef09c8 | ||
|
|
6b9148127e | ||
|
|
63ed4acd49 | ||
|
|
99ee21d657 | ||
|
|
449748b044 | ||
|
|
1019952989 | ||
|
|
1c057c8ea1 | ||
|
|
89507a2524 | ||
|
|
31b08a3ec6 | ||
|
|
b96aee50e1 | ||
|
|
337e9f9553 | ||
|
|
3260b42b18 | ||
|
|
f9c5d0796c | ||
|
|
2f113286aa | ||
|
|
686493e8ec | ||
|
|
1b3e6bdb92 | ||
|
|
0fe65a688e | ||
|
|
377666503c | ||
|
|
0411c2d2b6 | ||
|
|
839a751de5 | ||
|
|
a74d3d210d | ||
|
|
df86c9dac1 | ||
|
|
e3d67a304f | ||
|
|
77253abbd7 | ||
|
|
013a7717b4 | ||
|
|
aae4abfa86 | ||
|
|
abc6e1e289 | ||
|
|
dc154f3907 | ||
|
|
9f86fa1893 | ||
|
|
01b42c9e59 | ||
|
|
6bd0b82b2e | ||
|
|
391468ece0 | ||
|
|
5e05a3045c | ||
|
|
c2996d4fd1 | ||
|
|
d37bf06b5a | ||
|
|
1c07235121 | ||
|
|
59a2430f1d | ||
|
|
87221f8f55 | ||
|
|
e3215a1f21 | ||
|
|
2522bc2298 | ||
|
|
f3103e9b00 | ||
|
|
e897377879 | ||
|
|
6833865ff3 | ||
|
|
88dde07bf1 | ||
|
|
51f0090555 | ||
|
|
b8e75df8f0 | ||
|
|
de21a164ea | ||
|
|
95e1ea6599 | ||
|
|
2d2fbaaa4a | ||
|
|
7cfff62037 | ||
|
|
d61daf6f05 | ||
|
|
eca911a1b1 | ||
|
|
0a5a020466 | ||
|
|
79802c2919 | ||
|
|
3f1d540077 | ||
|
|
ff9027fa95 | ||
|
|
753a1e7aff | ||
|
|
4c8e483bc1 | ||
|
|
8404389a31 | ||
|
|
f8d6fab52b | ||
|
|
199e975a11 | ||
|
|
32f83d8e4e | ||
|
|
6ae3402aec | ||
|
|
21ccf80ba5 | ||
|
|
706c56bb30 | ||
|
|
c98e16b18f | ||
|
|
b386ec40be | ||
|
|
14cec9e20e | ||
|
|
120094a81e | ||
|
|
637b50044d | ||
|
|
acef33aa2c | ||
|
|
6134b9ed38 | ||
|
|
ce6f9f20bf | ||
|
|
b1f9c4dfc5 | ||
|
|
7660816468 | ||
|
|
1a43ec3557 | ||
|
|
4a3341e31e | ||
|
|
2f088c5caa | ||
|
|
38810c5518 | ||
|
|
876bfc69ac | ||
|
|
2ce1d3a784 | ||
|
|
a81ef7847d | ||
|
|
2117d06274 | ||
|
|
a5ec8a9110 | ||
|
|
30b3657c0e | ||
|
|
06a4f83bb7 | ||
|
|
7a8e43c65e | ||
|
|
90cc1a7062 | ||
|
|
7d93b4a48f | ||
|
|
a2ecb554cc | ||
|
|
f65f95e95c | ||
|
|
eaedac2536 | ||
|
|
8b9d35d84e | ||
|
|
99c0de6a1a | ||
|
|
f2bef6c26d | ||
|
|
1f57994e2a | ||
|
|
618040efc1 | ||
|
|
ed34aa6fb3 | ||
|
|
57639133a9 | ||
|
|
1b7c308475 | ||
|
|
2b2a55d870 | ||
|
|
c26a9b23a7 | ||
|
|
6c36f7e5c9 | ||
|
|
eb9673a152 | ||
|
|
fbe963c7f3 | ||
|
|
18f8af7822 | ||
|
|
3576c6d2ff | ||
|
|
b4ee01d43d | ||
|
|
679aa43113 | ||
|
|
2b82eafff4 | ||
|
|
94b3de557e | ||
|
|
c56480fd89 | ||
|
|
e9879b150e | ||
|
|
ea8d349b1b | ||
|
|
87b78a89fb | ||
|
|
27cd6688c1 | ||
|
|
c340cac02c | ||
|
|
0a9c371ca2 | ||
|
|
4a000a35c4 | ||
|
|
d89fb15daf | ||
|
|
d698ecf017 | ||
|
|
2b7b4a16f5 | ||
|
|
526aaecc52 | ||
|
|
e3d5b62000 | ||
|
|
6bd56f2a52 | ||
|
|
426e7645bc | ||
|
|
521fb7d54c | ||
|
|
4051d2ebdb | ||
|
|
b4fa3cd925 | ||
|
|
984d60f935 | ||
|
|
65f258160e | ||
|
|
a76183c188 | ||
|
|
fde4c544b8 | ||
|
|
274c9d04b1 | ||
|
|
07fc2b41af | ||
|
|
a9efe77ceb | ||
|
|
b932461b45 | ||
|
|
6b3ff63358 | ||
|
|
dd4e36a42e | ||
|
|
93687efee9 | ||
|
|
9ba7db8815 | ||
|
|
f4a2c12d75 | ||
|
|
74a83e3d7c | ||
|
|
283aa79c17 | ||
|
|
dc69c7b694 | ||
|
|
a78807b309 | ||
|
|
e7248b486f | ||
|
|
c2afa3521e | ||
|
|
6ae38d86df | ||
|
|
9f0d9e0fad | ||
|
|
45b626e0cc | ||
|
|
c13724b342 | ||
|
|
5da1e9ed10 | ||
|
|
a8913f5ea0 | ||
|
|
a59756485e | ||
|
|
6949af5427 | ||
|
|
da602a7c01 | ||
|
|
50eb5454d4 | ||
|
|
8ee1e1d208 | ||
|
|
73ec7783af | ||
|
|
a8f172752a | ||
|
|
b7e120b68c | ||
|
|
a85075103f | ||
|
|
fe30880ec0 | ||
|
|
c81128b675 | ||
|
|
2634328720 | ||
|
|
0df59e2714 | ||
|
|
18fdbb6432 | ||
|
|
bd51a4c8cf | ||
|
|
6478244fbf | ||
|
|
e0f660301c | ||
|
|
192014cc3f | ||
|
|
61b69a4e8a | ||
|
|
ec00da416f | ||
|
|
d4929de33c | ||
|
|
a0b15661ed | ||
|
|
9a58706e1f | ||
|
|
ce586e0835 | ||
|
|
795c31918a | ||
|
|
2592487c3f | ||
|
|
f05daa8bdc | ||
|
|
75ec34884d | ||
|
|
96cb4fd6d7 | ||
|
|
d63de1ae15 | ||
|
|
5250871e69 | ||
|
|
426bc97194 | ||
|
|
76098255f0 | ||
|
|
e8594b492e | ||
|
|
d4e362ec89 | ||
|
|
df399f7c8c | ||
|
|
ef8e5505c8 | ||
|
|
71fd147c47 | ||
|
|
c271d89677 | ||
|
|
7cf040e7ca | ||
|
|
a6c92f20c8 | ||
|
|
400e963b8b | ||
|
|
2a7244a366 | ||
|
|
5741bad918 | ||
|
|
1d7445c5aa | ||
|
|
4a1f8cf1c9 | ||
|
|
a2bf1b3907 | ||
|
|
b2d4d76bcf | ||
|
|
9ac555c302 | ||
|
|
43711083f7 | ||
|
|
9b07c2b894 | ||
|
|
2c28725722 | ||
|
|
53a4f34433 | ||
|
|
406f0b7bc7 | ||
|
|
6912a0513a | ||
|
|
0398577e93 | ||
|
|
42dc9c1ec6 | ||
|
|
2f798c5116 | ||
|
|
363f1da77e | ||
|
|
8655dec00e | ||
|
|
fbc68ecce5 | ||
|
|
8d4ac15834 | ||
|
|
249366c90a | ||
|
|
931182b677 | ||
|
|
2a129f892f | ||
|
|
57a27876ec | ||
|
|
fc2e069efe | ||
|
|
58d4ec5587 | ||
|
|
b0c23294fe | ||
|
|
290dd36bb0 | ||
|
|
84529de10d | ||
|
|
bde4a732c4 | ||
|
|
535b936c87 | ||
|
|
dc880b16f1 | ||
|
|
5eb1f52421 | ||
|
|
3747048218 | ||
|
|
a1a091d805 | ||
|
|
e536d0e7a8 | ||
|
|
e050494e5d | ||
|
|
bbc01e704c | ||
|
|
fff743053a | ||
|
|
e7b7efeb0a | ||
|
|
968fc71b78 | ||
|
|
d0494024a9 | ||
|
|
a12754f980 | ||
|
|
c76f510cea | ||
|
|
968f75529a | ||
|
|
93d5a2e195 | ||
|
|
367285f3f3 | ||
|
|
95b2003193 | ||
|
|
bcdc44c1c6 | ||
|
|
4ae2738ce5 | ||
|
|
e09a2ff811 | ||
|
|
7253a35455 | ||
|
|
1b1cf87115 | ||
|
|
3ec755e978 | ||
|
|
cf4616de7f | ||
|
|
2755fbaadf | ||
|
|
6f222651d7 | ||
|
|
fe4841a1cd | ||
|
|
fe8a2b9ee0 | ||
|
|
b939232670 | ||
|
|
a4253e3899 | ||
|
|
52b5f769f0 | ||
|
|
b73a114f8f | ||
|
|
7ca152070a | ||
|
|
f24ccd3841 | ||
|
|
66ac11ca5f | ||
|
|
7afef0fcdb | ||
|
|
627f487b36 | ||
|
|
c64a793364 | ||
|
|
63852a8c82 | ||
|
|
c97afdbdb3 | ||
|
|
6c5ea4ea32 | ||
|
|
cac3973731 | ||
|
|
19a35b58f0 | ||
|
|
5e51ad30d7 | ||
|
|
e1e5cb5ba4 | ||
|
|
8d124c7157 | ||
|
|
67ed72294b | ||
|
|
1bb5481071 | ||
|
|
876063b1ba | ||
|
|
7d193033f5 | ||
|
|
074ea374e0 | ||
|
|
f6c3a69595 | ||
|
|
f28881e203 | ||
|
|
6312c1108a | ||
|
|
0de40febab | ||
|
|
1701f572e2 | ||
|
|
15a9be6b93 | ||
|
|
a60be1563f | ||
|
|
a2522efb25 | ||
|
|
7c3f22a333 | ||
|
|
2945e1b50a | ||
|
|
aedacd39d2 | ||
|
|
d3f33152d0 | ||
|
|
cfca12d4a5 | ||
|
|
754cd88cc2 | ||
|
|
031426d54e | ||
|
|
980e8ca4dc | ||
|
|
df0094b6cb | ||
|
|
02d94c8b2e | ||
|
|
902be9bab5 | ||
|
|
f646d2dda8 | ||
|
|
92b19f89d9 | ||
|
|
d8eb465eb9 | ||
|
|
c04a9933cc | ||
|
|
5b12f80d01 | ||
|
|
75c44ca057 | ||
|
|
56f709ff1f | ||
|
|
0215c2fbee | ||
|
|
6e079d8bc4 | ||
|
|
a4715f936b | ||
|
|
1d88b31edd | ||
|
|
e07e26ca76 | ||
|
|
c82e73a4ec | ||
|
|
eda4249bf8 | ||
|
|
09201e3e65 | ||
|
|
2ca2d37e93 | ||
|
|
d3416e2873 | ||
|
|
4e4e316005 | ||
|
|
8fc1e055bf | ||
|
|
d51ea21afa | ||
|
|
abf982e4e5 | ||
|
|
998e9792fb | ||
|
|
c87b21148c | ||
|
|
7e67f7632d | ||
|
|
cd68396bd5 | ||
|
|
474e1fcd3b | ||
|
|
cfeeec37eb | ||
|
|
0a84c30d3b | ||
|
|
7ba03ce23d | ||
|
|
cc5db4dab9 | ||
|
|
aa3e8385df | ||
|
|
886ebdb002 | ||
|
|
ea2f87683a | ||
|
|
c116f6b35c | ||
|
|
2413eebd7b | ||
|
|
7708e7a8c4 | ||
|
|
1c0b391419 | ||
|
|
28f5d184b3 | ||
|
|
fc00da9732 | ||
|
|
9ea75b7519 | ||
|
|
61c63a6af9 | ||
|
|
e4bfa373de | ||
|
|
d53915c6ab | ||
|
|
409a431892 | ||
|
|
d82cfc023f | ||
|
|
f9c41f33e5 | ||
|
|
4ec4b01218 | ||
|
|
0a37852757 | ||
|
|
42ffa5813f | ||
|
|
597e17b540 | ||
|
|
9ac0591386 | ||
|
|
cb73a3c572 | ||
|
|
2c672052e6 | ||
|
|
b431e96f9d | ||
|
|
36445f8d8b | ||
|
|
085b1a45ee | ||
|
|
844fccc177 | ||
|
|
0a63395b0f | ||
|
|
623e0f3ae4 | ||
|
|
e9e90b481a | ||
|
|
4a1ee39156 | ||
|
|
e5afa72b4d | ||
|
|
287c948845 | ||
|
|
4625f051c8 | ||
|
|
8d271a6655 | ||
|
|
65b3435156 | ||
|
|
3c60e07653 | ||
|
|
564c5c1664 | ||
|
|
5f4a9316f1 | ||
|
|
a0c0bb18b7 | ||
|
|
284160bf2d | ||
|
|
0229c3187b | ||
|
|
eec8560119 | ||
|
|
fc4ed9be12 | ||
|
|
a614134144 | ||
|
|
5670ee7693 | ||
|
|
420ae1a2cc | ||
|
|
02bbf07d3a | ||
|
|
121163f9ca | ||
|
|
d79626f02f | ||
|
|
7cffbc8a1a | ||
|
|
170ef2362f | ||
|
|
e45f83e62a | ||
|
|
687c9de5d7 | ||
|
|
e43b39a009 | ||
|
|
bfe8928ab1 | ||
|
|
d6d1604623 | ||
|
|
7d5826df85 | ||
|
|
9493c1b0bb | ||
|
|
a2aa20b6b2 | ||
|
|
c8d0968e00 | ||
|
|
8237edcf0d | ||
|
|
13261921a7 | ||
|
|
adc5495d2b | ||
|
|
02d14ed23b | ||
|
|
a0a5b20ef1 | ||
|
|
fd081e162b | ||
|
|
30be4a847f | ||
|
|
0d77ba5222 | ||
|
|
94569f7f8c | ||
|
|
fdfff63119 | ||
|
|
da03784610 | ||
|
|
deef68bcf9 | ||
|
|
6393e2e1e5 | ||
|
|
bf77fcc03e | ||
|
|
386b921914 | ||
|
|
401fe76acd | ||
|
|
2fd3616ef3 | ||
|
|
ffaf535d00 | ||
|
|
9ac5ea5a6c | ||
|
|
edf7496443 | ||
|
|
151b2b5ad5 | ||
|
|
1fc9ef33db | ||
|
|
858f21a69c | ||
|
|
3a4835ff1c | ||
|
|
47d37cc1e3 | ||
|
|
a5224f705d | ||
|
|
b737e602b7 | ||
|
|
59f586ba59 | ||
|
|
70b7659893 | ||
|
|
717b664802 | ||
|
|
75e1fb63c8 | ||
|
|
a9c20dc42f | ||
|
|
dce7e50636 | ||
|
|
edd2bd74c9 | ||
|
|
6f8c46d2f4 | ||
|
|
4bab284f2e | ||
|
|
59b3e74542 | ||
|
|
4af646b760 | ||
|
|
5720d4f802 | ||
|
|
80824b13c6 | ||
|
|
33ad68f7a7 | ||
|
|
4af802f215 | ||
|
|
3b4a45ac65 | ||
|
|
a0548530e7 | ||
|
|
8d6764e0a0 | ||
|
|
36ecb35cb1 | ||
|
|
9ad3b7939f | ||
|
|
8493975840 | ||
|
|
ec880d64bf | ||
|
|
113d644615 | ||
|
|
4105527d07 | ||
|
|
2228184066 | ||
|
|
1af4ecfc26 | ||
|
|
9981fd51da | ||
|
|
458ff5c41f | ||
|
|
7735d8fbfd | ||
|
|
20e368eb89 | ||
|
|
ed3358e501 | ||
|
|
d181ff4e7f | ||
|
|
f8f09eb974 | ||
|
|
28b692aeaa | ||
|
|
aef6d44a01 | ||
|
|
e4b4087fdb | ||
|
|
1d2de6d1fb | ||
|
|
67dd596386 | ||
|
|
bd0836581b | ||
|
|
cdb5e24d2f | ||
|
|
6b02be6da8 | ||
|
|
d1a5c49843 | ||
|
|
dd4e43eb02 | ||
|
|
9007a45051 | ||
|
|
801a19504a | ||
|
|
a6989847ea | ||
|
|
e7d25385b0 | ||
|
|
62f200d252 | ||
|
|
374cf948e4 | ||
|
|
8f558fb252 | ||
|
|
8f2dd91e34 | ||
|
|
896c1793d3 | ||
|
|
85428d8eb3 | ||
|
|
57bee8b788 | ||
|
|
0ad51c394b | ||
|
|
e8455d5c9a | ||
|
|
2768eaa676 | ||
|
|
6c0621fe05 | ||
|
|
baa6d9730c | ||
|
|
d5ffa4dc77 | ||
|
|
01dd5638d0 | ||
|
|
ec5cd2fb1c | ||
|
|
44c0dc9104 | ||
|
|
7324f0468b | ||
|
|
64e3a6b437 | ||
|
|
690ab7d4ae | ||
|
|
48a0ac9a96 | ||
|
|
7212fa1056 | ||
|
|
8d710609fd | ||
|
|
7dcbd11863 | ||
|
|
e075a8b49e | ||
|
|
d1dc041aaf | ||
|
|
85243edf4e | ||
|
|
faeea88b16 | ||
|
|
139d581e5b | ||
|
|
64b2d0da36 | ||
|
|
dc1a8b644a | ||
|
|
8bb3b53833 | ||
|
|
8112fe741e | ||
|
|
60f24eb22b | ||
|
|
fd20050fc9 | ||
|
|
c5946bf977 | ||
|
|
618d0c6397 | ||
|
|
362bb6e68b | ||
|
|
b88168c0d2 | ||
|
|
df919a4be8 | ||
|
|
45f864d2b4 | ||
|
|
602f02b867 | ||
|
|
5cf61c9ab4 | ||
|
|
49a7954824 | ||
|
|
198b52bf40 | ||
|
|
cb31140d3a | ||
|
|
f2c1d8f4b2 | ||
|
|
3ddba90d94 | ||
|
|
887a2a3c00 | ||
|
|
585777e62d | ||
|
|
640f45a5b3 | ||
|
|
8bcb545119 | ||
|
|
aa911cdb2e | ||
|
|
27be89d39a | ||
|
|
5ce66fca5c | ||
|
|
94e4044160 | ||
|
|
30eabfb9f6 | ||
|
|
a6eb261af0 | ||
|
|
6e4f74ae35 | ||
|
|
f091352c56 | ||
|
|
534ff5efdb | ||
|
|
51d92454ce |
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1,11 +1,19 @@
|
||||
.DS_Store
|
||||
/build/
|
||||
/dist/
|
||||
/frameworks/
|
||||
/external_binaries/
|
||||
/out/
|
||||
/vendor/brightray/vendor/download/
|
||||
/vendor/debian_wheezy_arm-sysroot/
|
||||
/vendor/debian_wheezy_i386-sysroot/
|
||||
/vendor/python_26/
|
||||
/vendor/npm/
|
||||
/vendor/llvm/
|
||||
/vendor/llvm-build/
|
||||
/vendor/.gclient
|
||||
node_modules/
|
||||
*.xcodeproj
|
||||
*.swp
|
||||
*.pyc
|
||||
debug.log
|
||||
npm-debug.log
|
||||
|
||||
25
.gitmodules
vendored
25
.gitmodules
vendored
@@ -1,15 +1,24 @@
|
||||
[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
|
||||
[submodule "vendor/gyp"]
|
||||
path = vendor/gyp
|
||||
url = https://github.com/svn2github/gyp.git
|
||||
url = https://github.com/atom/node.git
|
||||
[submodule "vendor/depot_tools"]
|
||||
path = vendor/depot_tools
|
||||
url = https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
[submodule "vendor/apm"]
|
||||
path = vendor/apm
|
||||
url = https://github.com/atom/apm.git
|
||||
[submodule "vendor/breakpad"]
|
||||
path = vendor/breakpad
|
||||
url = https://github.com/atom/chromium-breakpad.git
|
||||
[submodule "vendor/native_mate"]
|
||||
path = vendor/native_mate
|
||||
url = https://github.com/zcbenz/native-mate.git
|
||||
[submodule "vendor/crashpad"]
|
||||
path = vendor/crashpad
|
||||
url = https://github.com/atom/crashpad.git
|
||||
[submodule "vendor/requests"]
|
||||
path = vendor/requests
|
||||
url = https://github.com/kennethreitz/requests
|
||||
[submodule "vendor/boto"]
|
||||
path = vendor/boto
|
||||
url = https://github.com/boto/boto.git
|
||||
|
||||
28
.travis.yml
Normal file
28
.travis.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
git:
|
||||
depth: 10
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
language: cpp
|
||||
compiler: clang
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
env:
|
||||
- TARGET_ARCH=x64
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
env: TARGET_ARCH=arm
|
||||
- os: linux
|
||||
env: TARGET_ARCH=ia32
|
||||
allow_failures:
|
||||
- env: TARGET_ARCH=arm
|
||||
- env: TARGET_ARCH=ia32
|
||||
|
||||
script: './script/cibuild'
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
75
CONTRIBUTING.md
Normal file
75
CONTRIBUTING.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Contributing to Electron
|
||||
|
||||
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
|
||||
|
||||
This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable behavior to atom@github.com.
|
||||
|
||||
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).
|
||||
See the [Documentation Styleguide](/docs/styleguide.md).
|
||||
* Use short, present tense commit messages. See [Commit Message Styleguide](#git-commit-messages).
|
||||
|
||||
## 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
|
||||
48
LICENSE
48
LICENSE
@@ -1,28 +1,20 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
Copyright (c) 2014 GitHub Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
58
README-ko.md
Normal file
58
README-ko.md
Normal file
@@ -0,0 +1,58 @@
|
||||
[](http://electron.atom.io/)
|
||||
|
||||
[](https://travis-ci.org/atom/electron)
|
||||
[](https://david-dm.org/atom/electron#info=devDependencies)
|
||||
[](http://atom-slack.herokuapp.com/)
|
||||
|
||||
### [Electron](https://github.com/atom/electron/) 한국어 참조문서
|
||||
|
||||
:zap: *프레임워크 이름이 Atom Shell에서 Electron으로 변경되었습니다* :zap:
|
||||
|
||||
Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여 Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다. 이 프레임워크는 [io.js](http://iojs.org) 와
|
||||
[Chromium](http://www.chromium.org)을 기반으로 만들어 졌으며 [Atom Editor](https://github.com/atom/atom)에 사용되고 있습니다.
|
||||
|
||||
Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서 [@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요.
|
||||
|
||||
이 프로젝트는 기여자 규약 1.2를 준수합니다. 이 프로젝트에 참여할 때 코드를 유지해야 합니다. 받아들일 수 없는 행동은 atom@github.com로 보고 하십시오.
|
||||
|
||||
## 다운로드
|
||||
|
||||
Linux, Windows, Mac용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어 있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 받아 볼 수 있습니다.
|
||||
|
||||
또한 [`npm`](https://docs.npmjs.com/)을 통해 미리 빌드된 Electron 바이너리를 받을 수도 있습니다:
|
||||
|
||||
```sh
|
||||
# $PATH에 `electron` 커맨드를 등록하고 전역에 설치합니다.
|
||||
npm install electron-prebuilt -g
|
||||
|
||||
# 개발 의존성 모듈 형태로 설치합니다.
|
||||
npm install electron-prebuilt --save-dev
|
||||
```
|
||||
|
||||
### 미러
|
||||
|
||||
- [China](https://npm.taobao.org/mirrors/electron)
|
||||
|
||||
## 참조 문서
|
||||
|
||||
[Docs](https://github.com/atom/electron/tree/master/docs/README.md)에 개발 가이드와 API 레퍼런스가 있습니다.
|
||||
Electron을 빌드 하는 방법과 프로젝트에 기여하는 방법도 문서에 포함되어 있으니 참고하시기 바랍니다.
|
||||
|
||||
## 참조 문서 (번역)
|
||||
|
||||
- [브라질 포르투칼어](https://github.com/atom/electron/tree/master/docs-translations/pt-BR)
|
||||
- [한국어](https://github.com/atom/electron/tree/master/docs-translations/ko-KR)
|
||||
- [일본어](https://github.com/atom/electron/tree/master/docs-translations/jp)
|
||||
- [스페인어](https://github.com/atom/electron/tree/master/docs-translations/es)
|
||||
- [중국어 간체](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
||||
- [중국어 번체](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
||||
|
||||
## 커뮤니티
|
||||
|
||||
다음 링크를 통해 커뮤니티에 질문을 올리거나 토론을 나누실 수 있습니다:
|
||||
|
||||
- Atom 포럼의 [`electron`](http://discuss.atom.io/category/electron) 카테고리
|
||||
- Freenode 채팅의 `#atom-shell` 채널
|
||||
- Slack의 [`Atom`](http://atom-slack.herokuapp.com/) 채널
|
||||
|
||||
[awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트엔 커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 한번 참고해 보시기 바랍니다.
|
||||
72
README.md
72
README.md
@@ -1,20 +1,66 @@
|
||||
# Atom Shell
|
||||
[](http://electron.atom.io/)
|
||||
|
||||
Native layer for the [Atom](https://github.com/github/atom).
|
||||
[](https://travis-ci.org/atom/electron)
|
||||
[](https://david-dm.org/atom/electron#info=devDependencies)
|
||||
[](http://atom-slack.herokuapp.com/)
|
||||
|
||||
## Features
|
||||
:zap: *Formerly known as Atom Shell* :zap:
|
||||
|
||||
* Write desktop applications with web techniques
|
||||
* Support built-in and third-party modules of node.js
|
||||
* Support native node.js modules
|
||||
* Extended built-in modules for desktop programming
|
||||
* JavaScript on browser side
|
||||
* Easy API for cross-process communication
|
||||
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).
|
||||
|
||||
## Usage & Development
|
||||
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
|
||||
announcements.
|
||||
|
||||
See the docs [here](https://github.com/atom/atom-shell/tree/master/docs).
|
||||
This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0).
|
||||
By participating, you are expected to uphold this code. Please report
|
||||
unacceptable behavior to atom@github.com.
|
||||
|
||||
## License
|
||||
## Downloads
|
||||
|
||||
See the [`LICENSE`](LICENSE) file.
|
||||
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/electron/tree/master/docs) directory. It also
|
||||
contains documents describing how to build and contribute to Electron.
|
||||
|
||||
## Documentation Translations
|
||||
|
||||
- [Brazilian Portuguese](https://github.com/atom/electron/tree/master/docs-translations/pt-BR)
|
||||
- [Korean](https://github.com/atom/electron/tree/master/docs-translations/ko-KR)
|
||||
- [Japanese](https://github.com/atom/electron/tree/master/docs-translations/jp)
|
||||
- [Spanish](https://github.com/atom/electron/tree/master/docs-translations/es)
|
||||
- [Simplified Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
||||
- [Traditional Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
||||
|
||||
## Community
|
||||
|
||||
You can ask questions and interact with the community in the following
|
||||
locations:
|
||||
- [`electron`](http://discuss.atom.io/category/electron) category on the Atom
|
||||
forums
|
||||
- `#atom-shell` channel on Freenode
|
||||
- [`Atom`](http://atom-slack.herokuapp.com/) channel on Slack
|
||||
|
||||
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron)
|
||||
for a community maintained list of useful example apps, tools and resources.
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "app/atom_library_main.h"
|
||||
|
||||
#include "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,17 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_APP_ATOM_LIBRARY_MAIN_
|
||||
#define ATOM_APP_ATOM_LIBRARY_MAIN_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
extern "C" {
|
||||
__attribute__((visibility("default")))
|
||||
int AtomMain(int argc, const char* argv[]);
|
||||
}
|
||||
#endif // OS_MACOSX
|
||||
|
||||
#endif // ATOM_APP_ATOM_LIBRARY_MAIN_
|
||||
@@ -1,87 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "content/public/app/content_main.h"
|
||||
|
||||
namespace node {
|
||||
int Start(int argc, char *argv[]);
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
#include <windows.h> // NOLINT
|
||||
#include <shellapi.h> // NOLINT
|
||||
|
||||
#include "app/atom_main_delegate.h"
|
||||
#include "base/environment.h"
|
||||
#include "content/public/app/startup_helper_win.h"
|
||||
#include "sandbox/win/src/sandbox_types.h"
|
||||
|
||||
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
int argc = 0;
|
||||
wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
||||
|
||||
scoped_ptr<base::Environment> env(base::Environment::Create());
|
||||
std::string node_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,
|
||||
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,
|
||||
argv[i],
|
||||
size,
|
||||
NULL,
|
||||
NULL);
|
||||
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);
|
||||
}
|
||||
|
||||
sandbox::SandboxInterfaceInfo sandbox_info = {0};
|
||||
content::InitializeSandboxInfo(&sandbox_info);
|
||||
atom::AtomMainDelegate delegate;
|
||||
return content::ContentMain(instance, &sandbox_info, &delegate);
|
||||
}
|
||||
|
||||
#else // defined(OS_WIN)
|
||||
|
||||
#include "app/atom_library_main.h"
|
||||
|
||||
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));
|
||||
|
||||
return AtomMain(argc, argv);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,79 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "app/atom_main_delegate.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/logging.h"
|
||||
#include "browser/atom_browser_client.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "renderer/atom_renderer_client.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
#include "base/path_service.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomMainDelegate::AtomMainDelegate() {
|
||||
}
|
||||
|
||||
AtomMainDelegate::~AtomMainDelegate() {
|
||||
}
|
||||
|
||||
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
// Disable logging out to debug.log on Windows
|
||||
#if defined(OS_WIN)
|
||||
logging::InitLogging(
|
||||
L"debug.log",
|
||||
#if defined(DEBUG)
|
||||
logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG ,
|
||||
#else
|
||||
logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
|
||||
#endif // defined(NDEBUG)
|
||||
logging::LOCK_LOG_FILE,
|
||||
logging::DELETE_OLD_LOG_FILE,
|
||||
logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS);
|
||||
logging::SetLogItems(true, false, true, false);
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
return brightray::MainDelegate::BasicStartupComplete(exit_code);
|
||||
}
|
||||
|
||||
void AtomMainDelegate::PreSandboxStartup() {
|
||||
#if defined(OS_MACOSX)
|
||||
OverrideChildProcessPath();
|
||||
OverrideFrameworkBundlePath();
|
||||
SetProcessName();
|
||||
#endif
|
||||
InitializeResourceBundle();
|
||||
|
||||
// Disable renderer sandbox for most of node's functions.
|
||||
CommandLine* command_line = CommandLine::ForCurrentProcess();
|
||||
command_line->AppendSwitch(switches::kNoSandbox);
|
||||
}
|
||||
|
||||
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"));
|
||||
#endif
|
||||
|
||||
ui::ResourceBundle::InitSharedInstanceWithPakPath(path);
|
||||
}
|
||||
|
||||
content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
|
||||
browser_client_.reset(new AtomBrowserClient);
|
||||
return browser_client_.get();
|
||||
}
|
||||
|
||||
content::ContentRendererClient*
|
||||
AtomMainDelegate::CreateContentRendererClient() {
|
||||
renderer_client_.reset(new AtomRendererClient);
|
||||
return renderer_client_.get();
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_APP_ATOM_MAIN_DELEGATE_
|
||||
#define ATOM_APP_ATOM_MAIN_DELEGATE_
|
||||
|
||||
#include "brightray/common/main_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomMainDelegate : public brightray::MainDelegate {
|
||||
public:
|
||||
AtomMainDelegate();
|
||||
~AtomMainDelegate();
|
||||
|
||||
protected:
|
||||
virtual bool BasicStartupComplete(int* exit_code) OVERRIDE;
|
||||
virtual void PreSandboxStartup() OVERRIDE;
|
||||
virtual void InitializeResourceBundle();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
virtual base::FilePath GetResourcesPakFilePath();
|
||||
virtual void OverrideChildProcessPath();
|
||||
virtual void OverrideFrameworkBundlePath();
|
||||
virtual void SetProcessName();
|
||||
#endif
|
||||
|
||||
private:
|
||||
virtual content::ContentBrowserClient* CreateContentBrowserClient() OVERRIDE;
|
||||
virtual content::ContentRendererClient*
|
||||
CreateContentRendererClient() OVERRIDE;
|
||||
|
||||
scoped_ptr<content::ContentBrowserClient> browser_client_;
|
||||
scoped_ptr<content::ContentRendererClient> renderer_client_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomMainDelegate);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_APP_ATOM_MAIN_DELEGATE_
|
||||
@@ -1,66 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "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/path_service.h"
|
||||
#include "base/strings/sys_string_conversions.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 {
|
||||
|
||||
namespace {
|
||||
|
||||
base::FilePath GetFrameworksPath() {
|
||||
return brightray::MainApplicationBundlePath().Append("Contents")
|
||||
.Append("Frameworks");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
base::FilePath AtomMainDelegate::GetResourcesPakFilePath() {
|
||||
NSString* path = [base::mac::FrameworkBundle()
|
||||
pathForResource:@"content_shell" ofType:@"pak"];
|
||||
return base::mac::NSStringToFilePath(path);
|
||||
}
|
||||
|
||||
void AtomMainDelegate::OverrideFrameworkBundlePath() {
|
||||
base::mac::SetOverrideFrameworkBundlePath(
|
||||
GetFrameworksPath().Append("Atom.framework"));
|
||||
}
|
||||
|
||||
void AtomMainDelegate::OverrideChildProcessPath() {
|
||||
base::FilePath helper_path = GetFrameworksPath().Append("Atom Helper.app")
|
||||
.Append("Contents")
|
||||
.Append("MacOS")
|
||||
.Append("Atom Helper");
|
||||
PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
|
||||
}
|
||||
|
||||
void AtomMainDelegate::SetProcessName() {
|
||||
const auto& command_line = *CommandLine::ForCurrentProcess();
|
||||
auto process_type = command_line.GetSwitchValueASCII(switches::kProcessType);
|
||||
std::string suffix;
|
||||
if (process_type == switches::kRendererProcess)
|
||||
suffix = "Renderer";
|
||||
else if (process_type == switches::kPluginProcess ||
|
||||
process_type == switches::kPpapiPluginProcess)
|
||||
suffix = "Plug-In Host";
|
||||
else if (process_type == switches::kUtilityProcess)
|
||||
suffix = "Utility";
|
||||
else
|
||||
return;
|
||||
|
||||
base::mac::SetProcessName(base::mac::NSToCFCast(base::SysUTF8ToNSString(
|
||||
brightray::GetApplicationName() + " " + suffix)));
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
BIN
app/win/atom.rc
BIN
app/win/atom.rc
Binary file not shown.
623
atom.gyp
623
atom.gyp
@@ -1,219 +1,34 @@
|
||||
{
|
||||
'variables': {
|
||||
'project_name': 'atom',
|
||||
'product_name': 'Atom',
|
||||
'app_sources': [
|
||||
'app/atom_main.cc',
|
||||
],
|
||||
'bundle_sources': [
|
||||
'browser/mac/atom.icns',
|
||||
],
|
||||
'coffee_sources': [
|
||||
'browser/api/lib/app.coffee',
|
||||
'browser/api/lib/atom-delegate.coffee',
|
||||
'browser/api/lib/auto-updater.coffee',
|
||||
'browser/api/lib/browser-window.coffee',
|
||||
'browser/api/lib/crash-reporter.coffee',
|
||||
'browser/api/lib/dialog.coffee',
|
||||
'browser/api/lib/ipc.coffee',
|
||||
'browser/api/lib/menu.coffee',
|
||||
'browser/api/lib/menu-item.coffee',
|
||||
'browser/api/lib/power-monitor.coffee',
|
||||
'browser/api/lib/protocol.coffee',
|
||||
'browser/atom/atom.coffee',
|
||||
'browser/atom/objects-registry.coffee',
|
||||
'browser/atom/rpc-server.coffee',
|
||||
'common/api/lib/callbacks-registry.coffee',
|
||||
'common/api/lib/clipboard.coffee',
|
||||
'common/api/lib/id-weak-map.coffee',
|
||||
'common/api/lib/shell.coffee',
|
||||
'renderer/api/lib/ipc.coffee',
|
||||
'renderer/api/lib/remote.coffee',
|
||||
],
|
||||
'lib_sources': [
|
||||
'app/atom_main_delegate.cc',
|
||||
'app/atom_main_delegate.h',
|
||||
'app/atom_main_delegate_mac.mm',
|
||||
'browser/api/atom_api_app.cc',
|
||||
'browser/api/atom_api_app.h',
|
||||
'browser/api/atom_api_auto_updater.cc',
|
||||
'browser/api/atom_api_auto_updater.h',
|
||||
'browser/api/atom_api_browser_ipc.cc',
|
||||
'browser/api/atom_api_browser_ipc.h',
|
||||
'browser/api/atom_api_crash_reporter.h',
|
||||
'browser/api/atom_api_crash_reporter.cc',
|
||||
'browser/api/atom_api_dialog.cc',
|
||||
'browser/api/atom_api_dialog.h',
|
||||
'browser/api/atom_api_event.cc',
|
||||
'browser/api/atom_api_event.h',
|
||||
'browser/api/atom_api_event_emitter.cc',
|
||||
'browser/api/atom_api_event_emitter.h',
|
||||
'browser/api/atom_api_menu.cc',
|
||||
'browser/api/atom_api_menu.h',
|
||||
'browser/api/atom_api_menu_mac.h',
|
||||
'browser/api/atom_api_menu_mac.mm',
|
||||
'browser/api/atom_api_menu_win.cc',
|
||||
'browser/api/atom_api_menu_win.h',
|
||||
'browser/api/atom_api_power_monitor.cc',
|
||||
'browser/api/atom_api_power_monitor.h',
|
||||
'browser/api/atom_api_protocol.cc',
|
||||
'browser/api/atom_api_protocol.h',
|
||||
'browser/api/atom_api_window.cc',
|
||||
'browser/api/atom_api_window.h',
|
||||
'browser/api/atom_browser_bindings.cc',
|
||||
'browser/api/atom_browser_bindings.h',
|
||||
'browser/auto_updater.cc',
|
||||
'browser/auto_updater.h',
|
||||
'browser/auto_updater_delegate.cc',
|
||||
'browser/auto_updater_delegate.h',
|
||||
'browser/auto_updater_mac.mm',
|
||||
'browser/auto_updater_win.cc',
|
||||
'browser/atom_application_mac.h',
|
||||
'browser/atom_application_mac.mm',
|
||||
'browser/atom_application_delegate_mac.h',
|
||||
'browser/atom_application_delegate_mac.mm',
|
||||
'browser/atom_browser_client.cc',
|
||||
'browser/atom_browser_client.h',
|
||||
'browser/atom_browser_context.cc',
|
||||
'browser/atom_browser_context.h',
|
||||
'browser/atom_browser_main_parts.cc',
|
||||
'browser/atom_browser_main_parts.h',
|
||||
'browser/atom_browser_main_parts_mac.mm',
|
||||
'browser/atom_javascript_dialog_manager.cc',
|
||||
'browser/atom_javascript_dialog_manager.h',
|
||||
'browser/browser.cc',
|
||||
'browser/browser.h',
|
||||
'browser/browser_mac.mm',
|
||||
'browser/browser_win.cc',
|
||||
'browser/browser_observer.h',
|
||||
'browser/crash_reporter.h',
|
||||
'browser/crash_reporter_mac.mm',
|
||||
'browser/crash_reporter_win.cc',
|
||||
'browser/native_window.cc',
|
||||
'browser/native_window.h',
|
||||
'browser/native_window_mac.h',
|
||||
'browser/native_window_mac.mm',
|
||||
'browser/native_window_win.cc',
|
||||
'browser/native_window_win.h',
|
||||
'browser/native_window_observer.h',
|
||||
'browser/net/adapter_request_job.cc',
|
||||
'browser/net/adapter_request_job.h',
|
||||
'browser/net/atom_url_request_context_getter.cc',
|
||||
'browser/net/atom_url_request_context_getter.h',
|
||||
'browser/net/atom_url_request_job_factory.cc',
|
||||
'browser/net/atom_url_request_job_factory.h',
|
||||
'browser/net/url_request_string_job.cc',
|
||||
'browser/net/url_request_string_job.h',
|
||||
'browser/ui/accelerator_util.cc',
|
||||
'browser/ui/accelerator_util.h',
|
||||
'browser/ui/accelerator_util_mac.mm',
|
||||
'browser/ui/accelerator_util_win.cc',
|
||||
'browser/ui/atom_event_processing_window.h',
|
||||
'browser/ui/atom_event_processing_window.mm',
|
||||
'browser/ui/atom_menu_controller_mac.h',
|
||||
'browser/ui/atom_menu_controller_mac.mm',
|
||||
'browser/ui/file_dialog.h',
|
||||
'browser/ui/file_dialog_mac.mm',
|
||||
'browser/ui/file_dialog_win.cc',
|
||||
'browser/ui/message_box.h',
|
||||
'browser/ui/message_box_mac.mm',
|
||||
'browser/ui/message_box_win.cc',
|
||||
'browser/ui/nsalert_synchronous_sheet_mac.h',
|
||||
'browser/ui/nsalert_synchronous_sheet_mac.mm',
|
||||
'browser/ui/win/menu_2.cc',
|
||||
'browser/ui/win/menu_2.h',
|
||||
'browser/ui/win/native_menu_win.cc',
|
||||
'browser/ui/win/native_menu_win.h',
|
||||
'browser/window_list.cc',
|
||||
'browser/window_list.h',
|
||||
'browser/window_list_observer.h',
|
||||
'common/api/api_messages.cc',
|
||||
'common/api/api_messages.h',
|
||||
'common/api/atom_api_clipboard.cc',
|
||||
'common/api/atom_api_clipboard.h',
|
||||
'common/api/atom_api_id_weak_map.cc',
|
||||
'common/api/atom_api_id_weak_map.h',
|
||||
'common/api/atom_api_shell.cc',
|
||||
'common/api/atom_api_shell.h',
|
||||
'common/api/atom_api_v8_util.cc',
|
||||
'common/api/atom_bindings.cc',
|
||||
'common/api/atom_bindings.h',
|
||||
'common/api/atom_extensions.cc',
|
||||
'common/api/atom_extensions.h',
|
||||
'common/api/object_life_monitor.cc',
|
||||
'common/api/object_life_monitor.h',
|
||||
'common/draggable_region.cc',
|
||||
'common/draggable_region.h',
|
||||
'common/node_bindings.cc',
|
||||
'common/node_bindings.h',
|
||||
'common/node_bindings_mac.cc',
|
||||
'common/node_bindings_mac.h',
|
||||
'common/node_bindings_win.cc',
|
||||
'common/node_bindings_win.h',
|
||||
'common/options_switches.cc',
|
||||
'common/options_switches.h',
|
||||
'common/platform_util.h',
|
||||
'common/platform_util_mac.mm',
|
||||
'common/platform_util_win.cc',
|
||||
'common/v8_conversions.h',
|
||||
'common/v8_value_converter_impl.cc',
|
||||
'common/v8_value_converter_impl.h',
|
||||
'renderer/api/atom_api_renderer_ipc.cc',
|
||||
'renderer/api/atom_api_renderer_ipc.h',
|
||||
'renderer/api/atom_renderer_bindings.cc',
|
||||
'renderer/api/atom_renderer_bindings.h',
|
||||
'renderer/atom_render_view_observer.cc',
|
||||
'renderer/atom_render_view_observer.h',
|
||||
'renderer/atom_renderer_client.cc',
|
||||
'renderer/atom_renderer_client.h',
|
||||
],
|
||||
'framework_sources': [
|
||||
'app/atom_library_main.cc',
|
||||
'app/atom_library_main.h',
|
||||
'project_name%': 'electron',
|
||||
'product_name%': 'Electron',
|
||||
'company_name%': 'GitHub, Inc',
|
||||
'company_abbr%': 'github',
|
||||
'version%': '0.33.2',
|
||||
},
|
||||
'includes': [
|
||||
'filenames.gypi',
|
||||
'vendor/native_mate/native_mate_files.gypi',
|
||||
],
|
||||
'target_defaults': {
|
||||
'defines': [
|
||||
'ATOM_PRODUCT_NAME="<(product_name)"',
|
||||
'ATOM_PROJECT_NAME="<(project_name)"',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="win"', {
|
||||
'app_sources': [
|
||||
'app/win/resource.h',
|
||||
'app/win/atom.rc',
|
||||
'<(libchromiumcontent_src_dir)/content/app/startup_helper_win.cc',
|
||||
['OS=="mac"', {
|
||||
'mac_framework_dirs': [
|
||||
'<(source_root)/external_binaries',
|
||||
],
|
||||
}], # OS=="win"
|
||||
}],
|
||||
],
|
||||
'fix_framework_link_command': [
|
||||
'install_name_tool',
|
||||
'-change',
|
||||
'@loader_path/../Frameworks/Sparkle.framework/Versions/A/Sparkle',
|
||||
'@rpath/Sparkle.framework/Versions/A/Sparkle',
|
||||
'-change',
|
||||
'@executable_path/../Frameworks/Quincy.framework/Versions/A/Quincy',
|
||||
'@rpath/Quincy.framework/Versions/A/Quincy',
|
||||
'${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}'
|
||||
],
|
||||
'atom_source_root': '<!(python tools/atom_source_root.py)',
|
||||
},
|
||||
'target_defaults': {
|
||||
'mac_framework_dirs': [
|
||||
'<(atom_source_root)/frameworks',
|
||||
],
|
||||
'includes': [
|
||||
# Rules for excluding e.g. foo_win.cc from the build on non-Windows.
|
||||
'filename_rules.gypi',
|
||||
],
|
||||
'configurations': {
|
||||
'Debug': {
|
||||
'defines': [
|
||||
'DEBUG',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': '<(project_name)',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'generated_sources',
|
||||
'compile_coffee',
|
||||
'<(project_name)_lib',
|
||||
],
|
||||
'sources': [
|
||||
@@ -234,7 +49,8 @@
|
||||
'<(project_name)_helper',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'INFOPLIST_FILE': 'browser/mac/Info.plist',
|
||||
'ATOM_BUNDLE_ID': 'com.<(company_abbr).<(project_name)',
|
||||
'INFOPLIST_FILE': 'atom/browser/resources/mac/Info.plist',
|
||||
'LD_RUNPATH_SEARCH_PATHS': [
|
||||
'@executable_path/../Frameworks',
|
||||
],
|
||||
@@ -247,25 +63,20 @@
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Frameworks',
|
||||
'files': [
|
||||
'<(PRODUCT_DIR)/<(product_name) Helper.app',
|
||||
'<(PRODUCT_DIR)/<(product_name).framework',
|
||||
'frameworks/Sparkle.framework',
|
||||
'frameworks/Quincy.framework',
|
||||
'<(PRODUCT_DIR)/<(product_name) Framework.framework',
|
||||
'external_binaries/Squirrel.framework',
|
||||
'external_binaries/ReactiveCocoa.framework',
|
||||
'external_binaries/Mantle.framework',
|
||||
],
|
||||
},
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Resources/browser',
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Resources',
|
||||
'files': [
|
||||
'browser/default_app',
|
||||
'atom/browser/default_app',
|
||||
],
|
||||
},
|
||||
],
|
||||
'postbuilds': [
|
||||
{
|
||||
'postbuild_name': 'Fix Framework Link',
|
||||
'action': [
|
||||
'<@(fix_framework_link_command)',
|
||||
],
|
||||
},
|
||||
{
|
||||
# This postbuid step is responsible for creating the following
|
||||
# helpers:
|
||||
@@ -282,43 +93,158 @@
|
||||
'<(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"', {
|
||||
'include_dirs': [
|
||||
'<(libchromiumcontent_dir)/gen/ui/resources',
|
||||
],
|
||||
'msvs_settings': {
|
||||
'VCManifestTool': {
|
||||
'EmbedManifest': 'true',
|
||||
'AdditionalManifestFiles': 'atom/browser/resources/win/atom.manifest',
|
||||
}
|
||||
},
|
||||
'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)/libGLESv2.dll',
|
||||
'<(libchromiumcontent_resources_dir)/content_shell.pak',
|
||||
'<@(copied_libraries)',
|
||||
'<(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',
|
||||
],
|
||||
},
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/resources/browser',
|
||||
'destination': '<(PRODUCT_DIR)/resources',
|
||||
'files': [
|
||||
'browser/default_app',
|
||||
'atom/browser/default_app',
|
||||
]
|
||||
},
|
||||
],
|
||||
}, {
|
||||
'dependencies': [
|
||||
'vendor/breakpad/breakpad.gyp:dump_syms#host',
|
||||
],
|
||||
}], # OS=="win"
|
||||
['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': [
|
||||
'<@(copied_libraries)',
|
||||
'<(libchromiumcontent_dir)/icudtl.dat',
|
||||
'<(libchromiumcontent_dir)/content_shell.pak',
|
||||
'<(libchromiumcontent_dir)/natives_blob.bin',
|
||||
'<(libchromiumcontent_dir)/snapshot_blob.bin',
|
||||
],
|
||||
},
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/resources',
|
||||
'files': [
|
||||
'atom/browser/default_app',
|
||||
]
|
||||
},
|
||||
],
|
||||
}], # OS=="linux"
|
||||
],
|
||||
},
|
||||
}, # target <(project_name)
|
||||
{
|
||||
'target_name': '<(project_name)_lib',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'atom_coffee2c',
|
||||
'vendor/brightray/brightray.gyp:brightray',
|
||||
'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',
|
||||
],
|
||||
'sources': [
|
||||
'<@(lib_sources)',
|
||||
],
|
||||
'include_dirs': [
|
||||
'.',
|
||||
'vendor',
|
||||
'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"`.
|
||||
'<(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': [
|
||||
@@ -329,65 +255,125 @@
|
||||
'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',
|
||||
'<(atom_source_root)/<(libchromiumcontent_library_dir)/chromiumviews.lib',
|
||||
'-lcomctl32.lib',
|
||||
'-lcomdlg32.lib',
|
||||
'-lwininet.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/crashpad/client/client.gyp:crashpad_client',
|
||||
'vendor/crashpad/handler/handler.gyp:crashpad_handler',
|
||||
],
|
||||
}], # OS=="mac"
|
||||
['OS=="linux"', {
|
||||
'link_settings': {
|
||||
'ldflags': [
|
||||
# Make binary search for libraries under current directory, so we
|
||||
# don't have to manually set $LD_LIBRARY_PATH:
|
||||
# http://serverfault.com/questions/279068/cant-find-so-in-the-same-directory-as-the-executable
|
||||
'-rpath \$$ORIGIN',
|
||||
# Make native module dynamic loading work.
|
||||
'-rdynamic',
|
||||
],
|
||||
},
|
||||
# Required settings of using breakpad.
|
||||
'cflags_cc': [
|
||||
'-Wno-empty-body',
|
||||
'-Wno-reserved-user-defined-literal',
|
||||
],
|
||||
'include_dirs': [
|
||||
'vendor/breakpad/src',
|
||||
],
|
||||
'dependencies': [
|
||||
'vendor/breakpad/breakpad.gyp:breakpad_client',
|
||||
],
|
||||
}], # OS=="linux"
|
||||
],
|
||||
},
|
||||
}, # 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"
|
||||
['OS=="win"', {
|
||||
'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"
|
||||
'outputs': [
|
||||
'<(resources_path)/atom.asar',
|
||||
],
|
||||
},
|
||||
'action': [
|
||||
'python',
|
||||
'tools/coffee2asar.py',
|
||||
'<@(_outputs)',
|
||||
'<@(_inputs)',
|
||||
],
|
||||
}
|
||||
],
|
||||
},
|
||||
}, # target compile_coffee
|
||||
{
|
||||
'target_name': 'atom_coffee2c',
|
||||
'type': 'none',
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'atom_coffee2c',
|
||||
'inputs': [
|
||||
'<@(coffee2c_sources)',
|
||||
],
|
||||
'outputs': [
|
||||
'<(SHARED_INTERMEDIATE_DIR)/atom_natives.h',
|
||||
],
|
||||
'action': [
|
||||
'python',
|
||||
'tools/coffee2c.py',
|
||||
'<@(_outputs)',
|
||||
'<@(_inputs)',
|
||||
],
|
||||
}
|
||||
],
|
||||
}, # target atom_coffee2c
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
'targets': [
|
||||
{
|
||||
'target_name': '<(project_name)_framework',
|
||||
'product_name': '<(product_name)',
|
||||
'product_name': '<(product_name) Framework',
|
||||
'type': 'shared_library',
|
||||
'dependencies': [
|
||||
'<(project_name)_lib',
|
||||
@@ -398,7 +384,7 @@
|
||||
'include_dirs': [
|
||||
'.',
|
||||
'vendor',
|
||||
'<(libchromiumcontent_include_dir)',
|
||||
'<(libchromiumcontent_src_dir)',
|
||||
],
|
||||
'export_dependent_settings': [
|
||||
'<(project_name)_lib',
|
||||
@@ -406,20 +392,24 @@
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'$(SDKROOT)/System/Library/Frameworks/Carbon.framework',
|
||||
'frameworks/Sparkle.framework',
|
||||
'frameworks/Quincy.framework',
|
||||
'$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework',
|
||||
'external_binaries/Squirrel.framework',
|
||||
'external_binaries/ReactiveCocoa.framework',
|
||||
'external_binaries/Mantle.framework',
|
||||
],
|
||||
},
|
||||
'mac_bundle': 1,
|
||||
'mac_bundle_resources': [
|
||||
'browser/mac/MainMenu.xib',
|
||||
'<(libchromiumcontent_resources_dir)/content_shell.pak',
|
||||
'atom/common/resources/mac/MainMenu.xib',
|
||||
'<(libchromiumcontent_dir)/content_shell.pak',
|
||||
'<(libchromiumcontent_dir)/icudtl.dat',
|
||||
'<(libchromiumcontent_dir)/natives_blob.bin',
|
||||
'<(libchromiumcontent_dir)/snapshot_blob.bin',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'LIBRARY_SEARCH_PATHS': [
|
||||
'<(libchromiumcontent_library_dir)',
|
||||
],
|
||||
'LD_DYLIB_INSTALL_NAME': '@rpath/<(product_name).framework/<(product_name)',
|
||||
'ATOM_BUNDLE_ID': 'com.<(company_abbr).<(project_name).framework',
|
||||
'INFOPLIST_FILE': 'atom/common/resources/mac/Info.plist',
|
||||
'LD_DYLIB_INSTALL_NAME': '@rpath/<(product_name) Framework.framework/<(product_name) Framework',
|
||||
'LD_RUNPATH_SEARCH_PATHS': [
|
||||
'@loader_path/Libraries',
|
||||
],
|
||||
@@ -429,27 +419,60 @@
|
||||
},
|
||||
'copies': [
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/<(product_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)',
|
||||
],
|
||||
},
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Resources',
|
||||
'files': [
|
||||
'<(PRODUCT_DIR)/crashpad_handler',
|
||||
],
|
||||
},
|
||||
],
|
||||
'postbuilds': [
|
||||
{
|
||||
'postbuild_name': 'Fix Framework Link',
|
||||
'postbuild_name': 'Fix path of libnode',
|
||||
'action': [
|
||||
'<@(fix_framework_link_command)',
|
||||
'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': 'Fix path of ffmpeg',
|
||||
'action': [
|
||||
'install_name_tool',
|
||||
'-change',
|
||||
'@loader_path/libffmpeg.dylib',
|
||||
'@rpath/libffmpeg.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',
|
||||
'<(product_name)',
|
||||
'<(product_name) Framework',
|
||||
'Libraries',
|
||||
'Frameworks',
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -469,53 +492,39 @@
|
||||
],
|
||||
'mac_bundle': 1,
|
||||
'xcode_settings': {
|
||||
'INFOPLIST_FILE': 'renderer/mac/Info.plist',
|
||||
'ATOM_BUNDLE_ID': 'com.<(company_abbr).<(project_name).helper',
|
||||
'INFOPLIST_FILE': 'atom/renderer/resources/mac/Info.plist',
|
||||
'LD_RUNPATH_SEARCH_PATHS': [
|
||||
'@executable_path/../../..',
|
||||
],
|
||||
},
|
||||
'postbuilds': [
|
||||
{
|
||||
'postbuild_name': 'Fix Framework Link',
|
||||
'action': [
|
||||
'<@(fix_framework_link_command)',
|
||||
],
|
||||
},
|
||||
],
|
||||
}, # 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"
|
||||
],
|
||||
}
|
||||
|
||||
114
atom/app/atom_content_client.cc
Normal file
114
atom/app/atom_content_client.cc
Normal file
@@ -0,0 +1,114 @@
|
||||
// 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/atom_version.h"
|
||||
#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 "content/public/common/user_agent.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;
|
||||
}
|
||||
|
||||
std::string AtomContentClient::GetUserAgent() const {
|
||||
return content::BuildUserAgentFromProduct(
|
||||
"Chrome/" CHROME_VERSION_STRING " "
|
||||
ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING);
|
||||
}
|
||||
|
||||
void AtomContentClient::AddAdditionalSchemes(
|
||||
std::vector<std::string>* standard_schemes,
|
||||
std::vector<std::string>* savable_schemes) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto custom_schemes = command_line->GetSwitchValueASCII(
|
||||
switches::kRegisterStandardSchemes);
|
||||
if (!custom_schemes.empty()) {
|
||||
std::vector<std::string> schemes;
|
||||
base::SplitString(custom_schemes, ',', &schemes);
|
||||
standard_schemes->insert(standard_schemes->end(),
|
||||
schemes.begin(),
|
||||
schemes.end());
|
||||
}
|
||||
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
|
||||
36
atom/app/atom_content_client.h
Normal file
36
atom/app/atom_content_client.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// 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;
|
||||
std::string GetUserAgent() 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_
|
||||
20
atom/app/atom_library_main.h
Normal file
20
atom/app/atom_library_main.h
Normal file
@@ -0,0 +1,20 @@
|
||||
// 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_APP_ATOM_LIBRARY_MAIN_H_
|
||||
#define ATOM_APP_ATOM_LIBRARY_MAIN_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
extern "C" {
|
||||
__attribute__((visibility("default")))
|
||||
int AtomMain(int argc, const char* argv[]);
|
||||
|
||||
__attribute__((visibility("default")))
|
||||
int AtomInitializeICUandStartNode(int argc, char *argv[]);
|
||||
}
|
||||
#endif // OS_MACOSX
|
||||
|
||||
#endif // ATOM_APP_ATOM_LIBRARY_MAIN_H_
|
||||
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_delegate.h"
|
||||
#include "atom/app/node_main.h"
|
||||
#include "atom/common/atom_command_line.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
|
||||
193
atom/app/atom_main.cc
Normal file
193
atom/app/atom_main.cc
Normal file
@@ -0,0 +1,193 @@
|
||||
// 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <shellscalingapi.h>
|
||||
#include <tchar.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#include "atom/app/atom_main_delegate.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"
|
||||
#else // defined(OS_LINUX)
|
||||
#include "atom/app/atom_library_main.h"
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
#include "atom/app/node_main.h"
|
||||
#include "atom/common/atom_command_line.h"
|
||||
#include "base/at_exit.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);
|
||||
|
||||
scoped_ptr<base::Environment> env(base::Environment::Create());
|
||||
|
||||
// Make output work in console if we are not in cygiwn.
|
||||
std::string os;
|
||||
if (env->GetVar("OS", &os) && os != "cygwin") {
|
||||
AttachConsole(ATTACH_PARENT_PROCESS);
|
||||
|
||||
FILE* dontcare;
|
||||
freopen_s(&dontcare, "CON", "w", stdout);
|
||||
freopen_s(&dontcare, "CON", "w", stderr);
|
||||
freopen_s(&dontcare, "CON", "r", stdin);
|
||||
}
|
||||
|
||||
// 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,
|
||||
argv[i],
|
||||
size,
|
||||
NULL,
|
||||
NULL);
|
||||
if (result == 0) {
|
||||
// This should never happen.
|
||||
fprintf(stderr, "Could not convert arguments to utf8.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
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::AtExitManager atexit_manager;
|
||||
base::i18n::InitializeICU();
|
||||
return atom::NodeMain(argc, argv);
|
||||
} else if (env->GetVar("ATOM_SHELL_INTERNAL_CRASH_SERVICE",
|
||||
&crash_service_indicator) &&
|
||||
crash_service_indicator == "1") {
|
||||
return crash_service::Main(cmd);
|
||||
}
|
||||
|
||||
sandbox::SandboxInterfaceInfo sandbox_info = {0};
|
||||
content::InitializeSandboxInfo(&sandbox_info);
|
||||
atom::AtomMainDelegate delegate;
|
||||
|
||||
// We don't want to set DPI awareness on pre-Win7 because we don't support
|
||||
// DirectWrite there. GDI fonts are kerned very badly, so better to leave
|
||||
// DPI-unaware and at effective 1.0. See also ShouldUseDirectWrite().
|
||||
if (base::win::GetVersion() >= base::win::VERSION_WIN7)
|
||||
EnableHighDPISupport();
|
||||
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.instance = instance;
|
||||
params.sandbox_info = &sandbox_info;
|
||||
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) {
|
||||
base::i18n::InitializeICU();
|
||||
base::AtExitManager atexit_manager;
|
||||
return atom::NodeMain(argc, const_cast<char**>(argv));
|
||||
}
|
||||
|
||||
atom::AtomMainDelegate 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 AtomInitializeICUandStartNode(argc, const_cast<char**>(argv));
|
||||
}
|
||||
|
||||
return AtomMain(argc, argv);
|
||||
}
|
||||
|
||||
#endif // defined(OS_MACOSX)
|
||||
10
atom/app/atom_main.h
Normal file
10
atom/app/atom_main.h
Normal file
@@ -0,0 +1,10 @@
|
||||
// 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_APP_ATOM_MAIN_H_
|
||||
#define ATOM_APP_ATOM_MAIN_H_
|
||||
|
||||
#include "content/public/app/content_main.h"
|
||||
|
||||
#endif // ATOM_APP_ATOM_MAIN_H_
|
||||
128
atom/app/atom_main_delegate.cc
Normal file
128
atom/app/atom_main_delegate.cc
Normal file
@@ -0,0 +1,128 @@
|
||||
// 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_delegate.h"
|
||||
|
||||
#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 "content/public/common/content_switches.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomMainDelegate::AtomMainDelegate() {
|
||||
}
|
||||
|
||||
AtomMainDelegate::~AtomMainDelegate() {
|
||||
}
|
||||
|
||||
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
// Disable logging out to debug.log on Windows
|
||||
logging::LoggingSettings settings;
|
||||
#if defined(OS_WIN)
|
||||
#if defined(DEBUG)
|
||||
settings.logging_dest = logging::LOG_TO_ALL;
|
||||
settings.log_file = L"debug.log";
|
||||
settings.lock_log = logging::LOCK_LOG_FILE;
|
||||
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
|
||||
#else
|
||||
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
||||
#endif // defined(DEBUG)
|
||||
#else // defined(OS_WIN)
|
||||
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
||||
#endif // !defined(OS_WIN)
|
||||
logging::InitLogging(settings);
|
||||
|
||||
// Logging with pid and timestamp.
|
||||
logging::SetLogItems(true, false, true, false);
|
||||
|
||||
#if defined(DEBUG) && defined(OS_LINUX)
|
||||
// Enable convient stack printing.
|
||||
base::debug::EnableInProcessStackDumping();
|
||||
#endif
|
||||
|
||||
return brightray::MainDelegate::BasicStartupComplete(exit_code);
|
||||
}
|
||||
|
||||
void AtomMainDelegate::PreSandboxStartup() {
|
||||
brightray::MainDelegate::PreSandboxStartup();
|
||||
|
||||
// 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;
|
||||
|
||||
#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);
|
||||
|
||||
// Allow file:// URIs to read other file:// URIs by default.
|
||||
command_line->AppendSwitch(switches::kAllowFileAccessFromFiles);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// Enable AVFoundation.
|
||||
command_line->AppendSwitch("enable-avfoundation");
|
||||
#endif
|
||||
}
|
||||
|
||||
content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
|
||||
browser_client_.reset(new AtomBrowserClient);
|
||||
return browser_client_.get();
|
||||
}
|
||||
|
||||
content::ContentRendererClient*
|
||||
AtomMainDelegate::CreateContentRendererClient() {
|
||||
renderer_client_.reset(new AtomRendererClient);
|
||||
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
|
||||
46
atom/app/atom_main_delegate.h
Normal file
46
atom/app/atom_main_delegate.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// 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_APP_ATOM_MAIN_DELEGATE_H_
|
||||
#define ATOM_APP_ATOM_MAIN_DELEGATE_H_
|
||||
|
||||
#include "brightray/common/main_delegate.h"
|
||||
#include "brightray/common/content_client.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomMainDelegate : public brightray::MainDelegate {
|
||||
public:
|
||||
AtomMainDelegate();
|
||||
~AtomMainDelegate();
|
||||
|
||||
protected:
|
||||
// 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)
|
||||
void OverrideChildProcessPath() override;
|
||||
void OverrideFrameworkBundlePath() override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
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);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_APP_ATOM_MAIN_DELEGATE_H_
|
||||
51
atom/app/atom_main_delegate_mac.mm
Normal file
51
atom/app/atom_main_delegate_mac.mm
Normal file
@@ -0,0 +1,51 @@
|
||||
// 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"
|
||||
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
#include "brightray/common/mac/main_application_bundle.h"
|
||||
#include "content/public/common/content_paths.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
base::FilePath GetFrameworksPath() {
|
||||
return brightray::MainApplicationBundlePath().Append("Contents")
|
||||
.Append("Frameworks");
|
||||
}
|
||||
|
||||
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_PRODUCT_NAME " Framework.framework"));
|
||||
}
|
||||
|
||||
void AtomMainDelegate::OverrideChildProcessPath() {
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
77
atom/app/node_main.cc
Normal file
77
atom/app/node_main.cc
Normal file
@@ -0,0 +1,77 @@
|
||||
// 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/app/uv_task_runner.h"
|
||||
#include "atom/browser/javascript_environment.h"
|
||||
#include "atom/browser/node_debugger.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/thread_task_runner_handle.h"
|
||||
#include "gin/array_buffer.h"
|
||||
#include "gin/public/isolate_holder.h"
|
||||
#include "gin/v8_initializer.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
int NodeMain(int argc, char *argv[]) {
|
||||
base::CommandLine::Init(argc, argv);
|
||||
|
||||
argv = uv_setup_args(argc, argv);
|
||||
int exec_argc;
|
||||
const char** exec_argv;
|
||||
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
|
||||
|
||||
int exit_code = 1;
|
||||
{
|
||||
// Feed gin::PerIsolateData with a task runner.
|
||||
uv_loop_t* loop = uv_default_loop();
|
||||
scoped_refptr<UvTaskRunner> uv_task_runner(new UvTaskRunner(loop));
|
||||
base::ThreadTaskRunnerHandle handle(uv_task_runner);
|
||||
|
||||
gin::V8Initializer::LoadV8Snapshot();
|
||||
gin::V8Initializer::LoadV8Natives();
|
||||
gin::IsolateHolder::Initialize(
|
||||
gin::IsolateHolder::kNonStrictMode,
|
||||
gin::ArrayBufferAllocator::SharedInstance());
|
||||
|
||||
JavascriptEnvironment gin_env;
|
||||
node::Environment* env = node::CreateEnvironment(
|
||||
gin_env.isolate(), loop, gin_env.context(), argc, argv,
|
||||
exec_argc, exec_argv);
|
||||
|
||||
// Start our custom debugger implementation.
|
||||
NodeDebugger node_debugger(gin_env.isolate());
|
||||
if (node_debugger.IsRunning())
|
||||
env->AssignToContext(v8::Debug::GetDebugContext());
|
||||
|
||||
node::LoadEnvironment(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_
|
||||
55
atom/app/uv_task_runner.cc
Normal file
55
atom/app/uv_task_runner.cc
Normal file
@@ -0,0 +1,55 @@
|
||||
// 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/uv_task_runner.h"
|
||||
|
||||
#include "base/stl_util.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
UvTaskRunner::UvTaskRunner(uv_loop_t* loop) : loop_(loop) {
|
||||
}
|
||||
|
||||
UvTaskRunner::~UvTaskRunner() {
|
||||
for (auto& iter : tasks_) {
|
||||
uv_unref(reinterpret_cast<uv_handle_t*>(iter.first));
|
||||
delete iter.first;
|
||||
}
|
||||
}
|
||||
|
||||
bool UvTaskRunner::PostDelayedTask(const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) {
|
||||
uv_timer_t* timer = new uv_timer_t;
|
||||
timer->data = this;
|
||||
uv_timer_init(loop_, timer);
|
||||
uv_timer_start(timer, UvTaskRunner::OnTimeout, delay.InMilliseconds(), 0);
|
||||
tasks_[timer] = task;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UvTaskRunner::RunsTasksOnCurrentThread() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UvTaskRunner::PostNonNestableDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) {
|
||||
return PostDelayedTask(from_here, task, delay);;
|
||||
}
|
||||
|
||||
// static
|
||||
void UvTaskRunner::OnTimeout(uv_timer_t* timer) {
|
||||
UvTaskRunner* self = static_cast<UvTaskRunner*>(timer->data);
|
||||
if (!ContainsKey(self->tasks_, timer))
|
||||
return;
|
||||
|
||||
self->tasks_[timer].Run();
|
||||
self->tasks_.erase(timer);
|
||||
uv_unref(reinterpret_cast<uv_handle_t*>(timer));
|
||||
delete timer;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
44
atom/app/uv_task_runner.h
Normal file
44
atom/app/uv_task_runner.h
Normal file
@@ -0,0 +1,44 @@
|
||||
// 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_UV_TASK_RUNNER_H_
|
||||
#define ATOM_APP_UV_TASK_RUNNER_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/single_thread_task_runner.h"
|
||||
#include "vendor/node/deps/uv/include/uv.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
// TaskRunner implementation that posts tasks into libuv's default loop.
|
||||
class UvTaskRunner : public base::SingleThreadTaskRunner {
|
||||
public:
|
||||
explicit UvTaskRunner(uv_loop_t* loop);
|
||||
~UvTaskRunner() override;
|
||||
|
||||
// base::SingleThreadTaskRunner:
|
||||
bool PostDelayedTask(const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) override;
|
||||
bool RunsTasksOnCurrentThread() const override;
|
||||
bool PostNonNestableDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) override;
|
||||
|
||||
private:
|
||||
static void OnTimeout(uv_timer_t* timer);
|
||||
|
||||
uv_loop_t* loop_;
|
||||
|
||||
std::map<uv_timer_t*, base::Closure> tasks_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(UvTaskRunner);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_APP_UV_TASK_RUNNER_H_
|
||||
354
atom/browser/api/atom_api_app.cc
Normal file
354
atom/browser/api/atom_api_app.cc
Normal file
@@ -0,0 +1,354 @@
|
||||
// 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>
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/api/atom_api_session.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/path_service.h"
|
||||
#include "brightray/browser/brightray_paths.h"
|
||||
#include "content/public/browser/client_certificate_delegate.h"
|
||||
#include "content/public/browser/gpu_data_manager.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#endif
|
||||
|
||||
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
|
||||
|
||||
template<>
|
||||
struct Converter<scoped_refptr<net::X509Certificate>> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const scoped_refptr<net::X509Certificate>& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
std::string encoded_data;
|
||||
net::X509Certificate::GetPEMEncoded(
|
||||
val->os_cert_handle(), &encoded_data);
|
||||
dict.Set("data", encoded_data);
|
||||
dict.Set("issuerName", val->issuer().GetDisplayName());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void OnClientCertificateSelected(
|
||||
v8::Isolate* isolate,
|
||||
std::shared_ptr<content::ClientCertificateDelegate> delegate,
|
||||
mate::Arguments* args) {
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
mate::Dictionary cert_data;
|
||||
if (!(args->Length() == 1 && args->GetNext(&cert_data))) {
|
||||
args->ThrowError();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string encoded_data;
|
||||
cert_data.Get("data", &encoded_data);
|
||||
|
||||
auto certs =
|
||||
net::X509Certificate::CreateCertificateListFromBytes(
|
||||
encoded_data.data(), encoded_data.size(),
|
||||
net::X509Certificate::FORMAT_AUTO);
|
||||
|
||||
delegate->ContinueWithCertificate(certs[0].get());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
App::App() {
|
||||
Browser::Get()->AddObserver(this);
|
||||
content::GpuDataManager::GetInstance()->AddObserver(this);
|
||||
}
|
||||
|
||||
App::~App() {
|
||||
Browser::Get()->RemoveObserver(this);
|
||||
content::GpuDataManager::GetInstance()->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void App::OnBeforeQuit(bool* prevent_default) {
|
||||
*prevent_default = Emit("before-quit");
|
||||
}
|
||||
|
||||
void App::OnWillQuit(bool* prevent_default) {
|
||||
*prevent_default = Emit("will-quit");
|
||||
}
|
||||
|
||||
void App::OnWindowAllClosed() {
|
||||
Emit("window-all-closed");
|
||||
}
|
||||
|
||||
void App::OnQuit() {
|
||||
Emit("quit");
|
||||
}
|
||||
|
||||
void App::OnOpenFile(bool* prevent_default, const std::string& file_path) {
|
||||
*prevent_default = Emit("open-file", file_path);
|
||||
}
|
||||
|
||||
void App::OnOpenURL(const std::string& url) {
|
||||
Emit("open-url", url);
|
||||
}
|
||||
|
||||
void App::OnActivate(bool has_visible_windows) {
|
||||
Emit("activate", has_visible_windows);
|
||||
}
|
||||
|
||||
void App::OnWillFinishLaunching() {
|
||||
Emit("will-finish-launching");
|
||||
}
|
||||
|
||||
void App::OnFinishLaunching() {
|
||||
// Create the defaultSession.
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto browser_context = static_cast<AtomBrowserContext*>(
|
||||
AtomBrowserMainParts::Get()->browser_context());
|
||||
auto handle = Session::CreateFrom(isolate(), browser_context);
|
||||
default_session_.Reset(isolate(), handle.ToV8());
|
||||
|
||||
Emit("ready");
|
||||
}
|
||||
|
||||
void App::OnSelectCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
scoped_ptr<content::ClientCertificateDelegate> delegate) {
|
||||
std::shared_ptr<content::ClientCertificateDelegate>
|
||||
shared_delegate(delegate.release());
|
||||
bool prevent_default =
|
||||
Emit("select-certificate",
|
||||
api::WebContents::CreateFrom(isolate(), web_contents),
|
||||
cert_request_info->host_and_port.ToString(),
|
||||
cert_request_info->client_certs,
|
||||
base::Bind(&OnClientCertificateSelected,
|
||||
isolate(),
|
||||
shared_delegate));
|
||||
|
||||
// Default to first certificate from the platform store.
|
||||
if (!prevent_default)
|
||||
shared_delegate->ContinueWithCertificate(
|
||||
cert_request_info->client_certs[0].get());
|
||||
}
|
||||
|
||||
void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) {
|
||||
Emit("gpu-process-crashed");
|
||||
}
|
||||
|
||||
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::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
|
||||
}
|
||||
|
||||
std::string App::GetLocale() {
|
||||
return l10n_util::GetApplicationLocale("");
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> App::DefaultSession(v8::Isolate* isolate) {
|
||||
if (default_session_.IsEmpty())
|
||||
return v8::Null(isolate);
|
||||
else
|
||||
return v8::Local<v8::Value>::New(isolate, default_session_);
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
auto browser = base::Unretained(Browser::Get());
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.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("setDesktopName", &App::SetDesktopName)
|
||||
.SetMethod("setAppUserModelId", &App::SetAppUserModelId)
|
||||
.SetMethod("getLocale", &App::GetLocale)
|
||||
.SetProperty("defaultSession", &App::DefaultSession);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<App> App::Create(v8::Isolate* isolate) {
|
||||
return CreateHandle(isolate, new App);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
void AppendSwitch(const std::string& switch_string, mate::Arguments* args) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
std::string value;
|
||||
if (args->GetNext(&value))
|
||||
command_line->AppendSwitchASCII(switch_string, value);
|
||||
else
|
||||
command_line->AppendSwitch(switch_string);
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
int DockBounce(const std::string& type) {
|
||||
int request_id = -1;
|
||||
if (type == "critical")
|
||||
request_id = Browser::Get()->DockBounce(Browser::BOUNCE_CRITICAL);
|
||||
else if (type == "informational")
|
||||
request_id = Browser::Get()->DockBounce(Browser::BOUNCE_INFORMATIONAL);
|
||||
return request_id;
|
||||
}
|
||||
|
||||
void DockSetMenu(atom::api::Menu* menu) {
|
||||
Browser::Get()->DockSetMenu(menu->model());
|
||||
}
|
||||
#endif
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("app", atom::api::App::Create(isolate));
|
||||
dict.SetMethod("appendSwitch", &AppendSwitch);
|
||||
dict.SetMethod("appendArgument",
|
||||
base::Bind(&base::CommandLine::AppendArg,
|
||||
base::Unretained(command_line)));
|
||||
#if defined(OS_MACOSX)
|
||||
auto browser = base::Unretained(Browser::Get());
|
||||
dict.SetMethod("dockBounce", &DockBounce);
|
||||
dict.SetMethod("dockCancelBounce",
|
||||
base::Bind(&Browser::DockCancelBounce, browser));
|
||||
dict.SetMethod("dockSetBadgeText",
|
||||
base::Bind(&Browser::DockSetBadgeText, browser));
|
||||
dict.SetMethod("dockGetBadgeText",
|
||||
base::Bind(&Browser::DockGetBadgeText, browser));
|
||||
dict.SetMethod("dockHide", base::Bind(&Browser::DockHide, browser));
|
||||
dict.SetMethod("dockShow", base::Bind(&Browser::DockShow, browser));
|
||||
dict.SetMethod("dockSetMenu", &DockSetMenu);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_app, Initialize)
|
||||
80
atom/browser/api/atom_api_app.h
Normal file
80
atom/browser/api/atom_api_app.h
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/browser_observer.h"
|
||||
#include "content/public/browser/gpu_data_manager_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class App : public mate::EventEmitter,
|
||||
public BrowserObserver,
|
||||
public content::GpuDataManagerObserver {
|
||||
public:
|
||||
static mate::Handle<App> Create(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
App();
|
||||
virtual ~App();
|
||||
|
||||
// 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 OnActivate(bool has_visible_windows) override;
|
||||
void OnWillFinishLaunching() override;
|
||||
void OnFinishLaunching() override;
|
||||
void OnSelectCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
|
||||
|
||||
// content::GpuDataManagerObserver:
|
||||
void OnGpuProcessCrashed(base::TerminationStatus exit_code) override;
|
||||
|
||||
// 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 SetDesktopName(const std::string& desktop_name);
|
||||
void SetAppUserModelId(const std::string& app_id);
|
||||
std::string GetLocale();
|
||||
v8::Local<v8::Value> DefaultSession(v8::Isolate* isolate);
|
||||
|
||||
v8::Global<v8::Value> default_session_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(App);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
88
atom/browser/api/atom_api_auto_updater.cc
Normal file
88
atom/browser/api/atom_api_auto_updater.cc
Normal file
@@ -0,0 +1,88 @@
|
||||
// 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 "atom/browser/auto_updater.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
AutoUpdater::AutoUpdater() {
|
||||
auto_updater::AutoUpdater::SetDelegate(this);
|
||||
}
|
||||
|
||||
AutoUpdater::~AutoUpdater() {
|
||||
auto_updater::AutoUpdater::SetDelegate(NULL);
|
||||
}
|
||||
|
||||
void AutoUpdater::OnError(const std::string& error) {
|
||||
Emit("error", error);
|
||||
}
|
||||
|
||||
void AutoUpdater::OnCheckingForUpdate() {
|
||||
Emit("checking-for-update");
|
||||
}
|
||||
|
||||
void AutoUpdater::OnUpdateAvailable() {
|
||||
Emit("update-available");
|
||||
}
|
||||
|
||||
void AutoUpdater::OnUpdateNotAvailable() {
|
||||
Emit("update-not-available");
|
||||
}
|
||||
|
||||
void AutoUpdater::OnUpdateDownloaded(const std::string& release_notes,
|
||||
const std::string& release_name,
|
||||
const base::Time& release_date,
|
||||
const std::string& update_url,
|
||||
const base::Closure& quit_and_install) {
|
||||
quit_and_install_ = quit_and_install;
|
||||
Emit("update-downloaded-raw", release_notes, release_name,
|
||||
release_date.ToJsTime(), update_url);
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder AutoUpdater::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("setFeedUrl", &auto_updater::AutoUpdater::SetFeedURL)
|
||||
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
|
||||
.SetMethod("_quitAndInstall", &AutoUpdater::QuitAndInstall);
|
||||
}
|
||||
|
||||
void AutoUpdater::QuitAndInstall() {
|
||||
if (quit_and_install_.is_null())
|
||||
Browser::Get()->Shutdown();
|
||||
else
|
||||
quit_and_install_.Run();
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<AutoUpdater> AutoUpdater::Create(v8::Isolate* isolate) {
|
||||
return CreateHandle(isolate, new AutoUpdater);
|
||||
}
|
||||
|
||||
} // 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("autoUpdater", atom::api::AutoUpdater::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_auto_updater, Initialize)
|
||||
56
atom/browser/api/atom_api_auto_updater.h
Normal file
56
atom/browser/api/atom_api_auto_updater.h
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/auto_updater_delegate.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class AutoUpdater : public mate::EventEmitter,
|
||||
public auto_updater::AutoUpdaterDelegate {
|
||||
public:
|
||||
static mate::Handle<AutoUpdater> Create(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
AutoUpdater();
|
||||
virtual ~AutoUpdater();
|
||||
|
||||
// AutoUpdaterDelegate implementations.
|
||||
void OnError(const std::string& error) override;
|
||||
void OnCheckingForUpdate() override;
|
||||
void OnUpdateAvailable() override;
|
||||
void OnUpdateNotAvailable() override;
|
||||
void OnUpdateDownloaded(
|
||||
const std::string& release_notes,
|
||||
const std::string& release_name,
|
||||
const base::Time& release_date,
|
||||
const std::string& update_url,
|
||||
const base::Closure& quit_and_install) override;
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
void QuitAndInstall();
|
||||
|
||||
base::Closure quit_and_install_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AutoUpdater);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
|
||||
90
atom/browser/api/atom_api_content_tracing.cc
Normal file
90
atom/browser/api/atom_api_content_tracing.cc
Normal file
@@ -0,0 +1,90 @@
|
||||
// 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/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "content/public/browser/tracing_controller.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
using content::TracingController;
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<base::trace_event::TraceConfig> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::trace_event::TraceConfig* out) {
|
||||
Dictionary options;
|
||||
if (!ConvertFromV8(isolate, val, &options))
|
||||
return false;
|
||||
std::string category_filter, trace_options;
|
||||
if (!options.Get("categoryFilter", &category_filter) ||
|
||||
!options.Get("traceOptions", &trace_options))
|
||||
return false;
|
||||
*out = base::trace_event::TraceConfig(category_filter, trace_options);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace {
|
||||
|
||||
using CompletionCallback = base::Callback<void(const base::FilePath&)>;
|
||||
|
||||
scoped_refptr<TracingController::TraceDataSink> GetTraceDataSink(
|
||||
const base::FilePath& path, const CompletionCallback& callback) {
|
||||
base::FilePath result_file_path = path;
|
||||
if (result_file_path.empty() && !base::CreateTemporaryFile(&result_file_path))
|
||||
LOG(ERROR) << "Creating temporary file failed";
|
||||
|
||||
return TracingController::CreateFileSink(result_file_path,
|
||||
base::Bind(callback,
|
||||
result_file_path));
|
||||
}
|
||||
|
||||
void StopRecording(const base::FilePath& path,
|
||||
const CompletionCallback& callback) {
|
||||
TracingController::GetInstance()->DisableRecording(
|
||||
GetTraceDataSink(path, callback));
|
||||
}
|
||||
|
||||
void CaptureMonitoringSnapshot(const base::FilePath& path,
|
||||
const CompletionCallback& callback) {
|
||||
TracingController::GetInstance()->CaptureMonitoringSnapshot(
|
||||
GetTraceDataSink(path, callback));
|
||||
}
|
||||
|
||||
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", &StopRecording);
|
||||
dict.SetMethod("startMonitoring", base::Bind(
|
||||
&TracingController::EnableMonitoring, controller));
|
||||
dict.SetMethod("stopMonitoring", base::Bind(
|
||||
&TracingController::DisableMonitoring, controller));
|
||||
dict.SetMethod("captureMonitoringSnapshot", &CaptureMonitoringSnapshot);
|
||||
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)
|
||||
346
atom/browser/api/atom_api_cookies.cc
Normal file
346
atom/browser/api/atom_api_cookies.cc
Normal file
@@ -0,0 +1,346 @@
|
||||
// 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_cookies.h"
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/cookies/cookie_monster.h"
|
||||
#include "net/cookies/cookie_store.h"
|
||||
#include "net/cookies/cookie_util.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
using atom::api::Cookies;
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace {
|
||||
|
||||
bool GetCookieListFromStore(
|
||||
net::CookieStore* cookie_store,
|
||||
const std::string& url,
|
||||
const net::CookieMonster::GetCookieListCallback& callback) {
|
||||
DCHECK(cookie_store);
|
||||
GURL gurl(url);
|
||||
net::CookieMonster* monster = cookie_store->GetCookieMonster();
|
||||
// Empty url will match all url cookies.
|
||||
if (url.empty()) {
|
||||
monster->GetAllCookiesAsync(callback);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!gurl.is_valid())
|
||||
return false;
|
||||
|
||||
monster->GetAllCookiesForURLAsync(gurl, callback);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RunGetCookiesCallbackOnUIThread(v8::Isolate* isolate,
|
||||
const std::string& error_message,
|
||||
const net::CookieList& cookie_list,
|
||||
const Cookies::CookiesCallback& callback) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
if (!error_message.empty()) {
|
||||
v8::Local<v8::Value> error = mate::ConvertToV8(isolate, error_message);
|
||||
callback.Run(error, v8::Null(isolate));
|
||||
return;
|
||||
}
|
||||
callback.Run(v8::Null(isolate), mate::ConvertToV8(isolate, cookie_list));
|
||||
}
|
||||
|
||||
void RunRemoveCookiesCallbackOnUIThread(
|
||||
v8::Isolate* isolate,
|
||||
const std::string& error_message,
|
||||
const Cookies::CookiesCallback& callback) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
if (!error_message.empty()) {
|
||||
v8::Local<v8::Value> error = mate::ConvertToV8(isolate, error_message);
|
||||
callback.Run(error, v8::Null(isolate));
|
||||
return;
|
||||
}
|
||||
|
||||
callback.Run(v8::Null(isolate), v8::Null(isolate));
|
||||
}
|
||||
|
||||
void RunSetCookiesCallbackOnUIThread(v8::Isolate* isolate,
|
||||
const std::string& error_message,
|
||||
bool set_success,
|
||||
const Cookies::CookiesCallback& callback) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
if (!error_message.empty()) {
|
||||
v8::Local<v8::Value> error = mate::ConvertToV8(isolate, error_message);
|
||||
callback.Run(error, v8::Null(isolate));
|
||||
return;
|
||||
}
|
||||
if (!set_success) {
|
||||
v8::Local<v8::Value> error = mate::ConvertToV8(
|
||||
isolate, "Failed to set cookies");
|
||||
callback.Run(error, v8::Null(isolate));
|
||||
}
|
||||
|
||||
callback.Run(v8::Null(isolate), v8::Null(isolate));
|
||||
}
|
||||
|
||||
bool MatchesDomain(const base::DictionaryValue* filter,
|
||||
const std::string& cookie_domain) {
|
||||
std::string filter_domain;
|
||||
if (!filter->GetString("domain", &filter_domain))
|
||||
return true;
|
||||
|
||||
// Add a leading '.' character to the filter domain if it doesn't exist.
|
||||
if (net::cookie_util::DomainIsHostOnly(filter_domain))
|
||||
filter_domain.insert(0, ".");
|
||||
|
||||
std::string sub_domain(cookie_domain);
|
||||
// Strip any leading '.' character from the input cookie domain.
|
||||
if (!net::cookie_util::DomainIsHostOnly(sub_domain))
|
||||
sub_domain = sub_domain.substr(1);
|
||||
|
||||
// Now check whether the domain argument is a subdomain of the filter domain.
|
||||
for (sub_domain.insert(0, ".");
|
||||
sub_domain.length() >= filter_domain.length();) {
|
||||
if (sub_domain == filter_domain) {
|
||||
return true;
|
||||
}
|
||||
const size_t next_dot = sub_domain.find('.', 1); // Skip over leading dot.
|
||||
sub_domain.erase(0, next_dot);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MatchesCookie(const base::DictionaryValue* filter,
|
||||
const net::CanonicalCookie& cookie) {
|
||||
std::string name, domain, path;
|
||||
bool is_secure, session;
|
||||
if (filter->GetString("name", &name) && name != cookie.Name())
|
||||
return false;
|
||||
if (filter->GetString("path", &path) && path != cookie.Path())
|
||||
return false;
|
||||
if (!MatchesDomain(filter, cookie.Domain()))
|
||||
return false;
|
||||
if (filter->GetBoolean("secure", &is_secure) &&
|
||||
is_secure != cookie.IsSecure())
|
||||
return false;
|
||||
if (filter->GetBoolean("session", &session) &&
|
||||
session != cookie.IsPersistent())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<net::CanonicalCookie> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const net::CanonicalCookie& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("name", val.Name());
|
||||
dict.Set("value", val.Value());
|
||||
dict.Set("domain", val.Domain());
|
||||
dict.Set("host_only", net::cookie_util::DomainIsHostOnly(val.Domain()));
|
||||
dict.Set("path", val.Path());
|
||||
dict.Set("secure", val.IsSecure());
|
||||
dict.Set("http_only", val.IsHttpOnly());
|
||||
dict.Set("session", val.IsPersistent());
|
||||
if (!val.IsPersistent())
|
||||
dict.Set("expirationDate", val.ExpiryDate().ToDoubleT());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
Cookies::Cookies(content::BrowserContext* browser_context)
|
||||
: request_context_getter_(browser_context->GetRequestContext()) {
|
||||
}
|
||||
|
||||
Cookies::~Cookies() {
|
||||
}
|
||||
|
||||
void Cookies::Get(const base::DictionaryValue& options,
|
||||
const CookiesCallback& callback) {
|
||||
scoped_ptr<base::DictionaryValue> filter(
|
||||
options.DeepCopyWithoutEmptyChildren());
|
||||
|
||||
content::BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Cookies::GetCookiesOnIOThread, base::Unretained(this),
|
||||
Passed(&filter), callback));
|
||||
}
|
||||
|
||||
void Cookies::GetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> filter,
|
||||
const CookiesCallback& callback) {
|
||||
std::string url;
|
||||
filter->GetString("url", &url);
|
||||
if (!GetCookieListFromStore(GetCookieStore(), url,
|
||||
base::Bind(&Cookies::OnGetCookies, base::Unretained(this),
|
||||
Passed(&filter), callback))) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&RunGetCookiesCallbackOnUIThread, isolate(),
|
||||
"Url is not valid", net::CookieList(), callback));
|
||||
}
|
||||
}
|
||||
|
||||
void Cookies::OnGetCookies(scoped_ptr<base::DictionaryValue> filter,
|
||||
const CookiesCallback& callback,
|
||||
const net::CookieList& cookie_list) {
|
||||
net::CookieList result;
|
||||
for (const auto& cookie : cookie_list) {
|
||||
if (MatchesCookie(filter.get(), cookie))
|
||||
result.push_back(cookie);
|
||||
}
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
|
||||
&RunGetCookiesCallbackOnUIThread, isolate(), "", result, callback));
|
||||
}
|
||||
|
||||
void Cookies::Remove(const mate::Dictionary& details,
|
||||
const CookiesCallback& callback) {
|
||||
GURL url;
|
||||
std::string name;
|
||||
std::string error_message;
|
||||
if (!details.Get("url", &url) || !details.Get("name", &name)) {
|
||||
error_message = "Details(url, name) of removing cookie are required.";
|
||||
}
|
||||
if (error_message.empty() && !url.is_valid()) {
|
||||
error_message = "Url is not valid.";
|
||||
}
|
||||
if (!error_message.empty()) {
|
||||
RunRemoveCookiesCallbackOnUIThread(isolate(), error_message, callback);
|
||||
return;
|
||||
}
|
||||
content::BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Cookies::RemoveCookiesOnIOThread, base::Unretained(this),
|
||||
url, name, callback));
|
||||
}
|
||||
|
||||
void Cookies::RemoveCookiesOnIOThread(const GURL& url, const std::string& name,
|
||||
const CookiesCallback& callback) {
|
||||
GetCookieStore()->DeleteCookieAsync(url, name,
|
||||
base::Bind(&Cookies::OnRemoveCookies, base::Unretained(this), callback));
|
||||
}
|
||||
|
||||
void Cookies::OnRemoveCookies(const CookiesCallback& callback) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&RunRemoveCookiesCallbackOnUIThread, isolate(), "", callback));
|
||||
}
|
||||
|
||||
void Cookies::Set(const base::DictionaryValue& options,
|
||||
const CookiesCallback& callback) {
|
||||
std::string url;
|
||||
std::string error_message;
|
||||
if (!options.GetString("url", &url)) {
|
||||
error_message = "The url field is required.";
|
||||
}
|
||||
|
||||
GURL gurl(url);
|
||||
if (error_message.empty() && !gurl.is_valid()) {
|
||||
error_message = "Url is not valid.";
|
||||
}
|
||||
|
||||
if (!error_message.empty()) {
|
||||
RunSetCookiesCallbackOnUIThread(isolate(), error_message, false, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
scoped_ptr<base::DictionaryValue> details(
|
||||
options.DeepCopyWithoutEmptyChildren());
|
||||
|
||||
content::BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Cookies::SetCookiesOnIOThread, base::Unretained(this),
|
||||
Passed(&details), gurl, callback));
|
||||
}
|
||||
|
||||
void Cookies::SetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> details,
|
||||
const GURL& url,
|
||||
const CookiesCallback& callback) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
std::string name, value, domain, path;
|
||||
bool secure = false;
|
||||
bool http_only = false;
|
||||
double expiration_date;
|
||||
|
||||
details->GetString("name", &name);
|
||||
details->GetString("value", &value);
|
||||
details->GetString("domain", &domain);
|
||||
details->GetString("path", &path);
|
||||
details->GetBoolean("secure", &secure);
|
||||
details->GetBoolean("http_only", &http_only);
|
||||
|
||||
base::Time expiration_time;
|
||||
if (details->GetDouble("expirationDate", &expiration_date)) {
|
||||
expiration_time = (expiration_date == 0) ?
|
||||
base::Time::UnixEpoch() :
|
||||
base::Time::FromDoubleT(expiration_date);
|
||||
}
|
||||
|
||||
GetCookieStore()->GetCookieMonster()->SetCookieWithDetailsAsync(
|
||||
url,
|
||||
name,
|
||||
value,
|
||||
domain,
|
||||
path,
|
||||
expiration_time,
|
||||
secure,
|
||||
http_only,
|
||||
false,
|
||||
net::COOKIE_PRIORITY_DEFAULT,
|
||||
base::Bind(&Cookies::OnSetCookies, base::Unretained(this), callback));
|
||||
}
|
||||
|
||||
void Cookies::OnSetCookies(const CookiesCallback& callback,
|
||||
bool set_success) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&RunSetCookiesCallbackOnUIThread, isolate(), "", set_success,
|
||||
callback));
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder Cookies::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("get", &Cookies::Get)
|
||||
.SetMethod("remove", &Cookies::Remove)
|
||||
.SetMethod("set", &Cookies::Set);
|
||||
}
|
||||
|
||||
net::CookieStore* Cookies::GetCookieStore() {
|
||||
return request_context_getter_->GetURLRequestContext()->cookie_store();
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<Cookies> Cookies::Create(
|
||||
v8::Isolate* isolate,
|
||||
content::BrowserContext* browser_context) {
|
||||
return mate::CreateHandle(isolate, new Cookies(browser_context));
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
90
atom/browser/api/atom_api_cookies.h
Normal file
90
atom/browser/api/atom_api_cookies.h
Normal file
@@ -0,0 +1,90 @@
|
||||
// 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_COOKIES_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_COOKIES_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/cookies/canonical_cookie.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class CookieStore;
|
||||
class URLRequestContextGetter;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Cookies : public mate::Wrappable {
|
||||
public:
|
||||
// node.js style callback function(error, result)
|
||||
typedef base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>
|
||||
CookiesCallback;
|
||||
|
||||
static mate::Handle<Cookies> Create(v8::Isolate* isolate,
|
||||
content::BrowserContext* browser_context);
|
||||
|
||||
protected:
|
||||
explicit Cookies(content::BrowserContext* browser_context);
|
||||
~Cookies();
|
||||
|
||||
void Get(const base::DictionaryValue& options,
|
||||
const CookiesCallback& callback);
|
||||
void Remove(const mate::Dictionary& details,
|
||||
const CookiesCallback& callback);
|
||||
void Set(const base::DictionaryValue& details,
|
||||
const CookiesCallback& callback);
|
||||
|
||||
void GetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> filter,
|
||||
const CookiesCallback& callback);
|
||||
void OnGetCookies(scoped_ptr<base::DictionaryValue> filter,
|
||||
const CookiesCallback& callback,
|
||||
const net::CookieList& cookie_list);
|
||||
|
||||
void RemoveCookiesOnIOThread(const GURL& url,
|
||||
const std::string& name,
|
||||
const CookiesCallback& callback);
|
||||
void OnRemoveCookies(const CookiesCallback& callback);
|
||||
|
||||
void SetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> details,
|
||||
const GURL& url,
|
||||
const CookiesCallback& callback);
|
||||
void OnSetCookies(const CookiesCallback& callback,
|
||||
bool set_success);
|
||||
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
// Must be called on IO thread.
|
||||
net::CookieStore* GetCookieStore();
|
||||
|
||||
net::URLRequestContextGetter* request_context_getter_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Cookies);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_COOKIES_H_
|
||||
118
atom/browser/api/atom_api_dialog.cc
Normal file
118
atom/browser/api/atom_api_dialog.cc
Normal file
@@ -0,0 +1,118 @@
|
||||
// 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 "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/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<file_dialog::Filter> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
file_dialog::Filter* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
if (!dict.Get("name", &(out->first)))
|
||||
return false;
|
||||
if (!dict.Get("extensions", &(out->second)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace {
|
||||
|
||||
void ShowMessageBox(int type,
|
||||
const std::vector<std::string>& buttons,
|
||||
int cancel_id,
|
||||
int options,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const gfx::ImageSkia& icon,
|
||||
atom::NativeWindow* window,
|
||||
mate::Arguments* args) {
|
||||
v8::Local<v8::Value> peek = args->PeekNext();
|
||||
atom::MessageBoxCallback callback;
|
||||
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(),
|
||||
peek,
|
||||
&callback)) {
|
||||
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons, cancel_id,
|
||||
options, title, message, detail, icon, callback);
|
||||
} else {
|
||||
int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type,
|
||||
buttons, cancel_id, options, 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::Local<v8::Value> peek = args->PeekNext();
|
||||
file_dialog::OpenDialogCallback callback;
|
||||
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(args->isolate(),
|
||||
peek,
|
||||
&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, 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::Local<v8::Value> peek = args->PeekNext();
|
||||
file_dialog::SaveDialogCallback callback;
|
||||
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(args->isolate(),
|
||||
peek,
|
||||
&callback)) {
|
||||
file_dialog::ShowSaveDialog(window, title, default_path, filters, callback);
|
||||
} else {
|
||||
base::FilePath path;
|
||||
if (file_dialog::ShowSaveDialog(window, title, default_path, filters,
|
||||
&path))
|
||||
args->Return(path);
|
||||
}
|
||||
}
|
||||
|
||||
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_CONTEXT_AWARE_BUILTIN(atom_browser_dialog, Initialize)
|
||||
201
atom/browser/api/atom_api_download_item.cc
Normal file
201
atom/browser/api/atom_api_download_item.cc
Normal file
@@ -0,0 +1,201 @@
|
||||
// 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_download_item.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/memory/linked_ptr.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/filename_util.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<content::DownloadItem::DownloadState> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
content::DownloadItem::DownloadState state) {
|
||||
std::string download_state;
|
||||
switch (state) {
|
||||
case content::DownloadItem::COMPLETE:
|
||||
download_state = "completed";
|
||||
break;
|
||||
case content::DownloadItem::CANCELLED:
|
||||
download_state = "cancelled";
|
||||
break;
|
||||
case content::DownloadItem::INTERRUPTED:
|
||||
download_state = "interrupted";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ConvertToV8(isolate, download_state);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
// The wrapDownloadItem funtion which is implemented in JavaScript
|
||||
using WrapDownloadItemCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
WrapDownloadItemCallback g_wrap_download_item;
|
||||
|
||||
char kDownloadItemSavePathKey[] = "DownloadItemSavePathKey";
|
||||
|
||||
std::map<uint32, linked_ptr<v8::Global<v8::Value>>> g_download_item_objects;
|
||||
} // namespace
|
||||
|
||||
DownloadItem::SavePathData::SavePathData(const base::FilePath& path) :
|
||||
path_(path) {
|
||||
}
|
||||
|
||||
const base::FilePath& DownloadItem::SavePathData::path() {
|
||||
return path_;
|
||||
}
|
||||
|
||||
DownloadItem::DownloadItem(content::DownloadItem* download_item) :
|
||||
download_item_(download_item) {
|
||||
download_item_->AddObserver(this);
|
||||
}
|
||||
|
||||
DownloadItem::~DownloadItem() {
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void DownloadItem::Destroy() {
|
||||
if (download_item_) {
|
||||
download_item_->RemoveObserver(this);
|
||||
auto iter = g_download_item_objects.find(download_item_->GetId());
|
||||
if (iter != g_download_item_objects.end())
|
||||
g_download_item_objects.erase(iter);
|
||||
download_item_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool DownloadItem::IsDestroyed() const {
|
||||
return download_item_ == nullptr;
|
||||
}
|
||||
|
||||
void DownloadItem::OnDownloadUpdated(content::DownloadItem* item) {
|
||||
download_item_->IsDone() ? Emit("done", item->GetState()) : Emit("updated");
|
||||
}
|
||||
|
||||
void DownloadItem::OnDownloadDestroyed(content::DownloadItem* download) {
|
||||
Destroy();
|
||||
}
|
||||
|
||||
int64 DownloadItem::GetReceivedBytes() {
|
||||
return download_item_->GetReceivedBytes();
|
||||
}
|
||||
|
||||
int64 DownloadItem::GetTotalBytes() {
|
||||
return download_item_->GetTotalBytes();
|
||||
}
|
||||
|
||||
const GURL& DownloadItem::GetUrl() {
|
||||
return download_item_->GetURL();
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetMimeType() {
|
||||
return download_item_->GetMimeType();
|
||||
}
|
||||
|
||||
bool DownloadItem::HasUserGesture() {
|
||||
return download_item_->HasUserGesture();
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetFilename() {
|
||||
return base::UTF16ToUTF8(net::GenerateFileName(GetUrl(),
|
||||
GetContentDisposition(),
|
||||
std::string(),
|
||||
download_item_->GetSuggestedFilename(),
|
||||
GetMimeType(),
|
||||
std::string()).LossyDisplayName());
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetContentDisposition() {
|
||||
return download_item_->GetContentDisposition();
|
||||
}
|
||||
|
||||
void DownloadItem::SetSavePath(const base::FilePath& path) {
|
||||
download_item_->SetUserData(UserDataKey(), new SavePathData(path));
|
||||
}
|
||||
|
||||
void DownloadItem::Pause() {
|
||||
download_item_->Pause();
|
||||
}
|
||||
|
||||
void DownloadItem::Resume() {
|
||||
download_item_->Resume();
|
||||
}
|
||||
|
||||
void DownloadItem::Cancel() {
|
||||
download_item_->Cancel(true);
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder DownloadItem::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("pause", &DownloadItem::Pause)
|
||||
.SetMethod("resume", &DownloadItem::Resume)
|
||||
.SetMethod("cancel", &DownloadItem::Cancel)
|
||||
.SetMethod("getReceivedBytes", &DownloadItem::GetReceivedBytes)
|
||||
.SetMethod("getTotalBytes", &DownloadItem::GetTotalBytes)
|
||||
.SetMethod("getUrl", &DownloadItem::GetUrl)
|
||||
.SetMethod("getMimeType", &DownloadItem::GetMimeType)
|
||||
.SetMethod("hasUserGesture", &DownloadItem::HasUserGesture)
|
||||
.SetMethod("getFilename", &DownloadItem::GetFilename)
|
||||
.SetMethod("getContentDisposition", &DownloadItem::GetContentDisposition)
|
||||
.SetMethod("setSavePath", &DownloadItem::SetSavePath);
|
||||
}
|
||||
|
||||
void SetWrapDownloadItem(const WrapDownloadItemCallback& callback) {
|
||||
g_wrap_download_item = callback;
|
||||
}
|
||||
|
||||
void ClearWrapDownloadItem() {
|
||||
g_wrap_download_item.Reset();
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<DownloadItem> DownloadItem::Create(
|
||||
v8::Isolate* isolate, content::DownloadItem* item) {
|
||||
auto handle = mate::CreateHandle(isolate, new DownloadItem(item));
|
||||
g_wrap_download_item.Run(handle.ToV8());
|
||||
g_download_item_objects[item->GetId()] = make_linked_ptr(
|
||||
new v8::Global<v8::Value>(isolate, handle.ToV8()));
|
||||
return handle;
|
||||
}
|
||||
|
||||
// static
|
||||
void* DownloadItem::UserDataKey() {
|
||||
return &kDownloadItemSavePathKey;
|
||||
}
|
||||
|
||||
} // 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("_setWrapDownloadItem", &atom::api::SetWrapDownloadItem);
|
||||
dict.SetMethod("_clearWrapDownloadItem", &atom::api::ClearWrapDownloadItem);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_download_item, Initialize);
|
||||
72
atom/browser/api/atom_api_download_item.h
Normal file
72
atom/browser/api/atom_api_download_item.h
Normal file
@@ -0,0 +1,72 @@
|
||||
// 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_DOWNLOAD_ITEM_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "content/public/browser/download_item.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class DownloadItem : public mate::EventEmitter,
|
||||
public content::DownloadItem::Observer {
|
||||
public:
|
||||
class SavePathData : public base::SupportsUserData::Data {
|
||||
public:
|
||||
explicit SavePathData(const base::FilePath& path);
|
||||
const base::FilePath& path();
|
||||
private:
|
||||
base::FilePath path_;
|
||||
};
|
||||
|
||||
static mate::Handle<DownloadItem> Create(v8::Isolate* isolate,
|
||||
content::DownloadItem* item);
|
||||
static void* UserDataKey();
|
||||
|
||||
protected:
|
||||
explicit DownloadItem(content::DownloadItem* download_item);
|
||||
~DownloadItem();
|
||||
|
||||
// Override content::DownloadItem::Observer methods
|
||||
void OnDownloadUpdated(content::DownloadItem* download) override;
|
||||
void OnDownloadDestroyed(content::DownloadItem* download) override;
|
||||
|
||||
void Pause();
|
||||
void Resume();
|
||||
void Cancel();
|
||||
int64 GetReceivedBytes();
|
||||
int64 GetTotalBytes();
|
||||
std::string GetMimeType();
|
||||
bool HasUserGesture();
|
||||
std::string GetFilename();
|
||||
std::string GetContentDisposition();
|
||||
const GURL& GetUrl();
|
||||
void SetSavePath(const base::FilePath& path);
|
||||
|
||||
private:
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
bool IsDestroyed() const override;
|
||||
|
||||
void Destroy();
|
||||
|
||||
content::DownloadItem* download_item_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DownloadItem);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_
|
||||
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 "atom/common/native_mate_converters/callback.h"
|
||||
#include "base/stl_util.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_
|
||||
199
atom/browser/api/atom_api_menu.cc
Normal file
199
atom/browser/api/atom_api_menu.cc
Normal file
@@ -0,0 +1,199 @@
|
||||
// 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/native_window.h"
|
||||
#include "atom/common/native_mate_converters/accelerator_converter.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
Menu::Menu()
|
||||
: model_(new AtomMenuModel(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 {
|
||||
return is_checked_.Run(command_id);
|
||||
}
|
||||
|
||||
bool Menu::IsCommandIdEnabled(int command_id) const {
|
||||
return is_enabled_.Run(command_id);
|
||||
}
|
||||
|
||||
bool Menu::IsCommandIdVisible(int command_id) const {
|
||||
return is_visible_.Run(command_id);
|
||||
}
|
||||
|
||||
bool Menu::GetAcceleratorForCommandId(int command_id,
|
||||
ui::Accelerator* accelerator) {
|
||||
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) {
|
||||
execute_command_.Run(command_id);
|
||||
}
|
||||
|
||||
void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
|
||||
menu_will_show_.Run();
|
||||
}
|
||||
|
||||
void Menu::InsertItemAt(
|
||||
int index, int command_id, const base::string16& label) {
|
||||
model_->InsertItemAt(index, command_id, label);
|
||||
}
|
||||
|
||||
void Menu::InsertSeparatorAt(int index) {
|
||||
model_->InsertSeparatorAt(index, ui::NORMAL_SEPARATOR);
|
||||
}
|
||||
|
||||
void Menu::InsertCheckItemAt(int index,
|
||||
int command_id,
|
||||
const base::string16& label) {
|
||||
model_->InsertCheckItemAt(index, command_id, label);
|
||||
}
|
||||
|
||||
void Menu::InsertRadioItemAt(int index,
|
||||
int command_id,
|
||||
const base::string16& label,
|
||||
int group_id) {
|
||||
model_->InsertRadioItemAt(index, command_id, label, group_id);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void Menu::SetRole(int index, const base::string16& role) {
|
||||
model_->SetRole(index, role);
|
||||
}
|
||||
|
||||
void Menu::Clear() {
|
||||
model_->Clear();
|
||||
}
|
||||
|
||||
int Menu::GetIndexOfCommandId(int command_id) {
|
||||
return model_->GetIndexOfCommandId(command_id);
|
||||
}
|
||||
|
||||
int Menu::GetItemCount() const {
|
||||
return model_->GetItemCount();
|
||||
}
|
||||
|
||||
int Menu::GetCommandIdAt(int index) const {
|
||||
return model_->GetCommandIdAt(index);
|
||||
}
|
||||
|
||||
base::string16 Menu::GetLabelAt(int index) const {
|
||||
return model_->GetLabelAt(index);
|
||||
}
|
||||
|
||||
base::string16 Menu::GetSublabelAt(int index) const {
|
||||
return model_->GetSublabelAt(index);
|
||||
}
|
||||
|
||||
bool Menu::IsItemCheckedAt(int index) const {
|
||||
return model_->IsItemCheckedAt(index);
|
||||
}
|
||||
|
||||
bool Menu::IsEnabledAt(int index) const {
|
||||
return model_->IsEnabledAt(index);
|
||||
}
|
||||
|
||||
bool Menu::IsVisibleAt(int index) const {
|
||||
return model_->IsVisibleAt(index);
|
||||
}
|
||||
|
||||
// static
|
||||
void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
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("setRole", &Menu::SetRole)
|
||||
.SetMethod("clear", &Menu::Clear)
|
||||
.SetMethod("getIndexOfCommandId", &Menu::GetIndexOfCommandId)
|
||||
.SetMethod("getItemCount", &Menu::GetItemCount)
|
||||
.SetMethod("getCommandIdAt", &Menu::GetCommandIdAt)
|
||||
.SetMethod("getLabelAt", &Menu::GetLabelAt)
|
||||
.SetMethod("getSublabelAt", &Menu::GetSublabelAt)
|
||||
.SetMethod("isItemCheckedAt", &Menu::IsItemCheckedAt)
|
||||
.SetMethod("isEnabledAt", &Menu::IsEnabledAt)
|
||||
.SetMethod("isVisibleAt", &Menu::IsVisibleAt)
|
||||
.SetMethod("_popup", &Menu::Popup)
|
||||
.SetMethod("_popupAt", &Menu::PopupAt);
|
||||
}
|
||||
|
||||
} // 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::Menu;
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::Local<v8::Function> constructor = mate::CreateConstructor<Menu>(
|
||||
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",
|
||||
&Menu::SendActionToFirstResponder);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_menu, Initialize)
|
||||
125
atom/browser/api/atom_api_menu.h
Normal file
125
atom/browser/api/atom_api_menu.h
Normal file
@@ -0,0 +1,125 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/atom_api_window.h"
|
||||
#include "atom/browser/ui/atom_menu_model.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Menu : public mate::Wrappable,
|
||||
public AtomMenuModel::Delegate {
|
||||
public:
|
||||
static mate::Wrappable* Create();
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// Set the global menubar.
|
||||
static void SetApplicationMenu(Menu* menu);
|
||||
|
||||
// Fake sending an action from the application menu.
|
||||
static void SendActionToFirstResponder(const std::string& action);
|
||||
#endif
|
||||
|
||||
AtomMenuModel* model() const { return model_.get(); }
|
||||
|
||||
protected:
|
||||
Menu();
|
||||
virtual ~Menu();
|
||||
|
||||
// mate::Wrappable:
|
||||
void AfterInit(v8::Isolate* isolate) override;
|
||||
|
||||
// ui::SimpleMenuModel::Delegate:
|
||||
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<AtomMenuModel> model_;
|
||||
Menu* parent_;
|
||||
|
||||
private:
|
||||
void InsertItemAt(int index, int command_id, const base::string16& label);
|
||||
void InsertSeparatorAt(int index);
|
||||
void InsertCheckItemAt(int index,
|
||||
int command_id,
|
||||
const base::string16& label);
|
||||
void InsertRadioItemAt(int index,
|
||||
int command_id,
|
||||
const base::string16& label,
|
||||
int group_id);
|
||||
void InsertSubMenuAt(int index,
|
||||
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 SetRole(int index, const base::string16& role);
|
||||
void Clear();
|
||||
int GetIndexOfCommandId(int command_id);
|
||||
int GetItemCount() const;
|
||||
int GetCommandIdAt(int index) const;
|
||||
base::string16 GetLabelAt(int index) const;
|
||||
base::string16 GetSublabelAt(int index) const;
|
||||
bool IsItemCheckedAt(int index) const;
|
||||
bool IsEnabledAt(int index) const;
|
||||
bool IsVisibleAt(int index) const;
|
||||
|
||||
// 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);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<atom::AtomMenuModel*> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
atom::AtomMenuModel** 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_
|
||||
39
atom/browser/api/atom_api_menu_mac.h
Normal file
39
atom/browser/api/atom_api_menu_mac.h
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#import "atom/browser/ui/cocoa/atom_menu_controller.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class MenuMac : public Menu {
|
||||
protected:
|
||||
MenuMac();
|
||||
|
||||
void Popup(Window* window) override;
|
||||
void PopupAt(Window* window, int x, int y) override;
|
||||
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller_;
|
||||
|
||||
private:
|
||||
friend class Menu;
|
||||
|
||||
static void SendActionToFirstResponder(const std::string& action);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MenuMac);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_
|
||||
96
atom/browser/api/atom_api_menu_mac.mm
Normal file
96
atom/browser/api/atom_api_menu_mac.mm
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "atom/browser/api/atom_api_menu_mac.h"
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
MenuMac::MenuMac() {
|
||||
}
|
||||
|
||||
void MenuMac::Popup(Window* window) {
|
||||
NativeWindow* native_window = window->window();
|
||||
if (!native_window)
|
||||
return;
|
||||
content::WebContents* web_contents = native_window->web_contents();
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
NSWindow* nswindow = native_window->GetNativeWindow();
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller(
|
||||
[[AtomMenuController alloc] initWithModel:model_.get()]);
|
||||
|
||||
// Fake out a context menu event.
|
||||
NSEvent* currentEvent = [NSApp currentEvent];
|
||||
NSPoint position = [nswindow mouseLocationOutsideOfEventStream];
|
||||
NSTimeInterval eventTime = [currentEvent timestamp];
|
||||
NSEvent* clickEvent = [NSEvent mouseEventWithType:NSRightMouseDown
|
||||
location:position
|
||||
modifierFlags:NSRightMouseDownMask
|
||||
timestamp:eventTime
|
||||
windowNumber:[nswindow windowNumber]
|
||||
context:nil
|
||||
eventNumber:0
|
||||
clickCount:1
|
||||
pressure:1.0];
|
||||
|
||||
// Show the menu.
|
||||
[NSMenu popUpContextMenu:[menu_controller menu]
|
||||
withEvent:clickEvent
|
||||
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->web_contents();
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller(
|
||||
[[AtomMenuController alloc] initWithModel:model_.get()]);
|
||||
NSMenu* menu = [menu_controller menu];
|
||||
NSView* view = web_contents->GetContentNativeView();
|
||||
|
||||
// Show the menu.
|
||||
[menu popUpMenuPositioningItem:[menu itemAtIndex:0]
|
||||
atLocation:NSMakePoint(x, [view frame].size.height - y)
|
||||
inView:view];
|
||||
}
|
||||
|
||||
// static
|
||||
void Menu::SetApplicationMenu(Menu* base_menu) {
|
||||
MenuMac* menu = static_cast<MenuMac*>(base_menu);
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller(
|
||||
[[AtomMenuController alloc] initWithModel:menu->model_.get()]);
|
||||
[NSApp setMainMenu:[menu_controller menu]];
|
||||
|
||||
// Ensure the menu_controller_ is destroyed after main menu is set.
|
||||
menu_controller.swap(menu->menu_controller_);
|
||||
}
|
||||
|
||||
// static
|
||||
void Menu::SendActionToFirstResponder(const std::string& action) {
|
||||
SEL selector = NSSelectorFromString(base::SysUTF8ToNSString(action));
|
||||
[NSApp sendAction:selector to:nil from:[NSApp mainMenu]];
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Wrappable* Menu::Create() {
|
||||
return new MenuMac();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
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->web_contents();
|
||||
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_
|
||||
73
atom/browser/api/atom_api_power_monitor.cc
Normal file
73
atom/browser/api/atom_api_power_monitor.cc
Normal file
@@ -0,0 +1,73 @@
|
||||
// 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 "atom/common/node_includes.h"
|
||||
#include "base/power_monitor/power_monitor.h"
|
||||
#include "base/power_monitor/power_monitor_device_source.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
PowerMonitor::PowerMonitor() {
|
||||
base::PowerMonitor::Get()->AddObserver(this);
|
||||
}
|
||||
|
||||
PowerMonitor::~PowerMonitor() {
|
||||
base::PowerMonitor::Get()->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void PowerMonitor::OnPowerStateChange(bool on_battery_power) {
|
||||
if (on_battery_power)
|
||||
Emit("on-battery");
|
||||
else
|
||||
Emit("on-ac");
|
||||
}
|
||||
|
||||
void PowerMonitor::OnSuspend() {
|
||||
Emit("suspend");
|
||||
}
|
||||
|
||||
void PowerMonitor::OnResume() {
|
||||
Emit("resume");
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate,
|
||||
"Cannot initialize \"power-monitor\" module before app is ready")));
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
return CreateHandle(isolate, new PowerMonitor).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) {
|
||||
#if defined(OS_MACOSX)
|
||||
base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
|
||||
#endif
|
||||
|
||||
using atom::api::PowerMonitor;
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("powerMonitor", PowerMonitor::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_power_monitor, Initialize)
|
||||
39
atom/browser/api/atom_api_power_monitor.h
Normal file
39
atom/browser/api/atom_api_power_monitor.h
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/power_monitor/power_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class PowerMonitor : public mate::EventEmitter,
|
||||
public base::PowerObserver {
|
||||
public:
|
||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
PowerMonitor();
|
||||
virtual ~PowerMonitor();
|
||||
|
||||
// base::PowerObserver implementations:
|
||||
void OnPowerStateChange(bool on_battery_power) override;
|
||||
void OnSuspend() override;
|
||||
void OnResume() override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
128
atom/browser/api/atom_api_power_save_blocker.cc
Normal file
128
atom/browser/api/atom_api_power_save_blocker.cc
Normal file
@@ -0,0 +1,128 @@
|
||||
// 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_power_save_blocker.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "content/public/browser/power_save_blocker.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<content::PowerSaveBlocker::PowerSaveBlockerType> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
content::PowerSaveBlocker::PowerSaveBlockerType* out) {
|
||||
using content::PowerSaveBlocker;
|
||||
std::string type;
|
||||
if (!ConvertFromV8(isolate, val, &type))
|
||||
return false;
|
||||
if (type == "prevent-app-suspension")
|
||||
*out = PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
|
||||
else if (type == "prevent-display-sleep")
|
||||
*out = PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
PowerSaveBlocker::PowerSaveBlocker()
|
||||
: current_blocker_type_(
|
||||
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
|
||||
}
|
||||
|
||||
PowerSaveBlocker::~PowerSaveBlocker() {
|
||||
}
|
||||
|
||||
void PowerSaveBlocker::UpdatePowerSaveBlocker() {
|
||||
if (power_save_blocker_types_.empty()) {
|
||||
power_save_blocker_.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
// |kPowerSaveBlockPreventAppSuspension| keeps system active, but allows
|
||||
// screen to be turned off.
|
||||
// |kPowerSaveBlockPreventDisplaySleep| keeps system and screen active, has a
|
||||
// higher precedence level than |kPowerSaveBlockPreventAppSuspension|.
|
||||
//
|
||||
// Only the highest-precedence blocker type takes effect.
|
||||
content::PowerSaveBlocker::PowerSaveBlockerType new_blocker_type =
|
||||
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
|
||||
for (const auto& element : power_save_blocker_types_) {
|
||||
if (element.second ==
|
||||
content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep) {
|
||||
new_blocker_type =
|
||||
content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!power_save_blocker_ || new_blocker_type != current_blocker_type_) {
|
||||
scoped_ptr<content::PowerSaveBlocker> new_blocker =
|
||||
content::PowerSaveBlocker::Create(
|
||||
new_blocker_type,
|
||||
content::PowerSaveBlocker::kReasonOther,
|
||||
ATOM_PRODUCT_NAME);
|
||||
power_save_blocker_.swap(new_blocker);
|
||||
current_blocker_type_ = new_blocker_type;
|
||||
}
|
||||
}
|
||||
|
||||
int PowerSaveBlocker::Start(
|
||||
content::PowerSaveBlocker::PowerSaveBlockerType type) {
|
||||
static int count = 0;
|
||||
power_save_blocker_types_[count] = type;
|
||||
UpdatePowerSaveBlocker();
|
||||
return count++;
|
||||
}
|
||||
|
||||
bool PowerSaveBlocker::Stop(int id) {
|
||||
bool success = power_save_blocker_types_.erase(id) > 0;
|
||||
UpdatePowerSaveBlocker();
|
||||
return success;
|
||||
}
|
||||
|
||||
bool PowerSaveBlocker::IsStarted(int id) {
|
||||
return power_save_blocker_types_.find(id) != power_save_blocker_types_.end();
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder PowerSaveBlocker::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("start", &PowerSaveBlocker::Start)
|
||||
.SetMethod("stop", &PowerSaveBlocker::Stop)
|
||||
.SetMethod("isStarted", &PowerSaveBlocker::IsStarted);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) {
|
||||
return CreateHandle(isolate, new PowerSaveBlocker);
|
||||
}
|
||||
|
||||
} // 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("powerSaveBlocker", atom::api::PowerSaveBlocker::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_power_save_blocker, Initialize);
|
||||
59
atom/browser/api/atom_api_power_save_blocker.h
Normal file
59
atom/browser/api/atom_api_power_save_blocker.h
Normal file
@@ -0,0 +1,59 @@
|
||||
// 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_POWER_SAVE_BLOCKER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "content/public/browser/power_save_blocker.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
|
||||
namespace mate {
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class PowerSaveBlocker : public mate::Wrappable {
|
||||
public:
|
||||
static mate::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
PowerSaveBlocker();
|
||||
virtual ~PowerSaveBlocker();
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
void UpdatePowerSaveBlocker();
|
||||
int Start(content::PowerSaveBlocker::PowerSaveBlockerType type);
|
||||
bool Stop(int id);
|
||||
bool IsStarted(int id);
|
||||
|
||||
scoped_ptr<content::PowerSaveBlocker> power_save_blocker_;
|
||||
|
||||
// Currnet blocker type used by |power_save_blocker_|
|
||||
content::PowerSaveBlocker::PowerSaveBlockerType current_blocker_type_;
|
||||
|
||||
// Map from id to the corresponding blocker type for each request.
|
||||
using PowerSaveBlockerTypeMap =
|
||||
std::map<int, content::PowerSaveBlocker::PowerSaveBlockerType>;
|
||||
PowerSaveBlockerTypeMap power_save_blocker_types_;
|
||||
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_
|
||||
181
atom/browser/api/atom_api_protocol.cc
Normal file
181
atom/browser/api/atom_api_protocol.cc
Normal file
@@ -0,0 +1,181 @@
|
||||
// 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 "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/net/url_request_async_asar_job.h"
|
||||
#include "atom/browser/net/url_request_buffer_job.h"
|
||||
#include "atom/browser/net/url_request_fetch_job.h"
|
||||
#include "atom/browser/net/url_request_string_job.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<const net::URLRequest*> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const net::URLRequest* val) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetValue("method", val->method())
|
||||
.SetValue("url", val->url().spec())
|
||||
.SetValue("referrer", val->referrer())
|
||||
.Build()->NewInstance();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
Protocol::Protocol(AtomBrowserContext* browser_context)
|
||||
: request_context_getter_(browser_context->GetRequestContext()),
|
||||
job_factory_(browser_context->job_factory()) {
|
||||
CHECK(job_factory_);
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes)
|
||||
.SetMethod("registerStringProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestStringJob>)
|
||||
.SetMethod("registerBufferProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestBufferJob>)
|
||||
.SetMethod("registerFileProtocol",
|
||||
&Protocol::RegisterProtocol<UrlRequestAsyncAsarJob>)
|
||||
.SetMethod("registerHttpProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
|
||||
.SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled)
|
||||
.SetMethod("interceptStringProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestStringJob>)
|
||||
.SetMethod("interceptBufferProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestBufferJob>)
|
||||
.SetMethod("interceptFileProtocol",
|
||||
&Protocol::InterceptProtocol<UrlRequestAsyncAsarJob>)
|
||||
.SetMethod("interceptHttpProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
|
||||
}
|
||||
|
||||
void Protocol::RegisterStandardSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
atom::AtomBrowserClient::SetCustomSchemes(schemes);
|
||||
}
|
||||
|
||||
void Protocol::UnregisterProtocol(
|
||||
const std::string& scheme, mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
args->GetNext(&callback);
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Protocol::UnregisterProtocolInIO,
|
||||
base::Unretained(this), scheme),
|
||||
base::Bind(&Protocol::OnIOCompleted,
|
||||
base::Unretained(this), callback));
|
||||
}
|
||||
|
||||
Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
|
||||
const std::string& scheme) {
|
||||
if (!job_factory_->HasProtocolHandler(scheme))
|
||||
return PROTOCOL_NOT_REGISTERED;
|
||||
job_factory_->SetProtocolHandler(scheme, nullptr);
|
||||
return PROTOCOL_OK;
|
||||
}
|
||||
|
||||
void Protocol::IsProtocolHandled(const std::string& scheme,
|
||||
const BooleanCallback& callback) {
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Protocol::IsProtocolHandledInIO,
|
||||
base::Unretained(this), scheme),
|
||||
callback);
|
||||
}
|
||||
|
||||
bool Protocol::IsProtocolHandledInIO(const std::string& scheme) {
|
||||
return job_factory_->IsHandledProtocol(scheme);
|
||||
}
|
||||
|
||||
void Protocol::UninterceptProtocol(
|
||||
const std::string& scheme, mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
args->GetNext(&callback);
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Protocol::UninterceptProtocolInIO,
|
||||
base::Unretained(this), scheme),
|
||||
base::Bind(&Protocol::OnIOCompleted,
|
||||
base::Unretained(this), callback));
|
||||
}
|
||||
|
||||
Protocol::ProtocolError Protocol::UninterceptProtocolInIO(
|
||||
const std::string& scheme) {
|
||||
if (!original_protocols_.contains(scheme))
|
||||
return PROTOCOL_NOT_INTERCEPTED;
|
||||
job_factory_->ReplaceProtocol(scheme,
|
||||
original_protocols_.take_and_erase(scheme));
|
||||
return PROTOCOL_OK;
|
||||
}
|
||||
|
||||
void Protocol::OnIOCompleted(
|
||||
const CompletionCallback& callback, ProtocolError error) {
|
||||
// The completion callback is optional.
|
||||
if (callback.is_null())
|
||||
return;
|
||||
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
|
||||
if (error == PROTOCOL_OK) {
|
||||
callback.Run(v8::Null(isolate()));
|
||||
} else {
|
||||
std::string str = ErrorCodeToString(error);
|
||||
callback.Run(v8::Exception::Error(mate::StringToV8(isolate(), str)));
|
||||
}
|
||||
}
|
||||
|
||||
std::string Protocol::ErrorCodeToString(ProtocolError error) {
|
||||
switch (error) {
|
||||
case PROTOCOL_FAIL: return "Failed to manipulate protocol factory";
|
||||
case PROTOCOL_REGISTERED: return "The scheme has been registred";
|
||||
case PROTOCOL_NOT_REGISTERED: return "The scheme has not been registred";
|
||||
case PROTOCOL_INTERCEPTED: return "The scheme has been intercepted";
|
||||
case PROTOCOL_NOT_INTERCEPTED: return "The scheme has not been intercepted";
|
||||
default: return "Unexpected error";
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<Protocol> Protocol::Create(
|
||||
v8::Isolate* isolate, AtomBrowserContext* browser_context) {
|
||||
return mate::CreateHandle(isolate, new Protocol(browser_context));
|
||||
}
|
||||
|
||||
} // 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);
|
||||
auto browser_context = static_cast<atom::AtomBrowserContext*>(
|
||||
atom::AtomBrowserMainParts::Get()->browser_context());
|
||||
dict.Set("protocol", atom::api::Protocol::Create(isolate, browser_context));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_protocol, Initialize)
|
||||
192
atom/browser/api/atom_api_protocol.h
Normal file
192
atom/browser/api/atom_api_protocol.h
Normal file
@@ -0,0 +1,192 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_PROTOCOL_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_PROTOCOL_H_
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/containers/scoped_ptr_hash_map.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/arguments.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
|
||||
namespace net {
|
||||
class URLRequest;
|
||||
class URLRequestContextGetter;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserContext;
|
||||
class AtomURLRequestJobFactory;
|
||||
|
||||
namespace api {
|
||||
|
||||
class Protocol : public mate::Wrappable {
|
||||
public:
|
||||
using Handler =
|
||||
base::Callback<void(const net::URLRequest*, v8::Local<v8::Value>)>;
|
||||
using CompletionCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
using BooleanCallback = base::Callback<void(bool)>;
|
||||
|
||||
static mate::Handle<Protocol> Create(
|
||||
v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
|
||||
protected:
|
||||
explicit Protocol(AtomBrowserContext* browser_context);
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate);
|
||||
|
||||
private:
|
||||
// Possible errors.
|
||||
enum ProtocolError {
|
||||
PROTOCOL_OK, // no error
|
||||
PROTOCOL_FAIL, // operation failed, should never occur
|
||||
PROTOCOL_REGISTERED,
|
||||
PROTOCOL_NOT_REGISTERED,
|
||||
PROTOCOL_INTERCEPTED,
|
||||
PROTOCOL_NOT_INTERCEPTED,
|
||||
};
|
||||
|
||||
// The protocol handler that will create a protocol handler for certain
|
||||
// request job.
|
||||
template<typename RequestJob>
|
||||
class CustomProtocolHandler
|
||||
: public net::URLRequestJobFactory::ProtocolHandler {
|
||||
public:
|
||||
CustomProtocolHandler(
|
||||
v8::Isolate* isolate,
|
||||
net::URLRequestContextGetter* request_context,
|
||||
const Handler& handler)
|
||||
: isolate_(isolate),
|
||||
request_context_(request_context),
|
||||
handler_(handler) {}
|
||||
~CustomProtocolHandler() override {}
|
||||
|
||||
net::URLRequestJob* MaybeCreateJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const override {
|
||||
RequestJob* request_job = new RequestJob(request, network_delegate);
|
||||
request_job->SetHandlerInfo(isolate_, request_context_, handler_);
|
||||
return request_job;
|
||||
}
|
||||
|
||||
private:
|
||||
v8::Isolate* isolate_;
|
||||
net::URLRequestContextGetter* request_context_;
|
||||
Protocol::Handler handler_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
|
||||
};
|
||||
|
||||
// Register schemes to standard scheme list.
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes);
|
||||
|
||||
// Register the protocol with certain request job.
|
||||
template<typename RequestJob>
|
||||
void RegisterProtocol(const std::string& scheme,
|
||||
const Handler& handler,
|
||||
mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
args->GetNext(&callback);
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Protocol::RegisterProtocolInIO<RequestJob>,
|
||||
base::Unretained(this), scheme, handler),
|
||||
base::Bind(&Protocol::OnIOCompleted,
|
||||
base::Unretained(this), callback));
|
||||
}
|
||||
template<typename RequestJob>
|
||||
ProtocolError RegisterProtocolInIO(const std::string& scheme,
|
||||
const Handler& handler) {
|
||||
if (job_factory_->IsHandledProtocol(scheme))
|
||||
return PROTOCOL_REGISTERED;
|
||||
scoped_ptr<CustomProtocolHandler<RequestJob>> protocol_handler(
|
||||
new CustomProtocolHandler<RequestJob>(
|
||||
isolate(), request_context_getter_, handler));
|
||||
if (job_factory_->SetProtocolHandler(scheme, protocol_handler.Pass()))
|
||||
return PROTOCOL_OK;
|
||||
else
|
||||
return PROTOCOL_FAIL;
|
||||
}
|
||||
|
||||
// Unregister the protocol handler that handles |scheme|.
|
||||
void UnregisterProtocol(const std::string& scheme, mate::Arguments* args);
|
||||
ProtocolError UnregisterProtocolInIO(const std::string& scheme);
|
||||
|
||||
// Whether the protocol has handler registered.
|
||||
void IsProtocolHandled(const std::string& scheme,
|
||||
const BooleanCallback& callback);
|
||||
bool IsProtocolHandledInIO(const std::string& scheme);
|
||||
|
||||
// Replace the protocol handler with a new one.
|
||||
template<typename RequestJob>
|
||||
void InterceptProtocol(const std::string& scheme,
|
||||
const Handler& handler,
|
||||
mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
args->GetNext(&callback);
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Protocol::InterceptProtocolInIO<RequestJob>,
|
||||
base::Unretained(this), scheme, handler),
|
||||
base::Bind(&Protocol::OnIOCompleted,
|
||||
base::Unretained(this), callback));
|
||||
}
|
||||
template<typename RequestJob>
|
||||
ProtocolError InterceptProtocolInIO(const std::string& scheme,
|
||||
const Handler& handler) {
|
||||
if (!job_factory_->IsHandledProtocol(scheme))
|
||||
return PROTOCOL_NOT_REGISTERED;
|
||||
// It is possible a protocol is handled but can not be intercepted.
|
||||
if (!job_factory_->HasProtocolHandler(scheme))
|
||||
return PROTOCOL_FAIL;
|
||||
if (ContainsKey(original_protocols_, scheme))
|
||||
return PROTOCOL_INTERCEPTED;
|
||||
scoped_ptr<CustomProtocolHandler<RequestJob>> protocol_handler(
|
||||
new CustomProtocolHandler<RequestJob>(
|
||||
isolate(), request_context_getter_, handler));
|
||||
original_protocols_.set(
|
||||
scheme,
|
||||
job_factory_->ReplaceProtocol(scheme, protocol_handler.Pass()));
|
||||
return PROTOCOL_OK;
|
||||
}
|
||||
|
||||
// Restore the |scheme| to its original protocol handler.
|
||||
void UninterceptProtocol(const std::string& scheme, mate::Arguments* args);
|
||||
ProtocolError UninterceptProtocolInIO(const std::string& scheme);
|
||||
|
||||
// Convert error code to JS exception and call the callback.
|
||||
void OnIOCompleted(const CompletionCallback& callback, ProtocolError error);
|
||||
|
||||
// Convert error code to string.
|
||||
std::string ErrorCodeToString(ProtocolError error);
|
||||
|
||||
net::URLRequestContextGetter* request_context_getter_;
|
||||
|
||||
// Map that stores the original protocols of schemes.
|
||||
using OriginalProtocolsMap = base::ScopedPtrHashMap<
|
||||
std::string,
|
||||
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>>;
|
||||
OriginalProtocolsMap original_protocols_;
|
||||
|
||||
AtomURLRequestJobFactory* job_factory_; // weak ref
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Protocol);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_PROTOCOL_H_
|
||||
146
atom/browser/api/atom_api_screen.cc
Normal file
146
atom/browser/api/atom_api_screen.cc
Normal file
@@ -0,0 +1,146 @@
|
||||
// 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()) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate,
|
||||
"Cannot initialize \"screen\" module before app is ready")));
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
gfx::Screen* screen = gfx::Screen::GetNativeScreen();
|
||||
if (!screen) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate, "Failed to get screen information")));
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
return mate::CreateHandle(isolate, new Screen(screen)).ToV8();
|
||||
}
|
||||
|
||||
} // 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_
|
||||
361
atom/browser/api/atom_api_session.cc
Normal file
361
atom/browser/api/atom_api_session.cc
Normal file
@@ -0,0 +1,361 @@
|
||||
// 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_session.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/atom_api_cookies.h"
|
||||
#include "atom/browser/api/atom_api_download_item.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/prefs/pref_service.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/thread_task_runner_handle.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/disk_cache/disk_cache.h"
|
||||
#include "net/proxy/proxy_service.h"
|
||||
#include "net/proxy/proxy_config_service_fixed.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
using content::StoragePartition;
|
||||
|
||||
namespace {
|
||||
|
||||
struct ClearStorageDataOptions {
|
||||
GURL origin;
|
||||
uint32 storage_types = StoragePartition::REMOVE_DATA_MASK_ALL;
|
||||
uint32 quota_types = StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL;
|
||||
};
|
||||
|
||||
uint32 GetStorageMask(const std::vector<std::string>& storage_types) {
|
||||
uint32 storage_mask = 0;
|
||||
for (const auto& it : storage_types) {
|
||||
auto type = base::StringToLowerASCII(it);
|
||||
if (type == "appcache")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_APPCACHE;
|
||||
else if (type == "cookies")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_COOKIES;
|
||||
else if (type == "filesystem")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS;
|
||||
else if (type == "indexdb")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_INDEXEDDB;
|
||||
else if (type == "localstorage")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE;
|
||||
else if (type == "shadercache")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE;
|
||||
else if (type == "websql")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_WEBSQL;
|
||||
else if (type == "serviceworkers")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS;
|
||||
}
|
||||
return storage_mask;
|
||||
}
|
||||
|
||||
uint32 GetQuotaMask(const std::vector<std::string>& quota_types) {
|
||||
uint32 quota_mask = 0;
|
||||
for (const auto& it : quota_types) {
|
||||
auto type = base::StringToLowerASCII(it);
|
||||
if (type == "temporary")
|
||||
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY;
|
||||
else if (type == "persistent")
|
||||
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT;
|
||||
else if (type == "syncable")
|
||||
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_SYNCABLE;
|
||||
}
|
||||
return quota_mask;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<ClearStorageDataOptions> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
ClearStorageDataOptions* out) {
|
||||
mate::Dictionary options;
|
||||
if (!ConvertFromV8(isolate, val, &options))
|
||||
return false;
|
||||
options.Get("origin", &out->origin);
|
||||
std::vector<std::string> types;
|
||||
if (options.Get("storages", &types))
|
||||
out->storage_types = GetStorageMask(types);
|
||||
if (options.Get("quotas", &types))
|
||||
out->quota_types = GetQuotaMask(types);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// The wrapSession funtion which is implemented in JavaScript
|
||||
using WrapSessionCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
WrapSessionCallback g_wrap_session;
|
||||
|
||||
class ResolveProxyHelper {
|
||||
public:
|
||||
ResolveProxyHelper(AtomBrowserContext* browser_context,
|
||||
const GURL& url,
|
||||
Session::ResolveProxyCallback callback)
|
||||
: callback_(callback),
|
||||
original_thread_(base::ThreadTaskRunnerHandle::Get()) {
|
||||
scoped_refptr<net::URLRequestContextGetter> context_getter =
|
||||
browser_context->GetRequestContext();
|
||||
context_getter->GetNetworkTaskRunner()->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&ResolveProxyHelper::ResolveProxy,
|
||||
base::Unretained(this), context_getter, url));
|
||||
}
|
||||
|
||||
void OnResolveProxyCompleted(int result) {
|
||||
std::string proxy;
|
||||
if (result == net::OK)
|
||||
proxy = proxy_info_.ToPacString();
|
||||
original_thread_->PostTask(FROM_HERE,
|
||||
base::Bind(callback_, proxy));
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
void ResolveProxy(scoped_refptr<net::URLRequestContextGetter> context_getter,
|
||||
const GURL& url) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
|
||||
net::ProxyService* proxy_service =
|
||||
context_getter->GetURLRequestContext()->proxy_service();
|
||||
net::CompletionCallback completion_callback =
|
||||
base::Bind(&ResolveProxyHelper::OnResolveProxyCompleted,
|
||||
base::Unretained(this));
|
||||
|
||||
// Start the request.
|
||||
int result = proxy_service->ResolveProxy(
|
||||
url, net::LOAD_NORMAL, &proxy_info_, completion_callback,
|
||||
&pac_req_, nullptr, net::BoundNetLog());
|
||||
|
||||
// Completed synchronously.
|
||||
if (result != net::ERR_IO_PENDING)
|
||||
completion_callback.Run(result);
|
||||
}
|
||||
|
||||
Session::ResolveProxyCallback callback_;
|
||||
net::ProxyInfo proxy_info_;
|
||||
net::ProxyService::PacRequest* pac_req_;
|
||||
scoped_refptr<base::SingleThreadTaskRunner> original_thread_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
|
||||
};
|
||||
|
||||
// Runs the callback in UI thread.
|
||||
template <typename ...T>
|
||||
void RunCallbackInUI(const base::Callback<void(T...)>& callback, T... result) {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE, base::Bind(callback, result...));
|
||||
}
|
||||
|
||||
// Callback of HttpCache::GetBackend.
|
||||
void OnGetBackend(disk_cache::Backend** backend_ptr,
|
||||
const net::CompletionCallback& callback,
|
||||
int result) {
|
||||
if (result != net::OK) {
|
||||
RunCallbackInUI(callback, result);
|
||||
} else if (backend_ptr && *backend_ptr) {
|
||||
(*backend_ptr)->DoomAllEntries(base::Bind(&RunCallbackInUI<int>, callback));
|
||||
} else {
|
||||
RunCallbackInUI<int>(callback, net::ERR_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
void ClearHttpCacheInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
const net::CompletionCallback& callback) {
|
||||
auto request_context = context_getter->GetURLRequestContext();
|
||||
auto http_cache = request_context->http_transaction_factory()->GetCache();
|
||||
if (!http_cache)
|
||||
RunCallbackInUI<int>(callback, net::ERR_FAILED);
|
||||
|
||||
// Call GetBackend and make the backend's ptr accessable in OnGetBackend.
|
||||
using BackendPtr = disk_cache::Backend*;
|
||||
BackendPtr* backend_ptr = new BackendPtr(nullptr);
|
||||
net::CompletionCallback on_get_backend =
|
||||
base::Bind(&OnGetBackend, base::Owned(backend_ptr), callback);
|
||||
int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
|
||||
if (rv != net::ERR_IO_PENDING)
|
||||
on_get_backend.Run(net::OK);
|
||||
}
|
||||
|
||||
void SetProxyInIO(net::URLRequestContextGetter* getter,
|
||||
const std::string& proxy,
|
||||
const base::Closure& callback) {
|
||||
net::ProxyConfig config;
|
||||
config.proxy_rules().ParseFromString(proxy);
|
||||
auto proxy_service = getter->GetURLRequestContext()->proxy_service();
|
||||
proxy_service->ResetConfigService(new net::ProxyConfigServiceFixed(config));
|
||||
RunCallbackInUI(callback);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Session::Session(AtomBrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
AttachAsUserData(browser_context);
|
||||
|
||||
// Observe DownloadManger to get download notifications.
|
||||
content::BrowserContext::GetDownloadManager(browser_context)->
|
||||
AddObserver(this);
|
||||
}
|
||||
|
||||
Session::~Session() {
|
||||
content::BrowserContext::GetDownloadManager(browser_context())->
|
||||
RemoveObserver(this);
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void Session::OnDownloadCreated(content::DownloadManager* manager,
|
||||
content::DownloadItem* item) {
|
||||
auto web_contents = item->GetWebContents();
|
||||
bool prevent_default = Emit(
|
||||
"will-download",
|
||||
DownloadItem::Create(isolate(), item),
|
||||
api::WebContents::CreateFrom(isolate(), web_contents));
|
||||
if (prevent_default) {
|
||||
item->Cancel(true);
|
||||
item->Remove();
|
||||
}
|
||||
}
|
||||
|
||||
bool Session::IsDestroyed() const {
|
||||
return !browser_context_;
|
||||
}
|
||||
|
||||
void Session::Destroy() {
|
||||
browser_context_ = nullptr;
|
||||
}
|
||||
|
||||
void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
|
||||
new ResolveProxyHelper(browser_context(), url, callback);
|
||||
}
|
||||
|
||||
void Session::ClearCache(const net::CompletionCallback& callback) {
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&ClearHttpCacheInIO,
|
||||
make_scoped_refptr(browser_context_->GetRequestContext()),
|
||||
callback));
|
||||
}
|
||||
|
||||
void Session::ClearStorageData(mate::Arguments* args) {
|
||||
// clearStorageData([options, ]callback)
|
||||
ClearStorageDataOptions options;
|
||||
args->GetNext(&options);
|
||||
base::Closure callback;
|
||||
if (!args->GetNext(&callback)) {
|
||||
args->ThrowError();
|
||||
return;
|
||||
}
|
||||
|
||||
auto storage_partition =
|
||||
content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
|
||||
storage_partition->ClearData(
|
||||
options.storage_types, options.quota_types, options.origin,
|
||||
content::StoragePartition::OriginMatcherFunction(),
|
||||
base::Time(), base::Time::Max(), callback);
|
||||
}
|
||||
|
||||
void Session::SetProxy(const std::string& proxy,
|
||||
const base::Closure& callback) {
|
||||
auto getter = browser_context_->GetRequestContext();
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&SetProxyInIO, base::Unretained(getter), proxy, callback));
|
||||
}
|
||||
|
||||
void Session::SetDownloadPath(const base::FilePath& path) {
|
||||
browser_context_->prefs()->SetFilePath(
|
||||
prefs::kDownloadDefaultDirectory, path);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
|
||||
if (cookies_.IsEmpty()) {
|
||||
auto handle = atom::api::Cookies::Create(isolate, browser_context());
|
||||
cookies_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, cookies_);
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder Session::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("resolveProxy", &Session::ResolveProxy)
|
||||
.SetMethod("clearCache", &Session::ClearCache)
|
||||
.SetMethod("clearStorageData", &Session::ClearStorageData)
|
||||
.SetMethod("setProxy", &Session::SetProxy)
|
||||
.SetMethod("setDownloadPath", &Session::SetDownloadPath)
|
||||
.SetProperty("cookies", &Session::Cookies);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<Session> Session::CreateFrom(
|
||||
v8::Isolate* isolate, AtomBrowserContext* browser_context) {
|
||||
auto existing = TrackableObject::FromWrappedClass(isolate, browser_context);
|
||||
if (existing)
|
||||
return mate::CreateHandle(isolate, static_cast<Session*>(existing));
|
||||
|
||||
auto handle = mate::CreateHandle(isolate, new Session(browser_context));
|
||||
g_wrap_session.Run(handle.ToV8());
|
||||
return handle;
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<Session> Session::FromPartition(
|
||||
v8::Isolate* isolate, const std::string& partition, bool in_memory) {
|
||||
auto browser_context = brightray::BrowserContext::From(partition, in_memory);
|
||||
return CreateFrom(isolate,
|
||||
static_cast<AtomBrowserContext*>(browser_context.get()));
|
||||
}
|
||||
|
||||
void SetWrapSession(const WrapSessionCallback& callback) {
|
||||
g_wrap_session = callback;
|
||||
}
|
||||
|
||||
void ClearWrapSession() {
|
||||
g_wrap_session.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("fromPartition", &atom::api::Session::FromPartition);
|
||||
dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession);
|
||||
dict.SetMethod("_clearWrapSession", &atom::api::ClearWrapSession);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_session, Initialize)
|
||||
82
atom/browser/api/atom_api_session.h
Normal file
82
atom/browser/api/atom_api_session.h
Normal file
@@ -0,0 +1,82 @@
|
||||
// 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_SESSION_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_SESSION_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/base/completion_callback.h"
|
||||
|
||||
class GURL;
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserContext;
|
||||
|
||||
namespace api {
|
||||
|
||||
class Session: public mate::TrackableObject<Session>,
|
||||
public content::DownloadManager::Observer {
|
||||
public:
|
||||
using ResolveProxyCallback = base::Callback<void(std::string)>;
|
||||
|
||||
// Gets or creates Session from the |browser_context|.
|
||||
static mate::Handle<Session> CreateFrom(
|
||||
v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
|
||||
// Gets the Session of |partition| and |in_memory|.
|
||||
static mate::Handle<Session> FromPartition(
|
||||
v8::Isolate* isolate, const std::string& partition, bool in_memory);
|
||||
|
||||
AtomBrowserContext* browser_context() const { return browser_context_.get(); }
|
||||
|
||||
protected:
|
||||
explicit Session(AtomBrowserContext* browser_context);
|
||||
~Session();
|
||||
|
||||
// content::DownloadManager::Observer:
|
||||
void OnDownloadCreated(content::DownloadManager* manager,
|
||||
content::DownloadItem* item) override;
|
||||
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
bool IsDestroyed() const override;
|
||||
|
||||
private:
|
||||
// mate::TrackableObject:
|
||||
void Destroy() override;
|
||||
|
||||
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
|
||||
void ClearCache(const net::CompletionCallback& callback);
|
||||
void ClearStorageData(mate::Arguments* args);
|
||||
void SetProxy(const std::string& proxy, const base::Closure& callback);
|
||||
void SetDownloadPath(const base::FilePath& path);
|
||||
v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
|
||||
|
||||
// Cached object for cookies API.
|
||||
v8::Global<v8::Value> cookies_;
|
||||
|
||||
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Session);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_SESSION_H_
|
||||
177
atom/browser/api/atom_api_tray.cc
Normal file
177
atom/browser/api/atom_api_tray.cc
Normal file
@@ -0,0 +1,177 @@
|
||||
// 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 "atom/common/node_includes.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/events/event_constants.h"
|
||||
#include "ui/gfx/image/image.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()) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate, "Cannot create Tray before app is ready")));
|
||||
return nullptr;
|
||||
}
|
||||
return new Tray(image);
|
||||
}
|
||||
|
||||
void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
EmitCustomEvent("clicked",
|
||||
ModifiersToObject(isolate(), modifiers), bounds);
|
||||
}
|
||||
|
||||
void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
EmitCustomEvent("double-clicked",
|
||||
ModifiersToObject(isolate(), modifiers), bounds);
|
||||
}
|
||||
|
||||
void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
EmitCustomEvent("right-clicked",
|
||||
ModifiersToObject(isolate(), modifiers), bounds);
|
||||
}
|
||||
|
||||
void Tray::OnBalloonShow() {
|
||||
Emit("balloon-show");
|
||||
}
|
||||
|
||||
void Tray::OnBalloonClicked() {
|
||||
Emit("balloon-clicked");
|
||||
}
|
||||
|
||||
void Tray::OnBalloonClosed() {
|
||||
Emit("balloon-closed");
|
||||
}
|
||||
|
||||
void Tray::OnDropFiles(const std::vector<std::string>& files) {
|
||||
Emit("drop-files", files);
|
||||
}
|
||||
|
||||
bool Tray::IsDestroyed() const {
|
||||
return !tray_icon_;
|
||||
}
|
||||
|
||||
void Tray::Destroy() {
|
||||
tray_icon_.reset();
|
||||
}
|
||||
|
||||
void Tray::SetImage(mate::Arguments* args, const gfx::Image& image) {
|
||||
tray_icon_->SetImage(image);
|
||||
}
|
||||
|
||||
void Tray::SetPressedImage(mate::Arguments* args, const gfx::Image& image) {
|
||||
tray_icon_->SetPressedImage(image);
|
||||
}
|
||||
|
||||
void Tray::SetToolTip(mate::Arguments* args, const std::string& tool_tip) {
|
||||
tray_icon_->SetToolTip(tool_tip);
|
||||
}
|
||||
|
||||
void Tray::SetTitle(mate::Arguments* args, const std::string& title) {
|
||||
tray_icon_->SetTitle(title);
|
||||
}
|
||||
|
||||
void Tray::SetHighlightMode(mate::Arguments* args, bool highlight) {
|
||||
tray_icon_->SetHighlightMode(highlight);
|
||||
}
|
||||
|
||||
void Tray::DisplayBalloon(mate::Arguments* args,
|
||||
const mate::Dictionary& options) {
|
||||
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::PopUpContextMenu(mate::Arguments* args) {
|
||||
gfx::Point pos;
|
||||
args->GetNext(&pos);
|
||||
tray_icon_->PopUpContextMenu(pos);
|
||||
}
|
||||
|
||||
void Tray::SetContextMenu(mate::Arguments* args, Menu* menu) {
|
||||
tray_icon_->SetContextMenu(menu->model());
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> Tray::ModifiersToObject(v8::Isolate* isolate,
|
||||
int modifiers) {
|
||||
mate::Dictionary obj(isolate, v8::Object::New(isolate));
|
||||
obj.Set("shiftKey", static_cast<bool>(modifiers & ui::EF_SHIFT_DOWN));
|
||||
obj.Set("ctrlKey", static_cast<bool>(modifiers & ui::EF_CONTROL_DOWN));
|
||||
obj.Set("altKey", static_cast<bool>(modifiers & ui::EF_ALT_DOWN));
|
||||
obj.Set("metaKey", static_cast<bool>(modifiers & ui::EF_COMMAND_DOWN));
|
||||
return obj.GetHandle();
|
||||
}
|
||||
|
||||
// static
|
||||
void Tray::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("destroy", &Tray::Destroy, true)
|
||||
.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("popUpContextMenu", &Tray::PopUpContextMenu)
|
||||
.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)
|
||||
78
atom/browser/api/atom_api_tray.h
Normal file
78
atom/browser/api/atom_api_tray.h
Normal file
@@ -0,0 +1,78 @@
|
||||
// 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 <vector>
|
||||
|
||||
#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& bounds, int modifiers) override;
|
||||
void OnDoubleClicked(const gfx::Rect& bounds, int modifiers) override;
|
||||
void OnRightClicked(const gfx::Rect& bounds, int modifiers) override;
|
||||
void OnBalloonShow() override;
|
||||
void OnBalloonClicked() override;
|
||||
void OnBalloonClosed() override;
|
||||
void OnDropFiles(const std::vector<std::string>& files) override;
|
||||
|
||||
// mate::Wrappable:
|
||||
bool IsDestroyed() const 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 PopUpContextMenu(mate::Arguments* args);
|
||||
void SetContextMenu(mate::Arguments* args, Menu* menu);
|
||||
|
||||
private:
|
||||
v8::Local<v8::Object> ModifiersToObject(v8::Isolate* isolate, int modifiers);
|
||||
|
||||
scoped_ptr<TrayIcon> tray_icon_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Tray);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_TRAY_H_
|
||||
1036
atom/browser/api/atom_api_web_contents.cc
Normal file
1036
atom/browser/api/atom_api_web_contents.cc
Normal file
File diff suppressed because it is too large
Load Diff
253
atom/browser/api/atom_api_web_contents.h
Normal file
253
atom/browser/api/atom_api_web_contents.h
Normal file
@@ -0,0 +1,253 @@
|
||||
// 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/frame_subscriber.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "content/public/common/favicon_url.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
namespace blink {
|
||||
struct WebDeviceEmulationParams;
|
||||
}
|
||||
|
||||
namespace brightray {
|
||||
class InspectableWebContents;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
struct SetSizeParams;
|
||||
class AtomBrowserContext;
|
||||
class WebViewGuestDelegate;
|
||||
|
||||
namespace api {
|
||||
|
||||
class WebContents : public mate::TrackableObject<WebContents>,
|
||||
public CommonWebContentsDelegate,
|
||||
public content::WebContentsObserver {
|
||||
public:
|
||||
// For node.js callback function type: function(error, buffer)
|
||||
using PrintToPDFCallback =
|
||||
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>;
|
||||
|
||||
// Create from an existing WebContents.
|
||||
static mate::Handle<WebContents> CreateFrom(
|
||||
v8::Isolate* isolate, content::WebContents* web_contents);
|
||||
|
||||
// Create a new WebContents.
|
||||
static mate::Handle<WebContents> Create(
|
||||
v8::Isolate* isolate, const mate::Dictionary& options);
|
||||
|
||||
// mate::TrackableObject:
|
||||
void Destroy() override;
|
||||
|
||||
bool IsAlive() const;
|
||||
int GetID() const;
|
||||
bool Equal(const WebContents* web_contents) const;
|
||||
void LoadURL(const GURL& url, const mate::Dictionary& options);
|
||||
GURL GetURL() const;
|
||||
base::string16 GetTitle() const;
|
||||
bool IsLoading() const;
|
||||
bool IsWaitingForResponse() const;
|
||||
void Stop();
|
||||
void ReloadIgnoringCache();
|
||||
void GoBack();
|
||||
void GoForward();
|
||||
void GoToOffset(int offset);
|
||||
bool IsCrashed() const;
|
||||
void SetUserAgent(const std::string& user_agent);
|
||||
std::string GetUserAgent();
|
||||
void InsertCSS(const std::string& css);
|
||||
void ExecuteJavaScript(const base::string16& code,
|
||||
bool has_user_gesture);
|
||||
void OpenDevTools(mate::Arguments* args);
|
||||
void CloseDevTools();
|
||||
bool IsDevToolsOpened();
|
||||
void ToggleDevTools();
|
||||
void EnableDeviceEmulation(const blink::WebDeviceEmulationParams& params);
|
||||
void DisableDeviceEmulation();
|
||||
void InspectElement(int x, int y);
|
||||
void InspectServiceWorker();
|
||||
v8::Local<v8::Value> Session(v8::Isolate* isolate);
|
||||
void HasServiceWorker(const base::Callback<void(bool)>&);
|
||||
void UnregisterServiceWorker(const base::Callback<void(bool)>&);
|
||||
void SetAudioMuted(bool muted);
|
||||
bool IsAudioMuted();
|
||||
void Print(mate::Arguments* args);
|
||||
|
||||
// Print current page as PDF.
|
||||
void PrintToPDF(const base::DictionaryValue& setting,
|
||||
const PrintToPDFCallback& callback);
|
||||
|
||||
// DevTools workspace api.
|
||||
void AddWorkSpace(mate::Arguments* args, const base::FilePath& path);
|
||||
void RemoveWorkSpace(mate::Arguments* args, const base::FilePath& path);
|
||||
|
||||
// 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);
|
||||
|
||||
// Focus.
|
||||
void Focus();
|
||||
void TabTraverse(bool reverse);
|
||||
|
||||
// Send messages to browser.
|
||||
bool SendIPCMessage(const base::string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
// Send WebInputEvent to the page.
|
||||
void SendInputEvent(v8::Isolate* isolate, v8::Local<v8::Value> input_event);
|
||||
|
||||
// Subscribe to the frame updates.
|
||||
void BeginFrameSubscription(
|
||||
const FrameSubscriber::FrameCaptureCallback& callback);
|
||||
void EndFrameSubscription();
|
||||
|
||||
// Methods for creating <webview>.
|
||||
void SetSize(const SetSizeParams& params);
|
||||
void SetAllowTransparency(bool allow);
|
||||
bool IsGuest() const;
|
||||
|
||||
// Returns the web preferences of current WebContents.
|
||||
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
explicit WebContents(content::WebContents* web_contents);
|
||||
WebContents(v8::Isolate* isolate, const mate::Dictionary& options);
|
||||
~WebContents();
|
||||
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
bool IsDestroyed() const 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 std::string& frame_name,
|
||||
const GURL& target_url,
|
||||
const std::string& partition_id,
|
||||
content::SessionStorageNamespace* session_storage_namespace) override;
|
||||
content::WebContents* OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) override;
|
||||
void BeforeUnloadFired(content::WebContents* tab,
|
||||
bool proceed,
|
||||
bool* proceed_to_fire_unload) override;
|
||||
void MoveContents(content::WebContents* source,
|
||||
const gfx::Rect& pos) override;
|
||||
void CloseContents(content::WebContents* source) override;
|
||||
void ActivateContents(content::WebContents* contents) override;
|
||||
bool IsPopupOrPanel(const content::WebContents* source) const 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;
|
||||
void RendererUnresponsive(content::WebContents* source) override;
|
||||
void RendererResponsive(content::WebContents* source) override;
|
||||
|
||||
// content::WebContentsObserver:
|
||||
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
|
||||
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,
|
||||
bool was_ignored_by_handler) override;
|
||||
void DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url,
|
||||
int error_code,
|
||||
const base::string16& error_description,
|
||||
bool was_ignored_by_handler) 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 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;
|
||||
|
||||
private:
|
||||
enum Type {
|
||||
BROWSER_WINDOW, // Used by BrowserWindow.
|
||||
WEB_VIEW, // Used by <webview>.
|
||||
REMOTE, // Thin wrap around an existing WebContents.
|
||||
};
|
||||
|
||||
AtomBrowserContext* GetBrowserContext() const;
|
||||
|
||||
// Called when received a message from renderer.
|
||||
void OnRendererMessage(const base::string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
// Called when received a synchronous message from renderer.
|
||||
void OnRendererMessageSync(const base::string16& channel,
|
||||
const base::ListValue& args,
|
||||
IPC::Message* message);
|
||||
|
||||
v8::Global<v8::Value> session_;
|
||||
|
||||
scoped_ptr<WebViewGuestDelegate> guest_delegate_;
|
||||
|
||||
// The type of current WebContents.
|
||||
Type type_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContents);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_WEB_CONTENTS_H_
|
||||
71
atom/browser/api/atom_api_web_view_manager.cc
Normal file
71
atom/browser/api/atom_api_web_view_manager.cc
Normal file
@@ -0,0 +1,71 @@
|
||||
// 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_contents_preferences.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
using atom::WebContentsPreferences;
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<content::WebContents*> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
content::WebContents** out) {
|
||||
atom::api::WebContents* contents;
|
||||
if (!Converter<atom::api::WebContents*>::FromV8(isolate, val, &contents))
|
||||
return false;
|
||||
*out = contents->web_contents();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace {
|
||||
|
||||
atom::WebViewManager* GetWebViewManager(content::WebContents* web_contents) {
|
||||
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,
|
||||
const base::DictionaryValue& options) {
|
||||
auto manager = GetWebViewManager(embedder);
|
||||
if (manager)
|
||||
manager->AddGuest(guest_instance_id, element_instance_id, embedder,
|
||||
guest_web_contents);
|
||||
|
||||
WebContentsPreferences::FromWebContents(guest_web_contents)->Merge(options);
|
||||
}
|
||||
|
||||
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)
|
||||
651
atom/browser/api/atom_api_window.cc
Normal file
651
atom/browser/api/atom_api_window.cc
Normal file
@@ -0,0 +1,651 @@
|
||||
// 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/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 "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/ui/win/taskbar_host.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<atom::TaskbarHost::ThumbarButton> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||
atom::TaskbarHost::ThumbarButton* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
dict.Get("click", &(out->clicked_callback));
|
||||
dict.Get("tooltip", &(out->tooltip));
|
||||
dict.Get("flags", &out->flags);
|
||||
return dict.Get("icon", &(out->icon));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
void OnCapturePageDone(
|
||||
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(v8::Isolate* isolate, const mate::Dictionary& options) {
|
||||
// Use options['web-preferences'] to create WebContents.
|
||||
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
|
||||
options.Get(switches::kWebPreferences, &web_preferences);
|
||||
|
||||
// Be compatible with old options which are now in web_preferences.
|
||||
v8::Local<v8::Value> value;
|
||||
if (options.Get(switches::kNodeIntegration, &value))
|
||||
web_preferences.Set(switches::kNodeIntegration, value);
|
||||
if (options.Get(switches::kPreloadScript, &value))
|
||||
web_preferences.Set(switches::kPreloadScript, value);
|
||||
if (options.Get(switches::kZoomFactor, &value))
|
||||
web_preferences.Set(switches::kZoomFactor, value);
|
||||
|
||||
// Creates the WebContents used by BrowserWindow.
|
||||
auto web_contents = WebContents::Create(isolate, web_preferences);
|
||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||
api_web_contents_ = web_contents.get();
|
||||
|
||||
// Keep a copy of the options for later use.
|
||||
mate::Dictionary(isolate, web_contents->GetWrapper(isolate)).Set(
|
||||
"browserWindowOptions", options);
|
||||
|
||||
// Creates BrowserWindow.
|
||||
window_.reset(NativeWindow::Create(web_contents->managed_web_contents(),
|
||||
options));
|
||||
web_contents->SetOwnerWindow(window_.get());
|
||||
window_->InitFromOptions(options);
|
||||
window_->AddObserver(this);
|
||||
}
|
||||
|
||||
Window::~Window() {
|
||||
if (window_)
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void Window::OnPageTitleUpdated(bool* prevent_default,
|
||||
const std::string& title) {
|
||||
*prevent_default = Emit("page-title-updated", title);
|
||||
}
|
||||
|
||||
void Window::WillCloseWindow(bool* prevent_default) {
|
||||
*prevent_default = Emit("close");
|
||||
}
|
||||
|
||||
void Window::OnWindowClosed() {
|
||||
if (api_web_contents_) {
|
||||
api_web_contents_->DestroyWebContents();
|
||||
api_web_contents_ = nullptr;
|
||||
web_contents_.Reset();
|
||||
}
|
||||
|
||||
RemoveFromWeakMap();
|
||||
window_->RemoveObserver(this);
|
||||
|
||||
Emit("closed");
|
||||
|
||||
// Clean up the resources after window has been closed.
|
||||
base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release());
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
void Window::OnRendererResponsive() {
|
||||
Emit("responsive");
|
||||
}
|
||||
|
||||
void Window::OnDevToolsFocus() {
|
||||
Emit("devtools-focused");
|
||||
}
|
||||
|
||||
void Window::OnDevToolsOpened() {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto handle = WebContents::CreateFrom(
|
||||
isolate(), api_web_contents_->GetDevToolsWebContents());
|
||||
devtools_web_contents_.Reset(isolate(), handle.ToV8());
|
||||
|
||||
Emit("devtools-opened");
|
||||
}
|
||||
|
||||
void Window::OnDevToolsClosed() {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
devtools_web_contents_.Reset();
|
||||
|
||||
Emit("devtools-closed");
|
||||
}
|
||||
|
||||
void Window::OnExecuteWindowsCommand(const std::string& command_name) {
|
||||
Emit("app-command", command_name);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Wrappable* Window::New(v8::Isolate* isolate,
|
||||
const mate::Dictionary& options) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate, "Cannot create BrowserWindow before app is ready")));
|
||||
return nullptr;
|
||||
}
|
||||
return new Window(isolate, options);
|
||||
}
|
||||
|
||||
bool Window::IsDestroyed() const {
|
||||
return !window_ || window_->IsClosed();
|
||||
}
|
||||
|
||||
void Window::Destroy() {
|
||||
if (window_)
|
||||
window_->CloseContents(nullptr);
|
||||
}
|
||||
|
||||
void Window::Close() {
|
||||
window_->Close();
|
||||
}
|
||||
|
||||
bool Window::IsClosed() {
|
||||
return window_->IsClosed();
|
||||
}
|
||||
|
||||
void Window::Focus() {
|
||||
window_->Focus(true);
|
||||
}
|
||||
|
||||
bool Window::IsFocused() {
|
||||
return window_->IsFocused();
|
||||
}
|
||||
|
||||
void Window::Show() {
|
||||
window_->Show();
|
||||
}
|
||||
|
||||
void Window::ShowInactive() {
|
||||
window_->ShowInactive();
|
||||
}
|
||||
|
||||
void Window::Hide() {
|
||||
window_->Hide();
|
||||
}
|
||||
|
||||
bool Window::IsVisible() {
|
||||
return window_->IsVisible();
|
||||
}
|
||||
|
||||
void Window::Maximize() {
|
||||
window_->Maximize();
|
||||
}
|
||||
|
||||
void Window::Unmaximize() {
|
||||
window_->Unmaximize();
|
||||
}
|
||||
|
||||
bool Window::IsMaximized() {
|
||||
return window_->IsMaximized();
|
||||
}
|
||||
|
||||
void Window::Minimize() {
|
||||
window_->Minimize();
|
||||
}
|
||||
|
||||
void Window::Restore() {
|
||||
window_->Restore();
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
std::vector<int> Window::GetSize() {
|
||||
std::vector<int> result(2);
|
||||
gfx::Size size = window_->GetSize();
|
||||
result[0] = size.width();
|
||||
result[1] = size.height();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Window::SetContentSize(int width, int height) {
|
||||
window_->SetContentSize(gfx::Size(width, height));
|
||||
}
|
||||
|
||||
std::vector<int> Window::GetContentSize() {
|
||||
std::vector<int> result(2);
|
||||
gfx::Size size = window_->GetContentSize();
|
||||
result[0] = size.width();
|
||||
result[1] = size.height();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Window::SetMinimumSize(int width, int height) {
|
||||
window_->SetMinimumSize(gfx::Size(width, height));
|
||||
}
|
||||
|
||||
std::vector<int> Window::GetMinimumSize() {
|
||||
std::vector<int> result(2);
|
||||
gfx::Size size = window_->GetMinimumSize();
|
||||
result[0] = size.width();
|
||||
result[1] = size.height();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Window::SetMaximumSize(int width, int height) {
|
||||
window_->SetMaximumSize(gfx::Size(width, height));
|
||||
}
|
||||
|
||||
std::vector<int> Window::GetMaximumSize() {
|
||||
std::vector<int> result(2);
|
||||
gfx::Size size = window_->GetMaximumSize();
|
||||
result[0] = size.width();
|
||||
result[1] = size.height();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Window::SetResizable(bool resizable) {
|
||||
window_->SetResizable(resizable);
|
||||
}
|
||||
|
||||
bool Window::IsResizable() {
|
||||
return window_->IsResizable();
|
||||
}
|
||||
|
||||
void Window::SetAlwaysOnTop(bool top) {
|
||||
window_->SetAlwaysOnTop(top);
|
||||
}
|
||||
|
||||
bool Window::IsAlwaysOnTop() {
|
||||
return window_->IsAlwaysOnTop();
|
||||
}
|
||||
|
||||
void Window::Center() {
|
||||
window_->Center();
|
||||
}
|
||||
|
||||
void Window::SetPosition(int x, int y) {
|
||||
window_->SetPosition(gfx::Point(x, y));
|
||||
}
|
||||
|
||||
std::vector<int> Window::GetPosition() {
|
||||
std::vector<int> result(2);
|
||||
gfx::Point pos = window_->GetPosition();
|
||||
result[0] = pos.x();
|
||||
result[1] = pos.y();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Window::SetTitle(const std::string& title) {
|
||||
window_->SetTitle(title);
|
||||
}
|
||||
|
||||
std::string Window::GetTitle() {
|
||||
return window_->GetTitle();
|
||||
}
|
||||
|
||||
void Window::FlashFrame(bool flash) {
|
||||
window_->FlashFrame(flash);
|
||||
}
|
||||
|
||||
void Window::SetSkipTaskbar(bool skip) {
|
||||
window_->SetSkipTaskbar(skip);
|
||||
}
|
||||
|
||||
void Window::SetKiosk(bool kiosk) {
|
||||
window_->SetKiosk(kiosk);
|
||||
}
|
||||
|
||||
bool Window::IsKiosk() {
|
||||
return window_->IsKiosk();
|
||||
}
|
||||
|
||||
void Window::FocusOnWebView() {
|
||||
window_->FocusOnWebView();
|
||||
}
|
||||
|
||||
void Window::BlurWebView() {
|
||||
window_->BlurWebView();
|
||||
}
|
||||
|
||||
bool Window::IsWebViewFocused() {
|
||||
return window_->IsWebViewFocused();
|
||||
}
|
||||
|
||||
bool Window::IsDevToolsFocused() {
|
||||
return window_->IsDevToolsFocused();
|
||||
}
|
||||
|
||||
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(const gfx::Image&)> callback;
|
||||
|
||||
if (!(args->Length() == 1 && args->GetNext(&callback)) &&
|
||||
!(args->Length() == 2 && args->GetNext(&rect)
|
||||
&& args->GetNext(&callback))) {
|
||||
args->ThrowError();
|
||||
return;
|
||||
}
|
||||
|
||||
window_->CapturePage(
|
||||
rect, base::Bind(&OnCapturePageDone, args->isolate(), callback));
|
||||
}
|
||||
|
||||
void Window::SetProgressBar(double progress) {
|
||||
window_->SetProgressBar(progress);
|
||||
}
|
||||
|
||||
void Window::SetOverlayIcon(const gfx::Image& overlay,
|
||||
const std::string& description) {
|
||||
window_->SetOverlayIcon(overlay, description);
|
||||
}
|
||||
|
||||
bool Window::SetThumbarButtons(mate::Arguments* args) {
|
||||
#if defined(OS_WIN)
|
||||
std::vector<TaskbarHost::ThumbarButton> buttons;
|
||||
if (!args->GetNext(&buttons)) {
|
||||
args->ThrowError();
|
||||
return false;
|
||||
}
|
||||
auto window = static_cast<NativeWindowViews*>(window_.get());
|
||||
return window->taskbar_host().SetThumbarButtons(
|
||||
window->GetAcceleratedWidget(), buttons);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Window::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
|
||||
mate::Handle<Menu> menu;
|
||||
if (value->IsObject() &&
|
||||
mate::V8ToString(value->ToObject()->GetConstructorName()) == "Menu" &&
|
||||
mate::ConvertFromV8(isolate, value, &menu)) {
|
||||
menu_.Reset(isolate, menu.ToV8());
|
||||
window_->SetMenu(menu->model());
|
||||
} else if (value->IsNull()) {
|
||||
menu_.Reset();
|
||||
window_->SetMenu(nullptr);
|
||||
} else {
|
||||
isolate->ThrowException(v8::Exception::TypeError(
|
||||
mate::StringToV8(isolate, "Invalid 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::SetAspectRatio(double aspect_ratio, mate::Arguments* args) {
|
||||
gfx::Size extra_size;
|
||||
args->GetNext(&extra_size);
|
||||
window_->SetAspectRatio(aspect_ratio, extra_size);
|
||||
}
|
||||
|
||||
void Window::SetVisibleOnAllWorkspaces(bool visible) {
|
||||
return window_->SetVisibleOnAllWorkspaces(visible);
|
||||
}
|
||||
|
||||
bool Window::IsVisibleOnAllWorkspaces() {
|
||||
return window_->IsVisibleOnAllWorkspaces();
|
||||
}
|
||||
|
||||
int32_t Window::ID() const {
|
||||
return weak_map_id();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Window::WebContents(v8::Isolate* isolate) {
|
||||
if (web_contents_.IsEmpty())
|
||||
return v8::Null(isolate);
|
||||
else
|
||||
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::Local<v8::ObjectTemplate> prototype) {
|
||||
mate::ObjectTemplateBuilder(isolate, prototype)
|
||||
.SetMethod("destroy", &Window::Destroy, true)
|
||||
.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("isMinimized", &Window::IsMinimized)
|
||||
.SetMethod("setFullScreen", &Window::SetFullScreen)
|
||||
.SetMethod("isFullScreen", &Window::IsFullscreen)
|
||||
.SetMethod("setAspectRatio", &Window::SetAspectRatio)
|
||||
.SetMethod("getBounds", &Window::GetBounds)
|
||||
.SetMethod("setBounds", &Window::SetBounds)
|
||||
.SetMethod("getSize", &Window::GetSize)
|
||||
.SetMethod("setSize", &Window::SetSize)
|
||||
.SetMethod("getContentSize", &Window::GetContentSize)
|
||||
.SetMethod("setContentSize", &Window::SetContentSize)
|
||||
.SetMethod("setMinimumSize", &Window::SetMinimumSize)
|
||||
.SetMethod("getMinimumSize", &Window::GetMinimumSize)
|
||||
.SetMethod("setMaximumSize", &Window::SetMaximumSize)
|
||||
.SetMethod("getMaximumSize", &Window::GetMaximumSize)
|
||||
.SetMethod("setResizable", &Window::SetResizable)
|
||||
.SetMethod("isResizable", &Window::IsResizable)
|
||||
.SetMethod("setAlwaysOnTop", &Window::SetAlwaysOnTop)
|
||||
.SetMethod("isAlwaysOnTop", &Window::IsAlwaysOnTop)
|
||||
.SetMethod("center", &Window::Center)
|
||||
.SetMethod("setPosition", &Window::SetPosition)
|
||||
.SetMethod("getPosition", &Window::GetPosition)
|
||||
.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("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("isDevToolsFocused", &Window::IsDevToolsFocused)
|
||||
.SetMethod("capturePage", &Window::CapturePage)
|
||||
.SetMethod("setProgressBar", &Window::SetProgressBar)
|
||||
.SetMethod("setOverlayIcon", &Window::SetOverlayIcon)
|
||||
.SetMethod("setThumbarButtons", &Window::SetThumbarButtons)
|
||||
.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("id", &Window::ID, true)
|
||||
.SetProperty("webContents", &Window::WebContents, true)
|
||||
.SetProperty("devToolsWebContents", &Window::DevToolsWebContents, true);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
using atom::api::Window;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::Local<v8::Function> constructor = mate::CreateConstructor<Window>(
|
||||
isolate, "BrowserWindow", base::Bind(&Window::New));
|
||||
mate::Dictionary browser_window(isolate, constructor);
|
||||
browser_window.SetMethod("fromId",
|
||||
&mate::TrackableObject<Window>::FromWeakMapID);
|
||||
browser_window.SetMethod("getAllWindows",
|
||||
&mate::TrackableObject<Window>::GetAll);
|
||||
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("BrowserWindow", browser_window);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_window, Initialize)
|
||||
193
atom/browser/api/atom_api_window.h
Normal file
193
atom/browser/api/atom_api_window.h
Normal file
@@ -0,0 +1,193 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_WINDOW_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_WINDOW_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/native_window_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
class GURL;
|
||||
|
||||
namespace gfx {
|
||||
class Rect;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class NativeWindow;
|
||||
|
||||
namespace api {
|
||||
|
||||
class WebContents;
|
||||
|
||||
class Window : public mate::TrackableObject<Window>,
|
||||
public NativeWindowObserver {
|
||||
public:
|
||||
static mate::Wrappable* New(v8::Isolate* isolate,
|
||||
const mate::Dictionary& options);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
NativeWindow* window() const { return window_.get(); }
|
||||
|
||||
protected:
|
||||
Window(v8::Isolate* isolate, const mate::Dictionary& options);
|
||||
virtual ~Window();
|
||||
|
||||
// NativeWindowObserver:
|
||||
void OnPageTitleUpdated(bool* prevent_default,
|
||||
const std::string& title) 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;
|
||||
void OnExecuteWindowsCommand(const std::string& command_name) override;
|
||||
|
||||
// mate::Wrappable:
|
||||
bool IsDestroyed() const override;
|
||||
|
||||
private:
|
||||
// mate::TrackableObject:
|
||||
void Destroy() override;
|
||||
|
||||
// APIs for NativeWindow.
|
||||
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();
|
||||
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);
|
||||
std::vector<int> GetContentSize();
|
||||
void SetMinimumSize(int width, int height);
|
||||
std::vector<int> GetMinimumSize();
|
||||
void SetMaximumSize(int width, int height);
|
||||
std::vector<int> GetMaximumSize();
|
||||
void SetResizable(bool resizable);
|
||||
bool IsResizable();
|
||||
void SetAlwaysOnTop(bool top);
|
||||
bool IsAlwaysOnTop();
|
||||
void Center();
|
||||
void SetPosition(int x, int y);
|
||||
std::vector<int> GetPosition();
|
||||
void SetTitle(const std::string& title);
|
||||
std::string GetTitle();
|
||||
void FlashFrame(bool flash);
|
||||
void SetSkipTaskbar(bool skip);
|
||||
void SetKiosk(bool kiosk);
|
||||
bool IsKiosk();
|
||||
void FocusOnWebView();
|
||||
void BlurWebView();
|
||||
bool IsWebViewFocused();
|
||||
bool IsDevToolsFocused();
|
||||
void SetRepresentedFilename(const std::string& filename);
|
||||
std::string GetRepresentedFilename();
|
||||
void SetDocumentEdited(bool edited);
|
||||
bool IsDocumentEdited();
|
||||
void CapturePage(mate::Arguments* args);
|
||||
void SetProgressBar(double progress);
|
||||
void SetOverlayIcon(const gfx::Image& overlay,
|
||||
const std::string& description);
|
||||
bool SetThumbarButtons(mate::Arguments* args);
|
||||
void SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> menu);
|
||||
void SetAutoHideMenuBar(bool auto_hide);
|
||||
bool IsMenuBarAutoHide();
|
||||
void SetMenuBarVisibility(bool visible);
|
||||
bool IsMenuBarVisible();
|
||||
void SetAspectRatio(double aspect_ratio, mate::Arguments* args);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void ShowDefinitionForSelection();
|
||||
#endif
|
||||
|
||||
void SetVisibleOnAllWorkspaces(bool visible);
|
||||
bool IsVisibleOnAllWorkspaces();
|
||||
|
||||
int32_t ID() const;
|
||||
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_;
|
||||
v8::Global<v8::Value> menu_;
|
||||
|
||||
api::WebContents* api_web_contents_;
|
||||
|
||||
scoped_ptr<NativeWindow> window_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Window);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<atom::NativeWindow*> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
atom::NativeWindow** out) {
|
||||
// null would be tranfered to NULL.
|
||||
if (val->IsNull()) {
|
||||
*out = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
atom::api::Window* window;
|
||||
if (!Converter<atom::api::Window*>::FromV8(isolate, val, &window))
|
||||
return false;
|
||||
*out = window->window();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_WINDOW_H_
|
||||
72
atom/browser/api/event.cc
Normal file
72
atom/browser/api/event.cc
Normal file
@@ -0,0 +1,72 @@
|
||||
// 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.h"
|
||||
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace {
|
||||
|
||||
v8::Persistent<v8::ObjectTemplate> template_;
|
||||
|
||||
} // namespace
|
||||
|
||||
Event::Event()
|
||||
: sender_(NULL),
|
||||
message_(NULL) {
|
||||
}
|
||||
|
||||
Event::~Event() {
|
||||
}
|
||||
|
||||
ObjectTemplateBuilder Event::GetObjectTemplateBuilder(v8::Isolate* isolate) {
|
||||
if (template_.IsEmpty())
|
||||
template_.Reset(isolate, ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("preventDefault", &Event::PreventDefault)
|
||||
.SetMethod("sendReply", &Event::SendReply)
|
||||
.Build());
|
||||
|
||||
return ObjectTemplateBuilder(
|
||||
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
|
||||
}
|
||||
|
||||
void Event::SetSenderAndMessage(content::WebContents* sender,
|
||||
IPC::Message* message) {
|
||||
DCHECK(!sender_);
|
||||
DCHECK(!message_);
|
||||
sender_ = sender;
|
||||
message_ = message;
|
||||
|
||||
Observe(sender);
|
||||
}
|
||||
|
||||
void Event::WebContentsDestroyed() {
|
||||
sender_ = NULL;
|
||||
message_ = NULL;
|
||||
}
|
||||
|
||||
void Event::PreventDefault(v8::Isolate* isolate) {
|
||||
GetWrapper(isolate)->Set(StringToV8(isolate, "defaultPrevented"),
|
||||
v8::True(isolate));
|
||||
}
|
||||
|
||||
bool Event::SendReply(const base::string16& json) {
|
||||
if (message_ == NULL || sender_ == NULL)
|
||||
return false;
|
||||
|
||||
AtomViewHostMsg_Message_Sync::WriteReplyParams(message_, json);
|
||||
return sender_->Send(message_);
|
||||
}
|
||||
|
||||
// static
|
||||
Handle<Event> Event::Create(v8::Isolate* isolate) {
|
||||
return CreateHandle(isolate, new Event);
|
||||
}
|
||||
|
||||
} // namespace mate
|
||||
52
atom/browser/api/event.h
Normal file
52
atom/browser/api/event.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_API_EVENT_H_
|
||||
#define ATOM_BROWSER_API_EVENT_H_
|
||||
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace IPC {
|
||||
class Message;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
|
||||
class Event : public Wrappable,
|
||||
public content::WebContentsObserver {
|
||||
public:
|
||||
static Handle<Event> Create(v8::Isolate* isolate);
|
||||
|
||||
// Pass the sender and message to be replied.
|
||||
void SetSenderAndMessage(content::WebContents* sender, IPC::Message* message);
|
||||
|
||||
// event.PreventDefault().
|
||||
void PreventDefault(v8::Isolate* isolate);
|
||||
|
||||
// event.sendReply(json), used for replying synchronous message.
|
||||
bool SendReply(const base::string16& json);
|
||||
|
||||
protected:
|
||||
Event();
|
||||
virtual ~Event();
|
||||
|
||||
// Wrappable implementations:
|
||||
ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) override;
|
||||
|
||||
// content::WebContentsObserver implementations:
|
||||
void WebContentsDestroyed() override;
|
||||
|
||||
private:
|
||||
// Replyer for the synchronous messages.
|
||||
content::WebContents* sender_;
|
||||
IPC::Message* message_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Event);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_BROWSER_API_EVENT_H_
|
||||
64
atom/browser/api/event_emitter.cc
Normal file
64
atom/browser/api/event_emitter.cc
Normal file
@@ -0,0 +1,64 @@
|
||||
// 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 "atom/browser/api/event.h"
|
||||
#include "native_mate/arguments.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace {
|
||||
|
||||
v8::Persistent<v8::ObjectTemplate> event_template;
|
||||
|
||||
void PreventDefault(mate::Arguments* args) {
|
||||
mate::Dictionary self(args->isolate(), args->GetThis());
|
||||
self.Set("defaultPrevented", true);
|
||||
}
|
||||
|
||||
// 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() {
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> EventEmitter::CreateJSEvent(
|
||||
v8::Isolate* isolate, content::WebContents* sender, IPC::Message* message) {
|
||||
v8::Local<v8::Object> event;
|
||||
bool use_native_event = sender && message;
|
||||
|
||||
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);
|
||||
}
|
||||
mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate));
|
||||
return event;
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> EventEmitter::CreateCustomEvent(
|
||||
v8::Isolate* isolate, v8::Local<v8::Object> custom_event) {
|
||||
v8::Local<v8::Object> event = CreateEventObject(isolate);
|
||||
(void)event->SetPrototype(custom_event->CreationContext(), custom_event);
|
||||
mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate));
|
||||
return event;
|
||||
}
|
||||
|
||||
} // namespace mate
|
||||
81
atom/browser/api/event_emitter.h
Normal file
81
atom/browser/api/event_emitter.h
Normal file
@@ -0,0 +1,81 @@
|
||||
// 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 <vector>
|
||||
|
||||
#include "atom/common/api/event_emitter_caller.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
|
||||
namespace content {
|
||||
class WebContents;
|
||||
}
|
||||
|
||||
namespace IPC {
|
||||
class Message;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
|
||||
// Provide helperers to emit event in JavaScript.
|
||||
class EventEmitter : public Wrappable {
|
||||
public:
|
||||
typedef std::vector<v8::Local<v8::Value>> ValueArray;
|
||||
|
||||
// this.emit(name, event, args...);
|
||||
template<typename... Args>
|
||||
bool EmitCustomEvent(const base::StringPiece& name,
|
||||
v8::Local<v8::Object> event,
|
||||
const Args&... args) {
|
||||
return EmitWithEvent(name, CreateCustomEvent(isolate(), event), args...);
|
||||
}
|
||||
|
||||
// this.emit(name, new Event(), 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...);
|
||||
template<typename... Args>
|
||||
bool EmitWithSender(const base::StringPiece& name,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message,
|
||||
const Args&... args) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
v8::Local<v8::Object> event = CreateJSEvent(isolate(), sender, message);
|
||||
return EmitWithEvent(name, event, args...);
|
||||
}
|
||||
|
||||
protected:
|
||||
EventEmitter();
|
||||
|
||||
private:
|
||||
// this.emit(name, event, args...);
|
||||
template<typename... Args>
|
||||
bool EmitWithEvent(const base::StringPiece& name,
|
||||
v8::Local<v8::Object> event,
|
||||
const Args&... args) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
EmitEvent(isolate(), GetWrapper(isolate()), name, event, args...);
|
||||
return event->Get(
|
||||
StringToV8(isolate(), "defaultPrevented"))->BooleanValue();
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message);
|
||||
v8::Local<v8::Object> CreateCustomEvent(
|
||||
v8::Isolate* isolate, v8::Local<v8::Object> event);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(EventEmitter);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_BROWSER_API_EVENT_EMITTER_H_
|
||||
66
atom/browser/api/frame_subscriber.cc
Normal file
66
atom/browser/api/frame_subscriber.cc
Normal file
@@ -0,0 +1,66 @@
|
||||
// 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/frame_subscriber.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/bind.h"
|
||||
#include "media/base/video_frame.h"
|
||||
#include "media/base/yuv_convert.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
FrameSubscriber::FrameSubscriber(v8::Isolate* isolate,
|
||||
const gfx::Size& size,
|
||||
const FrameCaptureCallback& callback)
|
||||
: isolate_(isolate), size_(size), callback_(callback) {
|
||||
}
|
||||
|
||||
bool FrameSubscriber::ShouldCaptureFrame(
|
||||
const gfx::Rect& damage_rect,
|
||||
base::TimeTicks present_time,
|
||||
scoped_refptr<media::VideoFrame>* storage,
|
||||
DeliverFrameCallback* callback) {
|
||||
*storage = media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_,
|
||||
gfx::Rect(size_), size_,
|
||||
base::TimeDelta());
|
||||
*callback = base::Bind(&FrameSubscriber::OnFrameDelivered,
|
||||
base::Unretained(this),
|
||||
*storage);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FrameSubscriber::OnFrameDelivered(
|
||||
scoped_refptr<media::VideoFrame> frame, base::TimeTicks, bool result) {
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
gfx::Rect rect = frame->visible_rect();
|
||||
size_t rgb_arr_size = rect.width() * rect.height() * 4;
|
||||
v8::MaybeLocal<v8::Object> buffer = node::Buffer::New(isolate_, rgb_arr_size);
|
||||
if (buffer.IsEmpty())
|
||||
return;
|
||||
|
||||
// Convert a frame of YUV to 32 bit ARGB.
|
||||
media::ConvertYUVToRGB32(frame->data(media::VideoFrame::kYPlane),
|
||||
frame->data(media::VideoFrame::kUPlane),
|
||||
frame->data(media::VideoFrame::kVPlane),
|
||||
reinterpret_cast<uint8*>(
|
||||
node::Buffer::Data(buffer.ToLocalChecked())),
|
||||
rect.width(), rect.height(),
|
||||
frame->stride(media::VideoFrame::kYPlane),
|
||||
frame->stride(media::VideoFrame::kUVPlane),
|
||||
rect.width() * 4,
|
||||
media::YV12);
|
||||
|
||||
v8::Locker locker(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
callback_.Run(buffer.ToLocalChecked());
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
45
atom/browser/api/frame_subscriber.h
Normal file
45
atom/browser/api/frame_subscriber.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// 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_FRAME_SUBSCRIBER_H_
|
||||
#define ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
|
||||
#include "ui/gfx/geometry/size.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber {
|
||||
public:
|
||||
using FrameCaptureCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
|
||||
FrameSubscriber(v8::Isolate* isolate,
|
||||
const gfx::Size& size,
|
||||
const FrameCaptureCallback& callback);
|
||||
|
||||
bool ShouldCaptureFrame(const gfx::Rect& damage_rect,
|
||||
base::TimeTicks present_time,
|
||||
scoped_refptr<media::VideoFrame>* storage,
|
||||
DeliverFrameCallback* callback) override;
|
||||
|
||||
private:
|
||||
void OnFrameDelivered(
|
||||
scoped_refptr<media::VideoFrame> frame, base::TimeTicks, bool);
|
||||
|
||||
v8::Isolate* isolate_;
|
||||
gfx::Size size_;
|
||||
FrameCaptureCallback callback_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(FrameSubscriber);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_
|
||||
68
atom/browser/api/lib/app.coffee
Normal file
68
atom/browser/api/lib/app.coffee
Normal file
@@ -0,0 +1,68 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
bindings = process.atomBinding 'app'
|
||||
sessionBindings = process.atomBinding 'session'
|
||||
downloadItemBindings = process.atomBinding 'download_item'
|
||||
|
||||
app = bindings.app
|
||||
app.__proto__ = EventEmitter.prototype
|
||||
|
||||
wrapSession = (session) ->
|
||||
# session is an Event Emitter.
|
||||
session.__proto__ = EventEmitter.prototype
|
||||
|
||||
wrapDownloadItem = (download_item) ->
|
||||
# download_item is an Event Emitter.
|
||||
download_item.__proto__ = EventEmitter.prototype
|
||||
# Be compatible with old APIs.
|
||||
download_item.url = download_item.getUrl()
|
||||
download_item.filename = download_item.getFilename()
|
||||
download_item.mimeType = download_item.getMimeType()
|
||||
download_item.hasUserGesture = download_item.hasUserGesture()
|
||||
|
||||
app.setApplicationMenu = (menu) ->
|
||||
require('menu').setApplicationMenu menu
|
||||
|
||||
app.getApplicationMenu = ->
|
||||
require('menu').getApplicationMenu()
|
||||
|
||||
app.commandLine =
|
||||
appendSwitch: bindings.appendSwitch,
|
||||
appendArgument: bindings.appendArgument
|
||||
|
||||
if process.platform is 'darwin'
|
||||
app.dock =
|
||||
bounce: (type='informational') -> bindings.dockBounce type
|
||||
cancelBounce: bindings.dockCancelBounce
|
||||
setBadge: bindings.dockSetBadgeText
|
||||
getBadge: bindings.dockGetBadgeText
|
||||
hide: bindings.dockHide
|
||||
show: bindings.dockShow
|
||||
setMenu: bindings.dockSetMenu
|
||||
|
||||
appPath = null
|
||||
app.setAppPath = (path) ->
|
||||
appPath = path
|
||||
|
||||
app.getAppPath = ->
|
||||
appPath
|
||||
|
||||
# Be compatible with old API.
|
||||
app.once 'ready', -> @emit 'finish-launching'
|
||||
app.terminate = app.quit
|
||||
app.exit = process.exit
|
||||
app.getHomeDir = -> @getPath 'home'
|
||||
app.getDataPath = -> @getPath 'userData'
|
||||
app.setDataPath = (path) -> @setPath 'userData', path
|
||||
app.resolveProxy = -> @defaultSession.resolveProxy.apply @defaultSession, arguments
|
||||
app.on 'activate', (event, hasVisibleWindows) -> @emit 'activate-with-no-open-windows' if not hasVisibleWindows
|
||||
|
||||
# Session wrapper.
|
||||
sessionBindings._setWrapSession wrapSession
|
||||
process.once 'exit', sessionBindings._clearWrapSession
|
||||
|
||||
downloadItemBindings._setWrapDownloadItem wrapDownloadItem
|
||||
process.once 'exit', downloadItemBindings._clearWrapDownloadItem
|
||||
|
||||
# Only one App object pemitted.
|
||||
module.exports = app
|
||||
6
atom/browser/api/lib/atom-delegate.coffee
Normal file
6
atom/browser/api/lib/atom-delegate.coffee
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports =
|
||||
browserMainParts:
|
||||
preMainMessageLoopRun: ->
|
||||
|
||||
setImmediate ->
|
||||
module.exports.browserMainParts.preMainMessageLoopRun()
|
||||
24
atom/browser/api/lib/auto-updater.coffee
Normal file
24
atom/browser/api/lib/auto-updater.coffee
Normal file
@@ -0,0 +1,24 @@
|
||||
autoUpdater = process.atomBinding('auto_updater').autoUpdater
|
||||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
autoUpdater.__proto__ = EventEmitter.prototype
|
||||
|
||||
autoUpdater.on 'update-downloaded-raw', (args...) ->
|
||||
args[3] = new Date(args[3]) # releaseDate
|
||||
@emit 'update-downloaded', args..., => @quitAndInstall()
|
||||
|
||||
autoUpdater.quitAndInstall = ->
|
||||
# If we don't have any window then quitAndInstall immediately.
|
||||
BrowserWindow = require 'browser-window'
|
||||
windows = BrowserWindow.getAllWindows()
|
||||
if windows.length is 0
|
||||
@_quitAndInstall()
|
||||
return
|
||||
|
||||
# Do the restart after all windows have been closed.
|
||||
app = require 'app'
|
||||
app.removeAllListeners 'window-all-closed'
|
||||
app.once 'window-all-closed', @_quitAndInstall.bind(this)
|
||||
win.close() for win in windows
|
||||
|
||||
module.exports = autoUpdater
|
||||
93
atom/browser/api/lib/browser-window.coffee
Normal file
93
atom/browser/api/lib/browser-window.coffee
Normal file
@@ -0,0 +1,93 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
app = require 'app'
|
||||
ipc = require 'ipc'
|
||||
|
||||
BrowserWindow = process.atomBinding('window').BrowserWindow
|
||||
BrowserWindow::__proto__ = EventEmitter.prototype
|
||||
|
||||
BrowserWindow::_init = ->
|
||||
# Simulate the application menu on platforms other than OS X.
|
||||
if process.platform isnt 'darwin'
|
||||
menu = app.getApplicationMenu()
|
||||
@setMenu menu if menu?
|
||||
|
||||
# Make new windows requested by links behave like "window.open"
|
||||
@webContents.on '-new-window', (event, url, frameName) ->
|
||||
options = show: true, width: 800, height: 600
|
||||
ipc.emit 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, options
|
||||
|
||||
# window.resizeTo(...)
|
||||
# window.moveTo(...)
|
||||
@webContents.on 'move', (event, size) =>
|
||||
@setBounds size
|
||||
|
||||
# Hide the auto-hide menu when webContents is focused.
|
||||
@webContents.on 'activate', =>
|
||||
if process.platform isnt 'darwin' and @isMenuBarAutoHide() and @isMenuBarVisible()
|
||||
@setMenuBarVisibility false
|
||||
|
||||
# Forward the crashed event.
|
||||
@webContents.on 'crashed', =>
|
||||
@emit 'crashed'
|
||||
|
||||
# Sometimes the webContents doesn't get focus when window is shown, so we have
|
||||
# to force focusing on webContents in this case. The safest way is to focus it
|
||||
# when we first start to load URL, if we do it earlier it won't have effect,
|
||||
# if we do it later we might move focus in the page.
|
||||
# Though this hack is only needed on OS X when the app is launched from
|
||||
# Finder, we still do it on all platforms in case of other bugs we don't know.
|
||||
@webContents.once 'load-url', ->
|
||||
@focus()
|
||||
|
||||
# Redirect focus/blur event to app instance too.
|
||||
@on 'blur', (event) =>
|
||||
app.emit 'browser-window-blur', event, this
|
||||
@on 'focus', (event) =>
|
||||
app.emit 'browser-window-focus', event, this
|
||||
|
||||
# Notify the creation of the window.
|
||||
app.emit 'browser-window-created', {}, this
|
||||
|
||||
BrowserWindow.getFocusedWindow = ->
|
||||
windows = BrowserWindow.getAllWindows()
|
||||
return window for window in windows when window.isFocused()
|
||||
|
||||
BrowserWindow.fromWebContents = (webContents) ->
|
||||
windows = BrowserWindow.getAllWindows()
|
||||
return window for window in windows when window.webContents?.equal webContents
|
||||
|
||||
BrowserWindow.fromDevToolsWebContents = (webContents) ->
|
||||
windows = BrowserWindow.getAllWindows()
|
||||
return window for window in windows when window.devToolsWebContents?.equal webContents
|
||||
|
||||
# Helpers.
|
||||
BrowserWindow::loadUrl = -> @webContents.loadUrl.apply @webContents, arguments
|
||||
BrowserWindow::send = -> @webContents.send.apply @webContents, arguments
|
||||
|
||||
# Be compatible with old API.
|
||||
BrowserWindow::undo = -> @webContents.undo()
|
||||
BrowserWindow::redo = -> @webContents.redo()
|
||||
BrowserWindow::cut = -> @webContents.cut()
|
||||
BrowserWindow::copy = -> @webContents.copy()
|
||||
BrowserWindow::paste = -> @webContents.paste()
|
||||
BrowserWindow::selectAll = -> @webContents.selectAll()
|
||||
BrowserWindow::restart = -> @webContents.reload()
|
||||
BrowserWindow::getUrl = -> @webContents.getUrl()
|
||||
BrowserWindow::reload = -> @webContents.reload.apply @webContents, arguments
|
||||
BrowserWindow::reloadIgnoringCache = -> @webContents.reloadIgnoringCache.apply @webContents, arguments
|
||||
BrowserWindow::getPageTitle = -> @webContents.getTitle()
|
||||
BrowserWindow::isLoading = -> @webContents.isLoading()
|
||||
BrowserWindow::isWaitingForResponse = -> @webContents.isWaitingForResponse()
|
||||
BrowserWindow::stop = -> @webContents.stop()
|
||||
BrowserWindow::isCrashed = -> @webContents.isCrashed()
|
||||
BrowserWindow::executeJavaScriptInDevTools = (code) -> @devToolsWebContents?.executeJavaScript code
|
||||
BrowserWindow::openDevTools = -> @webContents.openDevTools.apply @webContents, arguments
|
||||
BrowserWindow::closeDevTools = -> @webContents.closeDevTools()
|
||||
BrowserWindow::isDevToolsOpened = -> @webContents.isDevToolsOpened()
|
||||
BrowserWindow::toggleDevTools = -> @webContents.toggleDevTools()
|
||||
BrowserWindow::inspectElement = -> @webContents.inspectElement.apply @webContents, arguments
|
||||
BrowserWindow::inspectServiceWorker = -> @webContents.inspectServiceWorker()
|
||||
BrowserWindow::print = -> @webContents.print.apply @webContents, arguments
|
||||
BrowserWindow::printToPDF = -> @webContents.printToPDF.apply @webContents, arguments
|
||||
|
||||
module.exports = BrowserWindow
|
||||
1
atom/browser/api/lib/content-tracing.coffee
Normal file
1
atom/browser/api/lib/content-tracing.coffee
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = process.atomBinding 'content_tracing'
|
||||
125
atom/browser/api/lib/dialog.coffee
Normal file
125
atom/browser/api/lib/dialog.coffee
Normal file
@@ -0,0 +1,125 @@
|
||||
binding = process.atomBinding 'dialog'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
app = require 'app'
|
||||
BrowserWindow = require 'browser-window'
|
||||
|
||||
fileDialogProperties =
|
||||
openFile: 1 << 0
|
||||
openDirectory: 1 << 1
|
||||
multiSelections: 1 << 2
|
||||
createDirectory: 1 << 3
|
||||
|
||||
messageBoxTypes = ['none', 'info', 'warning', 'error', 'question']
|
||||
|
||||
messageBoxOptions =
|
||||
noLink: 1 << 0
|
||||
|
||||
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: (args...) ->
|
||||
checkAppInitialized()
|
||||
[window, options, callback] = parseArgs args...
|
||||
|
||||
options ?= title: 'Open', properties: ['openFile']
|
||||
options.properties ?= ['openFile']
|
||||
throw new TypeError('Properties need to be array') unless Array.isArray options.properties
|
||||
|
||||
properties = 0
|
||||
for prop, value of fileDialogProperties
|
||||
properties |= value if prop in options.properties
|
||||
|
||||
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,
|
||||
wrappedCallback
|
||||
|
||||
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,
|
||||
wrappedCallback
|
||||
|
||||
showMessageBox: (args...) ->
|
||||
checkAppInitialized()
|
||||
[window, options, callback] = parseArgs args...
|
||||
|
||||
options ?= type: 'none'
|
||||
options.type ?= 'none'
|
||||
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
|
||||
|
||||
# Choose a default button to get selected when dialog is cancelled.
|
||||
unless options.cancelId?
|
||||
options.cancelId = 0
|
||||
for text, i in options.buttons
|
||||
if text.toLowerCase() in ['cancel', 'no']
|
||||
options.cancelId = i
|
||||
break
|
||||
|
||||
flags = if options.noLink then messageBoxOptions.noLink else 0
|
||||
|
||||
binding.showMessageBox messageBoxType,
|
||||
options.buttons,
|
||||
options.cancelId,
|
||||
flags,
|
||||
options.title,
|
||||
options.message,
|
||||
options.detail,
|
||||
options.icon,
|
||||
window,
|
||||
callback
|
||||
|
||||
showErrorBox: (args...) ->
|
||||
binding.showErrorBox args...
|
||||
|
||||
# Mark standard asynchronous functions.
|
||||
for api in ['showMessageBox', 'showOpenDialog', 'showSaveDialog']
|
||||
v8Util.setHiddenValue module.exports[api], 'asynchronous', true
|
||||
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
|
||||
3
atom/browser/api/lib/ipc.coffee
Normal file
3
atom/browser/api/lib/ipc.coffee
Normal file
@@ -0,0 +1,3 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
module.exports = new EventEmitter
|
||||
63
atom/browser/api/lib/menu-item.coffee
Normal file
63
atom/browser/api/lib/menu-item.coffee
Normal file
@@ -0,0 +1,63 @@
|
||||
BrowserWindow = require 'browser-window'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
|
||||
nextCommandId = 0
|
||||
|
||||
# Maps role to methods of webContents
|
||||
rolesMap =
|
||||
undo: 'undo'
|
||||
redo: 'redo'
|
||||
cut: 'cut'
|
||||
copy: 'copy'
|
||||
paste: 'paste'
|
||||
selectall: 'selectAll'
|
||||
minimize: 'minimize'
|
||||
close: 'close'
|
||||
|
||||
class MenuItem
|
||||
@types = ['normal', 'separator', 'submenu', 'checkbox', 'radio']
|
||||
|
||||
constructor: (options) ->
|
||||
Menu = require 'menu'
|
||||
|
||||
{click, @selector, @type, @role, @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
|
||||
|
||||
@overrideReadOnlyProperty 'type', 'normal'
|
||||
@overrideReadOnlyProperty 'role'
|
||||
@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 #{@type}") if MenuItem.types.indexOf(@type) is -1
|
||||
|
||||
@commandId = ++nextCommandId
|
||||
@click = (focusedWindow) =>
|
||||
# Manually flip the checked flags when clicked.
|
||||
@checked = !@checked if @type in ['checkbox', 'radio']
|
||||
|
||||
if @role and rolesMap[@role] and process.platform isnt 'darwin'
|
||||
focusedWindow?[rolesMap[@role]]()
|
||||
else if typeof click is 'function'
|
||||
click this, focusedWindow
|
||||
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
|
||||
176
atom/browser/api/lib/menu.coffee
Normal file
176
atom/browser/api/lib/menu.coffee
Normal file
@@ -0,0 +1,176 @@
|
||||
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
|
||||
|
||||
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 BrowserWindow.getFocusedWindow()
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
Menu::insert = (pos, item) ->
|
||||
throw new TypeError('Invalid item') unless item?.constructor is MenuItem
|
||||
|
||||
switch item.type
|
||||
when 'normal' then @insertItem pos, item.commandId, item.label
|
||||
when 'checkbox' then @insertCheckItem pos, item.commandId, item.label
|
||||
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?
|
||||
@setRole pos, item.role if item.role?
|
||||
|
||||
# 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 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()
|
||||
w.setMenu menu for w in windows
|
||||
|
||||
Menu.getApplicationMenu = -> applicationMenu
|
||||
|
||||
Menu.sendActionToFirstResponder = bindings.sendActionToFirstResponder
|
||||
|
||||
Menu.buildFromTemplate = (template) ->
|
||||
throw new TypeError('Invalid template for Menu') unless Array.isArray template
|
||||
|
||||
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
|
||||
|
||||
module.exports = Menu
|
||||
122
atom/browser/api/lib/navigation-controller.coffee
Normal file
122
atom/browser/api/lib/navigation-controller.coffee
Normal file
@@ -0,0 +1,122 @@
|
||||
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 may have already navigated to a page.
|
||||
if @webContents._getUrl()
|
||||
@currentIndex++
|
||||
@history.push @webContents._getUrl()
|
||||
|
||||
@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
|
||||
@webContents.emit 'load-url', 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
|
||||
6
atom/browser/api/lib/power-monitor.coffee
Normal file
6
atom/browser/api/lib/power-monitor.coffee
Normal file
@@ -0,0 +1,6 @@
|
||||
powerMonitor = process.atomBinding('power_monitor').powerMonitor
|
||||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
powerMonitor.__proto__ = EventEmitter.prototype
|
||||
|
||||
module.exports = powerMonitor
|
||||
3
atom/browser/api/lib/power-save-blocker.coffee
Normal file
3
atom/browser/api/lib/power-save-blocker.coffee
Normal file
@@ -0,0 +1,3 @@
|
||||
bindings = process.atomBinding 'power_save_blocker'
|
||||
|
||||
module.exports = bindings.powerSaveBlocker
|
||||
24
atom/browser/api/lib/protocol.coffee
Normal file
24
atom/browser/api/lib/protocol.coffee
Normal file
@@ -0,0 +1,24 @@
|
||||
app = require 'app'
|
||||
throw new Error('Can not initialize protocol module before app is ready') unless app.isReady()
|
||||
|
||||
protocol = process.atomBinding('protocol').protocol
|
||||
|
||||
# Warn about removed APIs.
|
||||
logAndThrow = (callback, message) ->
|
||||
console.error message
|
||||
if callback then callback(new Error(message)) else throw new Error(message)
|
||||
protocol.registerProtocol = (scheme, handler, callback) ->
|
||||
logAndThrow callback,
|
||||
'registerProtocol API has been replaced by the
|
||||
register[File/Http/Buffer/String]Protocol API family, please
|
||||
switch to the new APIs.'
|
||||
protocol.isHandledProtocol = (scheme, callback) ->
|
||||
logAndThrow callback,
|
||||
'isHandledProtocol API has been replaced by isProtocolHandled.'
|
||||
protocol.interceptProtocol = (scheme, handler, callback) ->
|
||||
logAndThrow callback,
|
||||
'interceptProtocol API has been replaced by the
|
||||
intercept[File/Http/Buffer/String]Protocol API family, please
|
||||
switch to the new APIs.'
|
||||
|
||||
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
|
||||
14
atom/browser/api/lib/tray.coffee
Normal file
14
atom/browser/api/lib/tray.coffee
Normal file
@@ -0,0 +1,14 @@
|
||||
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.
|
||||
|
||||
# Keep compatibility with old APIs.
|
||||
Tray::popContextMenu = Tray::popUpContextMenu
|
||||
|
||||
module.exports = Tray
|
||||
112
atom/browser/api/lib/web-contents.coffee
Normal file
112
atom/browser/api/lib/web-contents.coffee
Normal file
@@ -0,0 +1,112 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
NavigationController = require './navigation-controller'
|
||||
binding = process.atomBinding 'web_contents'
|
||||
ipc = require 'ipc'
|
||||
|
||||
nextId = 0
|
||||
getNextId = -> ++nextId
|
||||
|
||||
PDFPageSize =
|
||||
A4:
|
||||
custom_display_name: "A4"
|
||||
height_microns: 297000
|
||||
name: "ISO_A4"
|
||||
is_default: "true"
|
||||
width_microns: 210000
|
||||
A3:
|
||||
custom_display_name: "A3"
|
||||
height_microns: 420000
|
||||
name: "ISO_A3"
|
||||
width_microns: 297000
|
||||
Legal:
|
||||
custom_display_name: "Legal"
|
||||
height_microns: 355600
|
||||
name: "NA_LEGAL"
|
||||
width_microns: 215900
|
||||
Letter:
|
||||
custom_display_name: "Letter"
|
||||
height_microns: 279400
|
||||
name: "NA_LETTER"
|
||||
width_microns: 215900
|
||||
Tabloid:
|
||||
height_microns: 431800
|
||||
name: "NA_LEDGER"
|
||||
width_microns: 279400
|
||||
custom_display_name: "Tabloid"
|
||||
|
||||
wrapWebContents = (webContents) ->
|
||||
# webContents is an EventEmitter.
|
||||
webContents.__proto__ = EventEmitter.prototype
|
||||
|
||||
# WebContents::send(channel, 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.executeJavaScript = (code, hasUserGesture=false) ->
|
||||
if @getUrl() and not @isLoading()
|
||||
@_executeJavaScript code, hasUserGesture
|
||||
else
|
||||
webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code, hasUserGesture)
|
||||
|
||||
# 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
|
||||
|
||||
# Dispatch IPC messages to the ipc module.
|
||||
webContents.on 'ipc-message', (event, packed) ->
|
||||
[channel, args...] = packed
|
||||
ipc.emit channel, event, args...
|
||||
webContents.on 'ipc-message-sync', (event, packed) ->
|
||||
[channel, args...] = packed
|
||||
Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value)
|
||||
ipc.emit channel, event, args...
|
||||
|
||||
webContents.printToPDF = (options, callback) ->
|
||||
printingSetting =
|
||||
pageRage: []
|
||||
mediaSize: {}
|
||||
landscape: false
|
||||
color: 2
|
||||
headerFooterEnabled: false
|
||||
marginsType: 0
|
||||
isFirstRequest: false
|
||||
requestID: getNextId()
|
||||
previewModifiable: true
|
||||
printToPDF: true
|
||||
printWithCloudPrint: false
|
||||
printWithPrivet: false
|
||||
printWithExtension: false
|
||||
deviceName: "Save as PDF"
|
||||
generateDraftData: true
|
||||
fitToPageEnabled: false
|
||||
duplex: 0
|
||||
copies: 1
|
||||
collate: true
|
||||
shouldPrintBackgrounds: false
|
||||
shouldPrintSelectionOnly: false
|
||||
|
||||
if options.landscape
|
||||
printingSetting.landscape = options.landscape
|
||||
if options.marginsType
|
||||
printingSetting.marginsType = options.marginsType
|
||||
if options.printSelectionOnly
|
||||
printingSetting.shouldPrintSelectionOnly = options.printSelectionOnly
|
||||
if options.printBackground
|
||||
printingSetting.shouldPrintBackgrounds = options.printBackground
|
||||
|
||||
if options.pageSize and PDFPageSize[options.pageSize]
|
||||
printingSetting.mediaSize = PDFPageSize[options.pageSize]
|
||||
else
|
||||
printingSetting.mediaSize = PDFPageSize['A4']
|
||||
|
||||
@_printToPDF printingSetting, callback
|
||||
|
||||
binding._setWrapWebContents wrapWebContents
|
||||
process.once 'exit', binding._clearWrapWebContents
|
||||
|
||||
module.exports.create = (options={}) ->
|
||||
binding.create(options)
|
||||
71
atom/browser/api/trackable_object.cc
Normal file
71
atom/browser/api/trackable_object.cc
Normal file
@@ -0,0 +1,71 @@
|
||||
// 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/trackable_object.h"
|
||||
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/supports_user_data.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace {
|
||||
|
||||
const char* kTrackedObjectKey = "TrackedObjectKey";
|
||||
|
||||
class IDUserData : public base::SupportsUserData::Data {
|
||||
public:
|
||||
explicit IDUserData(int32_t id) : id_(id) {}
|
||||
|
||||
operator int32_t() const { return id_; }
|
||||
|
||||
private:
|
||||
int32_t id_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(IDUserData);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TrackableObjectBase::TrackableObjectBase()
|
||||
: weak_map_id_(0), wrapped_(nullptr), weak_factory_(this) {
|
||||
RegisterDestructionCallback(
|
||||
base::Bind(&TrackableObjectBase::Destroy, weak_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
||||
TrackableObjectBase::~TrackableObjectBase() {
|
||||
}
|
||||
|
||||
void TrackableObjectBase::AfterInit(v8::Isolate* isolate) {
|
||||
if (wrapped_)
|
||||
AttachAsUserData(wrapped_);
|
||||
}
|
||||
|
||||
void TrackableObjectBase::AttachAsUserData(base::SupportsUserData* wrapped) {
|
||||
if (weak_map_id_ != 0) {
|
||||
wrapped->SetUserData(kTrackedObjectKey, new IDUserData(weak_map_id_));
|
||||
wrapped_ = nullptr;
|
||||
} else {
|
||||
// If the TrackableObjectBase is not ready yet then delay SetUserData until
|
||||
// AfterInit is called.
|
||||
wrapped_ = wrapped;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
int32_t TrackableObjectBase::GetIDFromWrappedClass(base::SupportsUserData* w) {
|
||||
auto id = static_cast<IDUserData*>(w->GetUserData(kTrackedObjectKey));
|
||||
if (id)
|
||||
return *id;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// static
|
||||
void TrackableObjectBase::RegisterDestructionCallback(
|
||||
const base::Closure& closure) {
|
||||
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(closure);
|
||||
}
|
||||
|
||||
} // namespace mate
|
||||
133
atom/browser/api/trackable_object.h
Normal file
133
atom/browser/api/trackable_object.h
Normal file
@@ -0,0 +1,133 @@
|
||||
// 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_TRACKABLE_OBJECT_H_
|
||||
#define ATOM_BROWSER_API_TRACKABLE_OBJECT_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/common/id_weak_map.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
|
||||
namespace base {
|
||||
class SupportsUserData;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
|
||||
// Users should use TrackableObject instead.
|
||||
class TrackableObjectBase : public mate::EventEmitter {
|
||||
public:
|
||||
TrackableObjectBase();
|
||||
|
||||
// The ID in weak map.
|
||||
int32_t weak_map_id() const { return weak_map_id_; }
|
||||
|
||||
// Wrap TrackableObject into a class that SupportsUserData.
|
||||
void AttachAsUserData(base::SupportsUserData* wrapped);
|
||||
|
||||
// Subclasses should implement this to destroy their native types.
|
||||
virtual void Destroy() = 0;
|
||||
|
||||
protected:
|
||||
~TrackableObjectBase() override;
|
||||
|
||||
// mate::Wrappable:
|
||||
void AfterInit(v8::Isolate* isolate) override;
|
||||
|
||||
// Get the weak_map_id from SupportsUserData.
|
||||
static int32_t GetIDFromWrappedClass(base::SupportsUserData* wrapped);
|
||||
|
||||
// Register a callback that should be destroyed before JavaScript environment
|
||||
// gets destroyed.
|
||||
static void RegisterDestructionCallback(const base::Closure& closure);
|
||||
|
||||
int32_t weak_map_id_;
|
||||
base::SupportsUserData* wrapped_;
|
||||
|
||||
private:
|
||||
base::WeakPtrFactory<TrackableObjectBase> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TrackableObjectBase);
|
||||
};
|
||||
|
||||
// All instances of TrackableObject will be kept in a weak map and can be got
|
||||
// from its ID.
|
||||
template<typename T>
|
||||
class TrackableObject : public TrackableObjectBase {
|
||||
public:
|
||||
// Finds out the TrackableObject from its ID in weak map.
|
||||
static T* FromWeakMapID(v8::Isolate* isolate, int32_t id) {
|
||||
if (!weak_map_)
|
||||
return nullptr;
|
||||
|
||||
v8::MaybeLocal<v8::Object> object = weak_map_->Get(isolate, id);
|
||||
if (object.IsEmpty())
|
||||
return nullptr;
|
||||
|
||||
T* self = nullptr;
|
||||
mate::ConvertFromV8(isolate, object.ToLocalChecked(), &self);
|
||||
return self;
|
||||
}
|
||||
|
||||
// Finds out the TrackableObject from the class it wraps.
|
||||
static T* FromWrappedClass(v8::Isolate* isolate,
|
||||
base::SupportsUserData* wrapped) {
|
||||
int32_t id = GetIDFromWrappedClass(wrapped);
|
||||
if (!id)
|
||||
return nullptr;
|
||||
return FromWeakMapID(isolate, id);
|
||||
}
|
||||
|
||||
// Returns all objects in this class's weak map.
|
||||
static std::vector<v8::Local<v8::Object>> GetAll(v8::Isolate* isolate) {
|
||||
if (weak_map_)
|
||||
return weak_map_->Values(isolate);
|
||||
else
|
||||
return std::vector<v8::Local<v8::Object>>();
|
||||
}
|
||||
|
||||
TrackableObject() {
|
||||
RegisterDestructionCallback(
|
||||
base::Bind(&TrackableObject<T>::ReleaseAllWeakReferences));
|
||||
}
|
||||
|
||||
// Removes this instance from the weak map.
|
||||
void RemoveFromWeakMap() {
|
||||
if (weak_map_ && weak_map_->Has(weak_map_id()))
|
||||
weak_map_->Remove(weak_map_id());
|
||||
}
|
||||
|
||||
protected:
|
||||
~TrackableObject() override {
|
||||
RemoveFromWeakMap();
|
||||
}
|
||||
|
||||
void AfterInit(v8::Isolate* isolate) override {
|
||||
if (!weak_map_)
|
||||
weak_map_.reset(new atom::IDWeakMap);
|
||||
weak_map_id_ = weak_map_->Add(isolate, GetWrapper(isolate));
|
||||
TrackableObjectBase::AfterInit(isolate);
|
||||
}
|
||||
|
||||
private:
|
||||
// Releases all weak references in weak map, called when app is terminating.
|
||||
static void ReleaseAllWeakReferences() {
|
||||
weak_map_.reset();
|
||||
}
|
||||
|
||||
static scoped_ptr<atom::IDWeakMap> weak_map_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TrackableObject);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
scoped_ptr<atom::IDWeakMap> TrackableObject<T>::weak_map_;
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_BROWSER_API_TRACKABLE_OBJECT_H_
|
||||
53
atom/browser/atom_access_token_store.cc
Normal file
53
atom/browser/atom_access_token_store.cc
Normal file
@@ -0,0 +1,53 @@
|
||||
// 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/browser/atom_browser_main_parts.h"
|
||||
#include "atom/common/google_api_key.h"
|
||||
#include "content/public/browser/geolocation_provider.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() {
|
||||
content::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
|
||||
callback.Run(access_token_set, browser_context->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_
|
||||
246
atom/browser/atom_browser_client.cc
Normal file
246
atom/browser/atom_browser_client.cc
Normal file
@@ -0,0 +1,246 @@
|
||||
// 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"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
#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/browser.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/web_contents_preferences.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/stl_util.h"
|
||||
#include "base/strings/string_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 "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"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
// 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;
|
||||
|
||||
// Next navigation should not restart renderer process.
|
||||
bool g_suppress_renderer_process_restart = false;
|
||||
|
||||
// Custom schemes to be registered to standard.
|
||||
std::string g_custom_schemes = "";
|
||||
|
||||
scoped_refptr<net::X509Certificate> ImportCertFromFile(
|
||||
const base::FilePath& path) {
|
||||
if (path.empty())
|
||||
return nullptr;
|
||||
|
||||
std::string cert_data;
|
||||
if (!base::ReadFileToString(path, &cert_data))
|
||||
return nullptr;
|
||||
|
||||
net::CertificateList certs =
|
||||
net::X509Certificate::CreateCertificateListFromBytes(
|
||||
cert_data.data(), cert_data.size(),
|
||||
net::X509Certificate::FORMAT_AUTO);
|
||||
|
||||
if (certs.empty())
|
||||
return nullptr;
|
||||
|
||||
return certs[0];
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
void AtomBrowserClient::SuppressRendererProcessRestartForOnce() {
|
||||
g_suppress_renderer_process_restart = true;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::SetCustomSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
g_custom_schemes = JoinString(schemes, ',');
|
||||
}
|
||||
|
||||
AtomBrowserClient::AtomBrowserClient() {
|
||||
}
|
||||
|
||||
AtomBrowserClient::~AtomBrowserClient() {
|
||||
}
|
||||
|
||||
void AtomBrowserClient::RenderProcessWillLaunch(
|
||||
content::RenderProcessHost* host) {
|
||||
int process_id = host->GetID();
|
||||
host->AddFilter(new printing::PrintingMessageFilter(process_id));
|
||||
host->AddFilter(new TtsMessageFilter(process_id, host->GetBrowserContext()));
|
||||
}
|
||||
|
||||
content::SpeechRecognitionManagerDelegate*
|
||||
AtomBrowserClient::CreateSpeechRecognitionManagerDelegate() {
|
||||
return new AtomSpeechRecognitionManagerDelegate;
|
||||
}
|
||||
|
||||
content::AccessTokenStore* AtomBrowserClient::CreateAccessTokenStore() {
|
||||
return new AtomAccessTokenStore;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::OverrideWebkitPrefs(
|
||||
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 = true;
|
||||
prefs->dom_paste_enabled = true;
|
||||
prefs->java_enabled = false;
|
||||
prefs->allow_scripts_to_close_windows = true;
|
||||
prefs->javascript_can_access_clipboard = true;
|
||||
prefs->local_storage_enabled = true;
|
||||
prefs->databases_enabled = true;
|
||||
prefs->application_cache_enabled = true;
|
||||
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 = false;
|
||||
prefs->allow_running_insecure_content = false;
|
||||
|
||||
// Custom preferences of guest page.
|
||||
auto web_contents = content::WebContents::FromRenderViewHost(host);
|
||||
WebContentsPreferences::OverrideWebkitPrefs(web_contents, prefs);
|
||||
}
|
||||
|
||||
std::string AtomBrowserClient::GetApplicationLocale() {
|
||||
return l10n_util::GetApplicationLocale("");
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// Remember the original renderer process of the pending renderer process.
|
||||
auto current_process = current_instance->GetProcess();
|
||||
auto pending_process = (*new_instance)->GetProcess();
|
||||
pending_processes_[pending_process->GetID()] = current_process->GetID();
|
||||
// Clear the entry in map when process ends.
|
||||
current_process->AddObserver(this);
|
||||
}
|
||||
|
||||
void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
base::CommandLine* command_line,
|
||||
int process_id) {
|
||||
std::string process_type = command_line->GetSwitchValueASCII("type");
|
||||
if (process_type != "renderer")
|
||||
return;
|
||||
|
||||
// The registered standard schemes.
|
||||
if (!g_custom_schemes.empty())
|
||||
command_line->AppendSwitchASCII(switches::kRegisterStandardSchemes,
|
||||
g_custom_schemes);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Append --app-user-model-id.
|
||||
PWSTR current_app_id;
|
||||
if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(¤t_app_id))) {
|
||||
command_line->AppendSwitchNative(switches::kAppUserModelId, current_app_id);
|
||||
CoTaskMemFree(current_app_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
// If the process is a pending process, we should use the old one.
|
||||
if (ContainsKey(pending_processes_, process_id))
|
||||
process_id = pending_processes_[process_id];
|
||||
|
||||
// Get the WebContents of the render process.
|
||||
content::WebContents* web_contents = content::WebContents::FromRenderViewHost(
|
||||
content::RenderViewHost::FromID(process_id, kDefaultRoutingID));
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
WebContentsPreferences::AppendExtraCommandLineSwitches(
|
||||
web_contents, command_line);
|
||||
}
|
||||
|
||||
void AtomBrowserClient::DidCreatePpapiPlugin(
|
||||
content::BrowserPpapiHost* host) {
|
||||
host->GetPpapiHost()->AddHostFactoryFilter(
|
||||
make_scoped_ptr(new chrome::ChromeBrowserPepperHostFactory(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) {
|
||||
// --client-certificate=`path`
|
||||
auto cmd = base::CommandLine::ForCurrentProcess();
|
||||
if (cmd->HasSwitch(switches::kClientCertificate)) {
|
||||
auto cert_path = cmd->GetSwitchValuePath(switches::kClientCertificate);
|
||||
auto certificate = ImportCertFromFile(cert_path);
|
||||
if (certificate.get())
|
||||
delegate->ContinueWithCertificate(certificate.get());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cert_request_info->client_certs.empty())
|
||||
Browser::Get()->ClientCertificateSelector(web_contents,
|
||||
cert_request_info,
|
||||
delegate.Pass());
|
||||
}
|
||||
|
||||
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
|
||||
const content::MainFunctionParams&) {
|
||||
v8::V8::Initialize(); // Init V8 before creating main parts.
|
||||
return new AtomBrowserMainParts;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::RenderProcessHostDestroyed(
|
||||
content::RenderProcessHost* host) {
|
||||
int process_id = host->GetID();
|
||||
for (const auto& entry : pending_processes_) {
|
||||
if (entry.first == process_id || entry.second == process_id) {
|
||||
pending_processes_.erase(entry.first);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
76
atom/browser/atom_browser_client.h
Normal file
76
atom/browser/atom_browser_client.h
Normal file
@@ -0,0 +1,76 @@
|
||||
// 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 <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "brightray/browser/browser_client.h"
|
||||
#include "content/public/browser/render_process_host_observer.h"
|
||||
|
||||
namespace content {
|
||||
class QuotaPermissionContext;
|
||||
class ClientCertificateDelegate;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class SSLCertRequestInfo;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserClient : public brightray::BrowserClient,
|
||||
public content::RenderProcessHostObserver {
|
||||
public:
|
||||
AtomBrowserClient();
|
||||
virtual ~AtomBrowserClient();
|
||||
|
||||
// Don't force renderer process to restart for once.
|
||||
static void SuppressRendererProcessRestartForOnce();
|
||||
// Custom schemes to be registered to standard.
|
||||
static void SetCustomSchemes(const std::vector<std::string>& schemes);
|
||||
|
||||
protected:
|
||||
// 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::SiteInstance* current_instance,
|
||||
const GURL& dest_url,
|
||||
content::SiteInstance** new_instance) override;
|
||||
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;
|
||||
|
||||
// brightray::BrowserClient:
|
||||
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
|
||||
const content::MainFunctionParams&) override;
|
||||
|
||||
// content::RenderProcessHostObserver:
|
||||
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
|
||||
|
||||
private:
|
||||
// pending_render_process => current_render_process.
|
||||
std::map<int, int> pending_processes_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_BROWSER_CLIENT_H_
|
||||
181
atom/browser/atom_browser_context.cc
Normal file
181
atom/browser/atom_browser_context.cc
Normal file
@@ -0,0 +1,181 @@
|
||||
// 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/atom_download_manager_delegate.h"
|
||||
#include "atom/browser/atom_ssl_config_service.h"
|
||||
#include "atom/browser/browser.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/atom_version.h"
|
||||
#include "atom/common/chrome_version.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/prefs/pref_registry_simple.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/threading/sequenced_worker_pool.h"
|
||||
#include "base/threading/worker_pool.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "content/public/common/user_agent.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;
|
||||
|
||||
namespace atom {
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
std::string RemoveWhitespace(const std::string& str) {
|
||||
std::string trimmed;
|
||||
if (base::RemoveChars(str, " ", &trimmed))
|
||||
return trimmed;
|
||||
else
|
||||
return str;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||
bool in_memory)
|
||||
: brightray::BrowserContext(partition, in_memory),
|
||||
job_factory_(new AtomURLRequestJobFactory) {
|
||||
}
|
||||
|
||||
AtomBrowserContext::~AtomBrowserContext() {
|
||||
}
|
||||
|
||||
std::string AtomBrowserContext::GetUserAgent() {
|
||||
Browser* browser = Browser::Get();
|
||||
std::string name = RemoveWhitespace(browser->GetName());
|
||||
std::string user_agent;
|
||||
if (name == ATOM_PRODUCT_NAME) {
|
||||
user_agent = "Chrome/" CHROME_VERSION_STRING " "
|
||||
ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING;
|
||||
} else {
|
||||
user_agent = base::StringPrintf(
|
||||
"%s/%s Chrome/%s " ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING,
|
||||
name.c_str(),
|
||||
browser->GetVersion().c_str(),
|
||||
CHROME_VERSION_STRING);
|
||||
}
|
||||
return content::BuildUserAgentFromProduct(user_agent);
|
||||
}
|
||||
|
||||
net::URLRequestJobFactory* AtomBrowserContext::CreateURLRequestJobFactory(
|
||||
content::ProtocolHandlerMap* handlers,
|
||||
content::URLRequestInterceptorScopedVector* interceptors) {
|
||||
scoped_ptr<AtomURLRequestJobFactory> job_factory(job_factory_);
|
||||
|
||||
for (auto& it : *handlers) {
|
||||
job_factory->SetProtocolHandler(it.first,
|
||||
make_scoped_ptr(it.second.release()));
|
||||
}
|
||||
handlers->clear();
|
||||
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kDataScheme, make_scoped_ptr(new net::DataProtocolHandler));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kFileScheme, make_scoped_ptr(new asar::AsarProtocolHandler(
|
||||
BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
|
||||
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN))));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kHttpScheme,
|
||||
make_scoped_ptr(new HttpProtocolHandler(url::kHttpScheme)));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kHttpsScheme,
|
||||
make_scoped_ptr(new HttpProtocolHandler(url::kHttpsScheme)));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kWsScheme,
|
||||
make_scoped_ptr(new HttpProtocolHandler(url::kWsScheme)));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kWssScheme,
|
||||
make_scoped_ptr(new HttpProtocolHandler(url::kWssScheme)));
|
||||
|
||||
auto host_resolver =
|
||||
url_request_context_getter()->GetURLRequestContext()->host_resolver();
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kFtpScheme,
|
||||
make_scoped_ptr(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();
|
||||
}
|
||||
|
||||
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::DownloadManagerDelegate*
|
||||
AtomBrowserContext::GetDownloadManagerDelegate() {
|
||||
if (!download_manager_delegate_.get()) {
|
||||
auto download_manager = content::BrowserContext::GetDownloadManager(this);
|
||||
download_manager_delegate_.reset(
|
||||
new AtomDownloadManagerDelegate(download_manager));
|
||||
}
|
||||
return download_manager_delegate_.get();
|
||||
}
|
||||
|
||||
content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() {
|
||||
if (!guest_manager_)
|
||||
guest_manager_.reset(new WebViewManager);
|
||||
return guest_manager_.get();
|
||||
}
|
||||
|
||||
net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() {
|
||||
return new AtomSSLConfigService;
|
||||
}
|
||||
|
||||
void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
|
||||
pref_registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory,
|
||||
base::FilePath());
|
||||
pref_registry->RegisterFilePathPref(prefs::kDownloadDefaultDirectory,
|
||||
base::FilePath());
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace brightray {
|
||||
|
||||
// static
|
||||
scoped_refptr<BrowserContext> BrowserContext::Create(
|
||||
const std::string& partition, bool in_memory) {
|
||||
return make_scoped_refptr(new atom::AtomBrowserContext(partition, in_memory));
|
||||
}
|
||||
|
||||
} // namespace brightray
|
||||
53
atom/browser/atom_browser_context.h
Normal file
53
atom/browser/atom_browser_context.h
Normal file
@@ -0,0 +1,53 @@
|
||||
// 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 <string>
|
||||
|
||||
#include "brightray/browser/browser_context.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomDownloadManagerDelegate;
|
||||
class AtomURLRequestJobFactory;
|
||||
class WebViewManager;
|
||||
|
||||
class AtomBrowserContext : public brightray::BrowserContext {
|
||||
public:
|
||||
AtomBrowserContext(const std::string& partition, bool in_memory);
|
||||
~AtomBrowserContext() override;
|
||||
|
||||
// brightray::URLRequestContextGetter::Delegate:
|
||||
std::string GetUserAgent() override;
|
||||
net::URLRequestJobFactory* CreateURLRequestJobFactory(
|
||||
content::ProtocolHandlerMap* handlers,
|
||||
content::URLRequestInterceptorScopedVector* interceptors) override;
|
||||
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path) override;
|
||||
net::SSLConfigService* CreateSSLConfigService() override;
|
||||
|
||||
// content::BrowserContext:
|
||||
content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
|
||||
content::BrowserPluginGuestManager* GetGuestManager() override;
|
||||
|
||||
// brightray::BrowserContext:
|
||||
void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
|
||||
|
||||
AtomURLRequestJobFactory* job_factory() const { return job_factory_; }
|
||||
|
||||
private:
|
||||
scoped_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
|
||||
scoped_ptr<WebViewManager> guest_manager_;
|
||||
|
||||
// Managed by brightray::BrowserContext.
|
||||
AtomURLRequestJobFactory* job_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_
|
||||
129
atom/browser/atom_browser_main_parts.cc
Normal file
129
atom/browser/atom_browser_main_parts.cc
Normal file
@@ -0,0 +1,129 @@
|
||||
// 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"
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/bridge_task_runner.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/javascript_environment.h"
|
||||
#include "atom/browser/node_debugger.h"
|
||||
#include "atom/common/api/atom_bindings.h"
|
||||
#include "atom/common/node_bindings.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/thread_task_runner_handle.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "v8/include/v8-debug.h"
|
||||
|
||||
#if defined(USE_X11)
|
||||
#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
// static
|
||||
AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL;
|
||||
|
||||
AtomBrowserMainParts::AtomBrowserMainParts()
|
||||
: fake_browser_process_(new BrowserProcess),
|
||||
browser_(new Browser),
|
||||
node_bindings_(NodeBindings::Create(true)),
|
||||
atom_bindings_(new AtomBindings),
|
||||
gc_timer_(true, true) {
|
||||
DCHECK(!self_) << "Cannot have two AtomBrowserMainParts";
|
||||
self_ = this;
|
||||
}
|
||||
|
||||
AtomBrowserMainParts::~AtomBrowserMainParts() {
|
||||
}
|
||||
|
||||
// static
|
||||
AtomBrowserMainParts* AtomBrowserMainParts::Get() {
|
||||
DCHECK(self_);
|
||||
return self_;
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::RegisterDestructionCallback(
|
||||
const base::Closure& callback) {
|
||||
destruction_callbacks_.push_back(callback);
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PostEarlyInitialization() {
|
||||
brightray::BrowserMainParts::PostEarlyInitialization();
|
||||
|
||||
#if defined(USE_X11)
|
||||
SetDPIFromGSettings();
|
||||
#endif
|
||||
|
||||
{
|
||||
// Temporary set the bridge_task_runner_ as current thread's task runner,
|
||||
// so we can fool gin::PerIsolateData to use it as its task runner, instead
|
||||
// of getting current message loop's task runner, which is null for now.
|
||||
bridge_task_runner_ = new BridgeTaskRunner;
|
||||
base::ThreadTaskRunnerHandle handle(bridge_task_runner_);
|
||||
|
||||
// The ProxyResolverV8 has setup a complete V8 environment, in order to
|
||||
// avoid conflicts we only initialize our V8 environment after that.
|
||||
js_env_.reset(new JavascriptEnvironment);
|
||||
}
|
||||
|
||||
node_bindings_->Initialize();
|
||||
|
||||
// Support the "--debug" switch.
|
||||
node_debugger_.reset(new NodeDebugger(js_env_->isolate()));
|
||||
|
||||
// Create the global environment.
|
||||
global_env = node_bindings_->CreateEnvironment(js_env_->context());
|
||||
|
||||
// Make sure node can get correct environment when debugging.
|
||||
if (node_debugger_->IsRunning())
|
||||
global_env->AssignToContext(v8::Debug::GetDebugContext());
|
||||
|
||||
// Add atom-shell extended APIs.
|
||||
atom_bindings_->BindTo(js_env_->isolate(), global_env->process_object());
|
||||
|
||||
// Load everything.
|
||||
node_bindings_->LoadEnvironment(global_env);
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::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();
|
||||
|
||||
// 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.
|
||||
Browser::Get()->WillFinishLaunching();
|
||||
Browser::Get()->DidFinishLaunching();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PostMainMessageLoopRun() {
|
||||
brightray::BrowserMainParts::PostMainMessageLoopRun();
|
||||
|
||||
// Make sure destruction callbacks are called before message loop is
|
||||
// destroyed, otherwise some objects that need to be deleted on IO thread
|
||||
// won't be freed.
|
||||
for (const auto& callback : destruction_callbacks_)
|
||||
callback.Run();
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
80
atom/browser/atom_browser_main_parts.h
Normal file
80
atom/browser/atom_browser_main_parts.h
Normal file
@@ -0,0 +1,80 @@
|
||||
// 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 <list>
|
||||
#include <string>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/timer/timer.h"
|
||||
#include "brightray/browser/browser_main_parts.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
|
||||
class BrowserProcess;
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBindings;
|
||||
class Browser;
|
||||
class JavascriptEnvironment;
|
||||
class NodeBindings;
|
||||
class NodeDebugger;
|
||||
class BridgeTaskRunner;
|
||||
|
||||
class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||
public:
|
||||
AtomBrowserMainParts();
|
||||
virtual ~AtomBrowserMainParts();
|
||||
|
||||
static AtomBrowserMainParts* Get();
|
||||
|
||||
// Register a callback that should be destroyed before JavaScript environment
|
||||
// gets destroyed.
|
||||
void RegisterDestructionCallback(const base::Closure& callback);
|
||||
|
||||
Browser* browser() { return browser_.get(); }
|
||||
|
||||
protected:
|
||||
// content::BrowserMainParts:
|
||||
void PostEarlyInitialization() override;
|
||||
void PreMainMessageLoopRun() override;
|
||||
void PostMainMessageLoopRun() override;
|
||||
#if defined(OS_MACOSX)
|
||||
void PreMainMessageLoopStart() override;
|
||||
void PostDestroyThreads() override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
#if defined(USE_X11)
|
||||
void SetDPIFromGSettings();
|
||||
#endif
|
||||
|
||||
// A fake BrowserProcess object that used to feed the source code from chrome.
|
||||
scoped_ptr<BrowserProcess> fake_browser_process_;
|
||||
|
||||
// The gin::PerIsolateData requires a task runner to create, so we feed it
|
||||
// with a task runner that will post all work to main loop.
|
||||
scoped_refptr<BridgeTaskRunner> bridge_task_runner_;
|
||||
|
||||
scoped_ptr<Browser> browser_;
|
||||
scoped_ptr<JavascriptEnvironment> js_env_;
|
||||
scoped_ptr<NodeBindings> node_bindings_;
|
||||
scoped_ptr<AtomBindings> atom_bindings_;
|
||||
scoped_ptr<NodeDebugger> node_debugger_;
|
||||
|
||||
base::Timer gc_timer_;
|
||||
|
||||
// List of callbacks should be executed before destroying JS env.
|
||||
std::list<base::Closure> destruction_callbacks_;
|
||||
|
||||
static AtomBrowserMainParts* self_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserMainParts);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_BROWSER_MAIN_PARTS_H_
|
||||
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
|
||||
42
atom/browser/atom_browser_main_parts_mac.mm
Normal file
42
atom/browser/atom_browser_main_parts_mac.mm
Normal file
@@ -0,0 +1,42 @@
|
||||
// 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"
|
||||
|
||||
#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] init];
|
||||
[NSApp setDelegate:(id<NSFileManagerDelegate>)delegate];
|
||||
|
||||
NSBundle* frameworkBundle = base::mac::FrameworkBundle();
|
||||
NSNib* mainNib = [[NSNib alloc] initWithNibNamed:@"MainMenu"
|
||||
bundle:frameworkBundle];
|
||||
[mainNib instantiateWithOwner:application topLevelObjects:nil];
|
||||
[mainNib release];
|
||||
|
||||
// Prevent Cocoa from turning command-line arguments into
|
||||
// |-application:openFiles:|, since we already handle them directly.
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PostDestroyThreads() {
|
||||
[[NSApp delegate] release];
|
||||
[NSApp setDelegate:nil];
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
164
atom/browser/atom_download_manager_delegate.cc
Normal file
164
atom/browser/atom_download_manager_delegate.cc
Normal file
@@ -0,0 +1,164 @@
|
||||
// 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_download_manager_delegate.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/atom_api_download_item.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/prefs/pref_service.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
#include "net/base/filename_util.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomDownloadManagerDelegate::AtomDownloadManagerDelegate(
|
||||
content::DownloadManager* manager)
|
||||
: download_manager_(manager),
|
||||
weak_ptr_factory_(this) {}
|
||||
|
||||
AtomDownloadManagerDelegate::~AtomDownloadManagerDelegate() {
|
||||
if (download_manager_) {
|
||||
DCHECK_EQ(static_cast<content::DownloadManagerDelegate*>(this),
|
||||
download_manager_->GetDelegate());
|
||||
download_manager_->SetDelegate(nullptr);
|
||||
download_manager_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AtomDownloadManagerDelegate::CreateDownloadPath(
|
||||
const GURL& url,
|
||||
const std::string& content_disposition,
|
||||
const std::string& suggested_filename,
|
||||
const std::string& mime_type,
|
||||
const base::FilePath& default_download_path,
|
||||
const CreateDownloadPathCallback& callback) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
|
||||
|
||||
auto generated_name = net::GenerateFileName(url,
|
||||
content_disposition,
|
||||
std::string(),
|
||||
suggested_filename,
|
||||
mime_type,
|
||||
std::string());
|
||||
|
||||
if (!base::PathExists(default_download_path))
|
||||
base::CreateDirectory(default_download_path);
|
||||
|
||||
base::FilePath path(default_download_path.Append(generated_name));
|
||||
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(callback, path));
|
||||
}
|
||||
|
||||
void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
|
||||
uint32 download_id,
|
||||
const content::DownloadTargetCallback& callback,
|
||||
const base::FilePath& default_path) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
auto item = download_manager_->GetDownload(download_id);
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
NativeWindow* window = nullptr;
|
||||
auto relay = NativeWindowRelay::FromWebContents(item->GetWebContents());
|
||||
if (relay)
|
||||
window = relay->window.get();
|
||||
|
||||
base::FilePath path;
|
||||
if (file_dialog::ShowSaveDialog(window, item->GetURL().spec(), default_path,
|
||||
file_dialog::Filters(), &path)) {
|
||||
// Remember the last selected download directory.
|
||||
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
|
||||
download_manager_->GetBrowserContext());
|
||||
browser_context->prefs()->SetFilePath(prefs::kDownloadDefaultDirectory,
|
||||
path.DirName());
|
||||
}
|
||||
|
||||
// Running the DownloadTargetCallback with an empty FilePath signals that the
|
||||
// download should be cancelled.
|
||||
// If user cancels the file save dialog, run the callback with empty FilePath.
|
||||
callback.Run(path,
|
||||
content::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path);
|
||||
}
|
||||
|
||||
void AtomDownloadManagerDelegate::Shutdown() {
|
||||
weak_ptr_factory_.InvalidateWeakPtrs();
|
||||
download_manager_ = nullptr;
|
||||
}
|
||||
|
||||
bool AtomDownloadManagerDelegate::DetermineDownloadTarget(
|
||||
content::DownloadItem* download,
|
||||
const content::DownloadTargetCallback& callback) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
if (!download->GetForcedFilePath().empty()) {
|
||||
callback.Run(download->GetForcedFilePath(),
|
||||
content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
download->GetForcedFilePath());
|
||||
return true;
|
||||
}
|
||||
base::SupportsUserData::Data* save_path = download->GetUserData(
|
||||
atom::api::DownloadItem::UserDataKey());
|
||||
if (save_path) {
|
||||
const base::FilePath& default_download_path =
|
||||
static_cast<api::DownloadItem::SavePathData*>(save_path)->path();
|
||||
callback.Run(default_download_path,
|
||||
content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
default_download_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
|
||||
download_manager_->GetBrowserContext());
|
||||
base::FilePath default_download_path = browser_context->prefs()->GetFilePath(
|
||||
prefs::kDownloadDefaultDirectory);
|
||||
// If users didn't set download path, use 'Downloads' directory by default.
|
||||
if (default_download_path.empty()) {
|
||||
auto path = download_manager_->GetBrowserContext()->GetPath();
|
||||
default_download_path = path.Append(FILE_PATH_LITERAL("Downloads"));
|
||||
}
|
||||
|
||||
CreateDownloadPathCallback download_path_callback =
|
||||
base::Bind(&AtomDownloadManagerDelegate::OnDownloadPathGenerated,
|
||||
weak_ptr_factory_.GetWeakPtr(),
|
||||
download->GetId(), callback);
|
||||
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::FILE, FROM_HERE,
|
||||
base::Bind(&AtomDownloadManagerDelegate::CreateDownloadPath,
|
||||
weak_ptr_factory_.GetWeakPtr(),
|
||||
download->GetURL(),
|
||||
download->GetContentDisposition(),
|
||||
download->GetSuggestedFilename(),
|
||||
download->GetMimeType(),
|
||||
default_download_path,
|
||||
download_path_callback));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtomDownloadManagerDelegate::ShouldOpenDownload(
|
||||
content::DownloadItem* download,
|
||||
const content::DownloadOpenDelayedCallback& callback) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void AtomDownloadManagerDelegate::GetNextId(
|
||||
const content::DownloadIdCallback& callback) {
|
||||
static uint32 next_id = content::DownloadItem::kInvalidId + 1;
|
||||
callback.Run(next_id++);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
57
atom/browser/atom_download_manager_delegate.h
Normal file
57
atom/browser/atom_download_manager_delegate.h
Normal file
@@ -0,0 +1,57 @@
|
||||
// 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_DOWNLOAD_MANAGER_DELEGATE_H_
|
||||
#define ATOM_BROWSER_ATOM_DOWNLOAD_MANAGER_DELEGATE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "content/public/browser/download_manager_delegate.h"
|
||||
|
||||
namespace content {
|
||||
class DownloadManager;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate {
|
||||
public:
|
||||
using CreateDownloadPathCallback =
|
||||
base::Callback<void(const base::FilePath&)>;
|
||||
|
||||
explicit AtomDownloadManagerDelegate(content::DownloadManager* manager);
|
||||
virtual ~AtomDownloadManagerDelegate();
|
||||
|
||||
// Generate default file path to save the download.
|
||||
void CreateDownloadPath(const GURL& url,
|
||||
const std::string& suggested_filename,
|
||||
const std::string& content_disposition,
|
||||
const std::string& mime_type,
|
||||
const base::FilePath& path,
|
||||
const CreateDownloadPathCallback& callback);
|
||||
void OnDownloadPathGenerated(uint32 download_id,
|
||||
const content::DownloadTargetCallback& callback,
|
||||
const base::FilePath& default_path);
|
||||
|
||||
// content::DownloadManagerDelegate:
|
||||
void Shutdown() override;
|
||||
bool DetermineDownloadTarget(
|
||||
content::DownloadItem* download,
|
||||
const content::DownloadTargetCallback& callback) override;
|
||||
bool ShouldOpenDownload(
|
||||
content::DownloadItem* download,
|
||||
const content::DownloadOpenDelayedCallback& callback) override;
|
||||
void GetNextId(const content::DownloadIdCallback& callback) override;
|
||||
|
||||
private:
|
||||
content::DownloadManager* download_manager_;
|
||||
base::WeakPtrFactory<AtomDownloadManagerDelegate> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomDownloadManagerDelegate);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_DOWNLOAD_MANAGER_DELEGATE_H_
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user