Compare commits
644 Commits
v18.2.4
...
v21.0.0-ni
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8004cb8722 | ||
|
|
7f757075bc | ||
|
|
674596d11e | ||
|
|
3c2ec2280e | ||
|
|
de1cec8693 | ||
|
|
99c2706376 | ||
|
|
63593ffb22 | ||
|
|
b0c6fb5152 | ||
|
|
77b4aab720 | ||
|
|
7c2ed98214 | ||
|
|
62001dc6cb | ||
|
|
ff804e3a74 | ||
|
|
9416091180 | ||
|
|
6d9e8b65bc | ||
|
|
b42fd1ddca | ||
|
|
182ab9ad76 | ||
|
|
77e1a046ec | ||
|
|
0be73d18ef | ||
|
|
c842f63383 | ||
|
|
6674082041 | ||
|
|
cabfb8507d | ||
|
|
aa40652456 | ||
|
|
dd68fae081 | ||
|
|
ad1bbc198b | ||
|
|
2c51a81e85 | ||
|
|
648c9934c0 | ||
|
|
aeba6ca973 | ||
|
|
49302e4a2f | ||
|
|
57c265198e | ||
|
|
08dd38d9be | ||
|
|
dd82a26e95 | ||
|
|
3c63f075bd | ||
|
|
fec4cca8d4 | ||
|
|
1ed191114a | ||
|
|
d4e97483aa | ||
|
|
7ae3025fd5 | ||
|
|
67eda4bcc8 | ||
|
|
9f0e7126c4 | ||
|
|
be7f90481d | ||
|
|
6dc1218c37 | ||
|
|
cffcd0d47a | ||
|
|
9e0a3c44dd | ||
|
|
1b96a3aa1d | ||
|
|
3c7d446fad | ||
|
|
60b6e74e3f | ||
|
|
ba25714e16 | ||
|
|
05d4966251 | ||
|
|
eb8c9452cb | ||
|
|
38848c5bf7 | ||
|
|
57b02e153d | ||
|
|
8a0df1f487 | ||
|
|
c4cde78818 | ||
|
|
f1746c81c6 | ||
|
|
9d23a624c1 | ||
|
|
574da5a9a1 | ||
|
|
2afb284456 | ||
|
|
4bec26cd0c | ||
|
|
0cb39b5bb5 | ||
|
|
e9f42b4ad4 | ||
|
|
9a5d759ea3 | ||
|
|
d32e6cc252 | ||
|
|
440c575aa6 | ||
|
|
46e5c537c8 | ||
|
|
07d168343a | ||
|
|
62aeb74d7c | ||
|
|
afd08c9450 | ||
|
|
5314ae5342 | ||
|
|
511ff8bc8d | ||
|
|
95019f0454 | ||
|
|
4190ec2482 | ||
|
|
f63bba8ce2 | ||
|
|
8f3fb8db09 | ||
|
|
2b862c18ba | ||
|
|
fa8e4a7610 | ||
|
|
2eb0e5dcab | ||
|
|
459404f536 | ||
|
|
78848f8bfe | ||
|
|
eba9d3fc79 | ||
|
|
1941c88442 | ||
|
|
e83c3ec744 | ||
|
|
7ec88584b5 | ||
|
|
47d8d4cc5c | ||
|
|
f7428baace | ||
|
|
403bd39d05 | ||
|
|
c418275228 | ||
|
|
98cd16d336 | ||
|
|
e5db178ab6 | ||
|
|
0ee7f14190 | ||
|
|
d28ed0da20 | ||
|
|
1edf9d2ada | ||
|
|
d359736e65 | ||
|
|
c885f9063b | ||
|
|
c3920c5c02 | ||
|
|
5d120359f6 | ||
|
|
0d4e417594 | ||
|
|
4ddd03b1b3 | ||
|
|
7c12baccab | ||
|
|
461561c19c | ||
|
|
1f814eacb2 | ||
|
|
ad2b1fee59 | ||
|
|
35ff95d3c7 | ||
|
|
6257e0c348 | ||
|
|
3310e4039f | ||
|
|
40fbc05bb2 | ||
|
|
3458eac276 | ||
|
|
44b9ee51f4 | ||
|
|
07294cbf15 | ||
|
|
a4043237da | ||
|
|
704b2199b3 | ||
|
|
f1087cc830 | ||
|
|
d028044a24 | ||
|
|
9c311a2059 | ||
|
|
47afaddaf5 | ||
|
|
59d3c12cae | ||
|
|
e86d1cba75 | ||
|
|
032e1d9bef | ||
|
|
39840502be | ||
|
|
8238cca87b | ||
|
|
e2c58d164d | ||
|
|
ba4893c248 | ||
|
|
c5b87e4919 | ||
|
|
3b881e4a13 | ||
|
|
106aa0e922 | ||
|
|
11924bdbb2 | ||
|
|
cd19a741b1 | ||
|
|
5895296239 | ||
|
|
e3243ad113 | ||
|
|
5fee5b0e22 | ||
|
|
f172136752 | ||
|
|
218797eb61 | ||
|
|
e410109a3d | ||
|
|
a5869fe997 | ||
|
|
bf52318c76 | ||
|
|
73c85410c5 | ||
|
|
ad7aab8338 | ||
|
|
140c8d0d0a | ||
|
|
34fc53e5e6 | ||
|
|
528cbe8131 | ||
|
|
116c32a030 | ||
|
|
530a022b05 | ||
|
|
f3f327823e | ||
|
|
0f528c1e43 | ||
|
|
2bbbc66eb8 | ||
|
|
3cd5223134 | ||
|
|
8e45f43f18 | ||
|
|
d341610d64 | ||
|
|
6e9466f96b | ||
|
|
e2f42e5d99 | ||
|
|
ec98e95b8a | ||
|
|
bf4efb693b | ||
|
|
999a225edb | ||
|
|
b3ec0a801a | ||
|
|
6f8bfdeb7a | ||
|
|
20538c4f34 | ||
|
|
d2e539c7d4 | ||
|
|
ea4278754c | ||
|
|
f418a49857 | ||
|
|
bad8d5e08a | ||
|
|
4ec95edf06 | ||
|
|
4c7c0b41c2 | ||
|
|
21ef8501e7 | ||
|
|
bed38e0985 | ||
|
|
8de5cdb426 | ||
|
|
9707812d68 | ||
|
|
16cd22ff6a | ||
|
|
954fd72500 | ||
|
|
8157a01a42 | ||
|
|
d565243f98 | ||
|
|
77dcf4a5e0 | ||
|
|
2a9b3cc9cd | ||
|
|
7ca3f55b10 | ||
|
|
e5543a2dd2 | ||
|
|
bd81ae08ac | ||
|
|
57b863c213 | ||
|
|
52c0a4fafc | ||
|
|
1302ebf50e | ||
|
|
37d93b0482 | ||
|
|
2fd0194e94 | ||
|
|
6d50717eed | ||
|
|
289128b96c | ||
|
|
16db5a112e | ||
|
|
f44ecb7f03 | ||
|
|
8e97f3badf | ||
|
|
a203123473 | ||
|
|
c750936328 | ||
|
|
5f0f517486 | ||
|
|
4ec2de659f | ||
|
|
30d15715a9 | ||
|
|
882fa36940 | ||
|
|
e56f626b94 | ||
|
|
92b0f3e808 | ||
|
|
4f99e3e46c | ||
|
|
f39c1a35e5 | ||
|
|
05b03b01dc | ||
|
|
6038e42c23 | ||
|
|
b00c026a54 | ||
|
|
eb26f99f6e | ||
|
|
d13c879a15 | ||
|
|
3ad70d0f0b | ||
|
|
0671f229ac | ||
|
|
539a53786c | ||
|
|
000c3d981c | ||
|
|
eb9888d1d2 | ||
|
|
1cd07c565a | ||
|
|
f306fbc010 | ||
|
|
5057cbf418 | ||
|
|
561be72373 | ||
|
|
a38e5d20ff | ||
|
|
cda8f3c15c | ||
|
|
df91dd6d2b | ||
|
|
470396d6ac | ||
|
|
3849d19e14 | ||
|
|
2cb53c5db1 | ||
|
|
93b39b92b5 | ||
|
|
0d69067dee | ||
|
|
fd88908457 | ||
|
|
34a9268e97 | ||
|
|
03d9615f99 | ||
|
|
2ffa31832e | ||
|
|
4accf67d2b | ||
|
|
afca3519fd | ||
|
|
4b3a7b7762 | ||
|
|
a6a2bb65a4 | ||
|
|
fd559d8516 | ||
|
|
7bc4b919dc | ||
|
|
6cb2b9eab7 | ||
|
|
b8abf5e38a | ||
|
|
6667de28e3 | ||
|
|
9d3fc9c794 | ||
|
|
ba573f5583 | ||
|
|
df9383cb3c | ||
|
|
09a80ea48c | ||
|
|
887b5a7dc7 | ||
|
|
c3fa6005db | ||
|
|
89fab6a549 | ||
|
|
291eb60916 | ||
|
|
aa3e852a73 | ||
|
|
1639ccf98f | ||
|
|
38c21b7aca | ||
|
|
ff13fa8f0a | ||
|
|
ba7dedcc6f | ||
|
|
5ff94e7f2b | ||
|
|
17c8ec765b | ||
|
|
588005a9d5 | ||
|
|
73e0bf973d | ||
|
|
455544dfb6 | ||
|
|
2436152536 | ||
|
|
61374019c0 | ||
|
|
04b33b319b | ||
|
|
97c9451efc | ||
|
|
4e3587c7c6 | ||
|
|
ccde8994b5 | ||
|
|
125c324a49 | ||
|
|
4aba68a59d | ||
|
|
7af0b58c98 | ||
|
|
cc411946d7 | ||
|
|
b06737fdac | ||
|
|
8b5613efcb | ||
|
|
a8103691ac | ||
|
|
142e1f667b | ||
|
|
ff5f66395e | ||
|
|
ba3aca8200 | ||
|
|
d67532ee9f | ||
|
|
4f8a843606 | ||
|
|
dd6ce91f57 | ||
|
|
6f8a36f404 | ||
|
|
c512993744 | ||
|
|
6063d4f8df | ||
|
|
64dc90824b | ||
|
|
79e1881b2a | ||
|
|
a853a6ce9f | ||
|
|
5633c45c19 | ||
|
|
9bcbe70dbe | ||
|
|
e76cf3e2ed | ||
|
|
627c2987ba | ||
|
|
7f5346b954 | ||
|
|
4fc42092b8 | ||
|
|
c8fbabae48 | ||
|
|
b94f25c287 | ||
|
|
5572659988 | ||
|
|
030087c1c7 | ||
|
|
5391211824 | ||
|
|
00368aca37 | ||
|
|
9483e714c4 | ||
|
|
03e68e2efe | ||
|
|
6fea35271c | ||
|
|
dd7dfd7ecd | ||
|
|
3ba60de51d | ||
|
|
1bdbb69351 | ||
|
|
2900bc55aa | ||
|
|
0d35084ada | ||
|
|
0f2da5c830 | ||
|
|
808efd89ed | ||
|
|
0696320d28 | ||
|
|
a401360057 | ||
|
|
d8a7219d07 | ||
|
|
a2a8e493eb | ||
|
|
90eb47f70b | ||
|
|
323f7d4c19 | ||
|
|
706d585eb8 | ||
|
|
5b648854d5 | ||
|
|
2091343b78 | ||
|
|
4fad376b0e | ||
|
|
60f1e5e008 | ||
|
|
349cd98b0a | ||
|
|
747dfe5851 | ||
|
|
658407df7a | ||
|
|
0893733496 | ||
|
|
f887000d50 | ||
|
|
7dee5179cb | ||
|
|
a71936e395 | ||
|
|
e1ed96b574 | ||
|
|
9901d2f281 | ||
|
|
14f07d7814 | ||
|
|
6f851afab5 | ||
|
|
682d2e3f78 | ||
|
|
b55f9d868a | ||
|
|
ce562b6889 | ||
|
|
015185ad5a | ||
|
|
fb534c927a | ||
|
|
192a7fad0d | ||
|
|
097da1d4ba | ||
|
|
b3530d5df8 | ||
|
|
b5297ea8e2 | ||
|
|
15c931201a | ||
|
|
f91b24deb5 | ||
|
|
d2c3e78117 | ||
|
|
a00544c745 | ||
|
|
160d6923db | ||
|
|
6d5501d0bd | ||
|
|
bfabd67112 | ||
|
|
40c022ad69 | ||
|
|
028a72daac | ||
|
|
6a1748da06 | ||
|
|
0a73f60423 | ||
|
|
f48a921d14 | ||
|
|
f3e0517b6e | ||
|
|
53c3dd68b2 | ||
|
|
283e4826af | ||
|
|
e571417c52 | ||
|
|
a5501d7118 | ||
|
|
0c8c755ffb | ||
|
|
bb146e3deb | ||
|
|
33e9bfd99b | ||
|
|
e864bc44c6 | ||
|
|
64517b36ef | ||
|
|
00021a41b1 | ||
|
|
b53118ca28 | ||
|
|
0c864837af | ||
|
|
fec147a0cb | ||
|
|
841e0a4e0c | ||
|
|
31c2b5703a | ||
|
|
6733279037 | ||
|
|
2d0ad04354 | ||
|
|
5ae234d5e1 | ||
|
|
0f087127de | ||
|
|
b9c0166b49 | ||
|
|
fd191fc50b | ||
|
|
37b7e347fc | ||
|
|
9d4aceb940 | ||
|
|
eee4232069 | ||
|
|
635b3a94c8 | ||
|
|
99791f620b | ||
|
|
8b0af86097 | ||
|
|
f5e874cbcb | ||
|
|
dda8bc3cd1 | ||
|
|
233a39dbc9 | ||
|
|
7658edfa1a | ||
|
|
16f8d713ab | ||
|
|
3d4d39d67b | ||
|
|
b66667b843 | ||
|
|
bfbba9dad6 | ||
|
|
341b7bdf4a | ||
|
|
4c4e02318f | ||
|
|
de2f48b40f | ||
|
|
a9c52926c0 | ||
|
|
bfa5b21044 | ||
|
|
d804cd5de2 | ||
|
|
7038d2d418 | ||
|
|
b8c0ef9713 | ||
|
|
c5b93eaf17 | ||
|
|
2ca46058cd | ||
|
|
3057ff0120 | ||
|
|
48edb2c707 | ||
|
|
56ab3d73c6 | ||
|
|
0287c3f511 | ||
|
|
1c53fc4331 | ||
|
|
c0d442364a | ||
|
|
59dd17f2cf | ||
|
|
e8ed9cb4b5 | ||
|
|
c9fd255093 | ||
|
|
caddc83cfe | ||
|
|
a7a5e7fcfd | ||
|
|
207d4e5823 | ||
|
|
8e2310db31 | ||
|
|
6872306117 | ||
|
|
41c1a7e318 | ||
|
|
9d6e6c45c1 | ||
|
|
f711fe6b57 | ||
|
|
94c2a7671c | ||
|
|
4d4682c0e3 | ||
|
|
7fb1c8faad | ||
|
|
ba8e7b9638 | ||
|
|
75ccec7996 | ||
|
|
68d6d8d451 | ||
|
|
0168aede8e | ||
|
|
a05d9be44f | ||
|
|
f95e565884 | ||
|
|
4615fc53ca | ||
|
|
927ab3104d | ||
|
|
cc3743bd43 | ||
|
|
fcbdaab5e3 | ||
|
|
a72acfc535 | ||
|
|
477aa389e6 | ||
|
|
1ada5d7ddf | ||
|
|
dce6c23b33 | ||
|
|
df34d20a21 | ||
|
|
d309558f64 | ||
|
|
128560c4ac | ||
|
|
bff1a37791 | ||
|
|
fcd7dbfa5c | ||
|
|
58386fbf43 | ||
|
|
09251fe24c | ||
|
|
18db9c551d | ||
|
|
c2449c421c | ||
|
|
e28bde9947 | ||
|
|
f287b0b382 | ||
|
|
204b53e7b8 | ||
|
|
0ac6d74536 | ||
|
|
78a3752ade | ||
|
|
9207c2aa68 | ||
|
|
1864edd287 | ||
|
|
9722ca78b2 | ||
|
|
7612df7687 | ||
|
|
cbd06cd25e | ||
|
|
8c8642634d | ||
|
|
afe0116d59 | ||
|
|
b711860d21 | ||
|
|
929fc8bea5 | ||
|
|
a508dce1bf | ||
|
|
f13f07023f | ||
|
|
aac546368f | ||
|
|
c119b1ebef | ||
|
|
df3cfb663c | ||
|
|
a9296229c8 | ||
|
|
9c3b159b95 | ||
|
|
89c1abd1b3 | ||
|
|
10f67e64f9 | ||
|
|
0615fadead | ||
|
|
479f652f90 | ||
|
|
4c988a5a24 | ||
|
|
94498b923e | ||
|
|
d1ea62c3e8 | ||
|
|
8ea0631b82 | ||
|
|
f0c22a770d | ||
|
|
bf3d0e2257 | ||
|
|
9a2b35163e | ||
|
|
4e66b072da | ||
|
|
6b66fea67d | ||
|
|
37a94d9857 | ||
|
|
4aeeb64d30 | ||
|
|
594dc7e24a | ||
|
|
1c5bbba5cf | ||
|
|
c4e3a1aad3 | ||
|
|
3c30b59c3e | ||
|
|
cdf2b3f4e4 | ||
|
|
1153a5ce5a | ||
|
|
9e45a1cd51 | ||
|
|
d4a34fb175 | ||
|
|
c11cd3c14c | ||
|
|
3c5c880a33 | ||
|
|
b03d6dfba9 | ||
|
|
f60ff18b14 | ||
|
|
7e59d784a0 | ||
|
|
92c5dedc76 | ||
|
|
f69b59effc | ||
|
|
4fdf8584ed | ||
|
|
962f4a6558 | ||
|
|
d5ad18db03 | ||
|
|
9d698c76c5 | ||
|
|
db5a3c014a | ||
|
|
cc253f5de9 | ||
|
|
41f94ef154 | ||
|
|
f912130be6 | ||
|
|
a5ab10f3d2 | ||
|
|
6bb492ac23 | ||
|
|
3744ac0a52 | ||
|
|
800b96fe14 | ||
|
|
06a00b74e8 | ||
|
|
27ddf19f3c | ||
|
|
4633376b28 | ||
|
|
8ad1470d08 | ||
|
|
3aec1c3e3f | ||
|
|
feff8b3584 | ||
|
|
b7188f07f4 | ||
|
|
4d8ebcd19c | ||
|
|
81318f0acc | ||
|
|
956406a193 | ||
|
|
0af2b8de73 | ||
|
|
f5112632a3 | ||
|
|
c262eac441 | ||
|
|
d79d3fc7d7 | ||
|
|
108ee7037f | ||
|
|
59246a4c7c | ||
|
|
2205d725f2 | ||
|
|
1ccf206e77 | ||
|
|
db79734bfb | ||
|
|
4b8b492b62 | ||
|
|
755feb4d81 | ||
|
|
4cc2ed842e | ||
|
|
e100402b13 | ||
|
|
45e2f86fe0 | ||
|
|
fdb60240f3 | ||
|
|
08d54d2416 | ||
|
|
e07c2b84d7 | ||
|
|
f2b06324b8 | ||
|
|
ac6ed62ab9 | ||
|
|
7acb513ba6 | ||
|
|
ce8e248b60 | ||
|
|
df8fd1b269 | ||
|
|
4342b7ff55 | ||
|
|
e904486076 | ||
|
|
b2c5623a13 | ||
|
|
652680e801 | ||
|
|
cf3ee7be56 | ||
|
|
b274011720 | ||
|
|
02fe245521 | ||
|
|
a5382b7780 | ||
|
|
fc7f38c7ce | ||
|
|
2657383ea7 | ||
|
|
37a904c299 | ||
|
|
c8a3a00017 | ||
|
|
7382891015 | ||
|
|
75339dccb3 | ||
|
|
4bdb50eeee | ||
|
|
039c061d07 | ||
|
|
f372953256 | ||
|
|
cdc27a3793 | ||
|
|
bbb79880f7 | ||
|
|
dc63b8e7f4 | ||
|
|
b888d9cd17 | ||
|
|
e589e9b259 | ||
|
|
86e746c36b | ||
|
|
ebfcf89a0b | ||
|
|
865a29ed17 | ||
|
|
373a905319 | ||
|
|
27527fe5ca | ||
|
|
e41c3e960d | ||
|
|
076bc58b2a | ||
|
|
b96f15bfc2 | ||
|
|
3bc3896ee7 | ||
|
|
a20216de7a | ||
|
|
a5a4818b67 | ||
|
|
aa8119515f | ||
|
|
3d9b9b97cf | ||
|
|
12aa991df2 | ||
|
|
0ff1727ec0 | ||
|
|
a1c01ded9c | ||
|
|
94a85cb191 | ||
|
|
f45aaea537 | ||
|
|
b43f7702c8 | ||
|
|
7beffb51fc | ||
|
|
3663f8e0ae | ||
|
|
41c81ed066 | ||
|
|
62366aeb95 | ||
|
|
89725f31bf | ||
|
|
f71a6db3ff | ||
|
|
c040305db4 | ||
|
|
d9bf02d9b6 | ||
|
|
318c91b78c | ||
|
|
ebd80a0602 | ||
|
|
306147ddf5 | ||
|
|
7cb62bfc22 | ||
|
|
283fa2b79d | ||
|
|
1e50f7d2b6 | ||
|
|
998c85af13 | ||
|
|
3da598015b | ||
|
|
c1a667c931 | ||
|
|
d5539ce834 | ||
|
|
067cc8ae2b | ||
|
|
c5a2af7811 | ||
|
|
8cf345660c | ||
|
|
da54cfcb3e | ||
|
|
268cd31e38 | ||
|
|
5b2d3910c1 | ||
|
|
08e26175fd | ||
|
|
41b2945ced | ||
|
|
bcf060fab6 | ||
|
|
e9b9835feb | ||
|
|
fa7461685d | ||
|
|
484a70f9b8 | ||
|
|
83a4ac1841 | ||
|
|
1e8da899a3 | ||
|
|
069cde09fb | ||
|
|
bdad6335c4 | ||
|
|
9d72c8b0ad | ||
|
|
faa392af28 | ||
|
|
683ff2ea02 | ||
|
|
9168f65321 | ||
|
|
101e17d6f3 | ||
|
|
b1463d2da1 | ||
|
|
36e730da93 | ||
|
|
e08ced5979 | ||
|
|
84cf685e76 | ||
|
|
fe43296f7f | ||
|
|
34129b83a4 | ||
|
|
b1777c5ad1 | ||
|
|
cc0eb7b908 | ||
|
|
c75ec2e689 | ||
|
|
600c37160b | ||
|
|
512bb96dcb | ||
|
|
90f17e4945 | ||
|
|
d36524c640 | ||
|
|
8397bfbd16 | ||
|
|
1e074605dc | ||
|
|
96c3179f32 | ||
|
|
8dfcf817e4 | ||
|
|
0a120468c0 | ||
|
|
4fa3310887 | ||
|
|
ceab6a146a | ||
|
|
cd7dc52c53 | ||
|
|
28ada6ea8b | ||
|
|
e9a43be9be | ||
|
|
254dbd7400 | ||
|
|
baaa7787af | ||
|
|
ac1d426c51 | ||
|
|
841d223b3b | ||
|
|
e119da8ce2 | ||
|
|
58af7d2a9a | ||
|
|
c09ce25ab6 | ||
|
|
ce86e81aa6 | ||
|
|
bf3650eb1f | ||
|
|
81fcd732c2 | ||
|
|
d46431b564 | ||
|
|
fb3f5e490e | ||
|
|
7442905dd2 | ||
|
|
2526031a5f | ||
|
|
e0f2511cba | ||
|
|
4c39eb32b0 | ||
|
|
c3d11e2ea2 | ||
|
|
ed185f324e | ||
|
|
9a5a45e804 | ||
|
|
8b6202b6a8 | ||
|
|
7c701367c0 |
@@ -24,7 +24,7 @@ parameters:
|
||||
linux-publish-arch-limit:
|
||||
type: enum
|
||||
default: all
|
||||
enum: ["all", "arm", "arm64", "x64", "ia32"]
|
||||
enum: ["all", "arm", "arm64", "x64"]
|
||||
|
||||
run-macos-publish:
|
||||
type: boolean
|
||||
@@ -53,14 +53,8 @@ executors:
|
||||
description: "macOS executor size"
|
||||
type: enum
|
||||
enum: ["macos.x86.medium.gen2", "large"]
|
||||
xcode:
|
||||
description: "xcode version"
|
||||
default: 13.2.1
|
||||
type: enum
|
||||
enum: ["12.4.0", "13.2.1"]
|
||||
|
||||
macos:
|
||||
xcode: << parameters.xcode >>
|
||||
xcode: 13.3.0
|
||||
resource_class: << parameters.size >>
|
||||
|
||||
# Electron Runners
|
||||
@@ -113,12 +107,6 @@ env-unittests: &env-unittests
|
||||
BUILD_TARGET: electron/spec:chromium_unittests
|
||||
TESTS_CONFIG: src/electron/spec/configs/unittests.yml
|
||||
|
||||
# Build targets options.
|
||||
env-ia32: &env-ia32
|
||||
GN_EXTRA_ARGS: 'target_cpu = "x86"'
|
||||
NPM_CONFIG_ARCH: ia32
|
||||
TARGET_ARCH: ia32
|
||||
|
||||
env-arm: &env-arm
|
||||
GN_EXTRA_ARGS: 'target_cpu = "arm"'
|
||||
MKSNAPSHOT_TOOLCHAIN: //build/toolchain/linux:clang_arm
|
||||
@@ -131,6 +119,9 @@ env-apple-silicon: &env-apple-silicon
|
||||
USE_PREBUILT_V8_CONTEXT_SNAPSHOT: 1
|
||||
npm_config_arch: arm64
|
||||
|
||||
env-runner: &env-runner
|
||||
IS_ELECTRON_RUNNER: 1
|
||||
|
||||
env-arm64: &env-arm64
|
||||
GN_EXTRA_ARGS: 'target_cpu = "arm64" fatal_linker_warnings = false enable_linux_installer = false'
|
||||
MKSNAPSHOT_TOOLCHAIN: //build/toolchain/linux:clang_arm64
|
||||
@@ -244,11 +235,20 @@ step-depot-tools-get: &step-depot-tools-get
|
||||
name: Get depot tools
|
||||
command: |
|
||||
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
|
||||
sed -i '' '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
else
|
||||
sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
# Remove swift-format dep from cipd on macOS until we send a patch upstream.
|
||||
cd depot_tools
|
||||
patch gclient.py -R \<<'EOF'
|
||||
676,677c676
|
||||
< packages = dep_value.get('packages', [])
|
||||
< for package in (x for x in packages if "infra/3pp/tools/swift-format" not in x.get('package')):
|
||||
---
|
||||
> for package in dep_value.get('packages', []):
|
||||
EOF
|
||||
fi
|
||||
|
||||
step-depot-tools-add-to-path: &step-depot-tools-add-to-path
|
||||
@@ -346,7 +346,7 @@ step-wait-for-goma: &step-wait-for-goma
|
||||
sleep 5
|
||||
done
|
||||
echo "Goma ready"
|
||||
no_output_timeout: 2m
|
||||
no_output_timeout: 5m
|
||||
|
||||
step-restore-brew-cache: &step-restore-brew-cache
|
||||
restore_cache:
|
||||
@@ -354,14 +354,14 @@ step-restore-brew-cache: &step-restore-brew-cache
|
||||
- /usr/local/Cellar/gnu-tar
|
||||
- /usr/local/bin/gtar
|
||||
keys:
|
||||
- v4-brew-cache-{{ arch }}
|
||||
- v5-brew-cache-{{ arch }}
|
||||
|
||||
step-save-brew-cache: &step-save-brew-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- /usr/local/Cellar/gnu-tar
|
||||
- /usr/local/bin/gtar
|
||||
key: v4-brew-cache-{{ arch }}
|
||||
key: v5-brew-cache-{{ arch }}
|
||||
name: Persisting brew cache
|
||||
|
||||
step-get-more-space-on-mac: &step-get-more-space-on-mac
|
||||
@@ -370,6 +370,7 @@ step-get-more-space-on-mac: &step-get-more-space-on-mac
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
sudo mkdir -p $TMPDIR/del-target
|
||||
|
||||
tmpify() {
|
||||
if [ -d "$1" ]; then
|
||||
sudo mv "$1" $TMPDIR/del-target/$(echo $1|shasum -a 256|head -n1|cut -d " " -f1)
|
||||
@@ -441,9 +442,11 @@ step-get-more-space-on-mac: &step-get-more-space-on-mac
|
||||
background: true
|
||||
|
||||
# On macOS delete all .git directories under src/ expect for
|
||||
# third_party/angle/ because of build time generation of file
|
||||
# third_party/angle/ and third_party/dawn/ because of build time generation of files
|
||||
# gen/angle/commit.h depends on third_party/angle/.git/HEAD
|
||||
# https://chromium-review.googlesource.com/c/angle/angle/+/2074924
|
||||
# and dawn/common/Version_autogen.h depends on third_party/dawn/.git/HEAD
|
||||
# https://dawn-review.googlesource.com/c/dawn/+/83901
|
||||
# TODO: maybe better to always leave out */.git/HEAD file for all targets ?
|
||||
step-delete-git-directories: &step-delete-git-directories
|
||||
run:
|
||||
@@ -451,7 +454,7 @@ step-delete-git-directories: &step-delete-git-directories
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
cd src
|
||||
( find . -type d -name ".git" -not -path "./third_party/angle/*" ) | xargs rm -rf
|
||||
( find . -type d -name ".git" -not -path "./third_party/angle/*" -not -path "./third_party/dawn/*" ) | xargs rm -rf
|
||||
fi
|
||||
|
||||
# On macOS the yarn install command during gclient sync was run on a linux
|
||||
@@ -467,6 +470,13 @@ step-install-npm-deps-on-mac: &step-install-npm-deps-on-mac
|
||||
node script/yarn install
|
||||
fi
|
||||
|
||||
step-install-npm-deps: &step-install-npm-deps
|
||||
run:
|
||||
name: Install node_modules
|
||||
command: |
|
||||
cd src/electron
|
||||
node script/yarn install --frozen-lockfile
|
||||
|
||||
# This step handles the differences between the linux "gclient sync"
|
||||
# and the expected state on macOS
|
||||
step-fix-sync: &step-fix-sync
|
||||
@@ -498,6 +508,7 @@ step-install-signing-cert-on-mac: &step-install-signing-cert-on-mac
|
||||
name: Import and trust self-signed codesigning cert on MacOS
|
||||
command: |
|
||||
if [ "$TARGET_ARCH" != "arm64" ] && [ "`uname`" == "Darwin" ]; then
|
||||
sudo security authorizationdb write com.apple.trust-settings.admin allow
|
||||
cd src/electron
|
||||
./script/codesign/generate-identity.sh
|
||||
fi
|
||||
@@ -536,7 +547,7 @@ step-gn-check: &step-gn-check
|
||||
step-electron-build: &step-electron-build
|
||||
run:
|
||||
name: Electron build
|
||||
no_output_timeout: 30m
|
||||
no_output_timeout: 60m
|
||||
command: |
|
||||
# On arm platforms we generate a cross-arch ffmpeg that ninja does not seem
|
||||
# to realize is not correct / should be rebuilt. We delete it here so it is
|
||||
@@ -577,8 +588,6 @@ step-maybe-electron-dist-strip: &step-maybe-electron-dist-strip
|
||||
if [ "$STRIP_BINARIES" == "true" ] && [ "`uname`" == "Linux" ]; then
|
||||
if [ x"$TARGET_ARCH" == x ]; then
|
||||
target_cpu=x64
|
||||
elif [ "$TARGET_ARCH" == "ia32" ]; then
|
||||
target_cpu=x86
|
||||
else
|
||||
target_cpu="$TARGET_ARCH"
|
||||
fi
|
||||
@@ -628,7 +637,7 @@ step-electron-publish: &step-electron-publish
|
||||
echo 'Uploading Electron release distribution to Azure'
|
||||
script/release/uploaders/upload.py --verbose --UPLOAD_TO_STORAGE
|
||||
else
|
||||
echo 'Uploading Electron release distribution to Github releases'
|
||||
echo 'Uploading Electron release distribution to GitHub releases'
|
||||
script/release/uploaders/upload.py --verbose
|
||||
fi
|
||||
|
||||
@@ -641,6 +650,7 @@ step-persist-data-for-tests: &step-persist-data-for-tests
|
||||
- src/out/Default/mksnapshot.zip
|
||||
- src/out/Default/chromedriver.zip
|
||||
- src/out/Default/gen/node_headers
|
||||
- src/out/Default/overlapped-checker
|
||||
- src/out/ffmpeg/ffmpeg.zip
|
||||
- src/electron
|
||||
- src/third_party/electron_node
|
||||
@@ -667,13 +677,6 @@ step-electron-dist-unzip: &step-electron-dist-unzip
|
||||
# passed.
|
||||
unzip -:o dist.zip
|
||||
|
||||
step-ffmpeg-unzip: &step-ffmpeg-unzip
|
||||
run:
|
||||
name: Unzip ffmpeg.zip
|
||||
command: |
|
||||
cd src/out/ffmpeg
|
||||
unzip -:o ffmpeg.zip
|
||||
|
||||
step-mksnapshot-unzip: &step-mksnapshot-unzip
|
||||
run:
|
||||
name: Unzip mksnapshot.zip
|
||||
@@ -702,13 +705,6 @@ step-ffmpeg-build: &step-ffmpeg-build
|
||||
cd src
|
||||
ninja -C out/ffmpeg electron:electron_ffmpeg_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
|
||||
step-verify-ffmpeg: &step-verify-ffmpeg
|
||||
run:
|
||||
name: Verify ffmpeg
|
||||
command: |
|
||||
cd src
|
||||
python electron/script/verify-ffmpeg.py --source-root "$PWD" --build-dir out/Default --ffmpeg-path out/ffmpeg
|
||||
|
||||
step-verify-mksnapshot: &step-verify-mksnapshot
|
||||
run:
|
||||
name: Verify mksnapshot
|
||||
@@ -901,7 +897,7 @@ step-restore-out-cache: &step-restore-out-cache
|
||||
paths:
|
||||
- ./src/out/Default
|
||||
keys:
|
||||
- v9-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
|
||||
- v10-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
|
||||
name: Restoring out cache
|
||||
|
||||
step-set-git-cache-path: &step-set-git-cache-path
|
||||
@@ -925,7 +921,7 @@ step-save-out-cache: &step-save-out-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- ./src/out/Default
|
||||
key: v9-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
|
||||
key: v10-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
|
||||
name: Persisting out cache
|
||||
|
||||
step-run-electron-only-hooks: &step-run-electron-only-hooks
|
||||
@@ -987,9 +983,16 @@ step-ts-compile: &step-ts-compile
|
||||
run:
|
||||
name: Run TS/JS compile on doc only change
|
||||
command: |
|
||||
cd src
|
||||
ninja -C out/Default electron:default_app_js -j $NUMBER_OF_NINJA_PROCESSES
|
||||
ninja -C out/Default electron:electron_js2c -j $NUMBER_OF_NINJA_PROCESSES
|
||||
cd src/electron
|
||||
node script/yarn create-typescript-definitions
|
||||
node script/yarn tsc -p tsconfig.default_app.json --noEmit
|
||||
for f in build/webpack/*.js
|
||||
do
|
||||
out="${f:29}"
|
||||
if [ "$out" != "base.js" ]; then
|
||||
node script/yarn webpack --config $f --output-filename=$out --output-path=./.tmp --env.mode=development
|
||||
fi
|
||||
done
|
||||
|
||||
# List of all steps.
|
||||
steps-electron-gn-check: &steps-electron-gn-check
|
||||
@@ -997,99 +1000,33 @@ steps-electron-gn-check: &steps-electron-gn-check
|
||||
- *step-checkout-electron
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- install-python2-mac
|
||||
- *step-setup-env-for-build
|
||||
- *step-setup-goma-for-build
|
||||
- *step-generate-deps-hash
|
||||
- *step-touch-sync-done
|
||||
- maybe-restore-portaled-src-cache
|
||||
- *step-wait-for-goma
|
||||
- *step-gn-gen-default
|
||||
- *step-gn-check
|
||||
- run:
|
||||
name: Ensure src checkout worked
|
||||
command: |
|
||||
if [ ! -d "src/third_party/blink" ]; then
|
||||
echo src cache was not restored for an unknown reason
|
||||
exit 1
|
||||
fi
|
||||
- run:
|
||||
name: Wipe Electron
|
||||
command: rm -rf src/electron
|
||||
- *step-checkout-electron
|
||||
|
||||
steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-change
|
||||
steps:
|
||||
# Checkout - Copied from steps-checkout
|
||||
- *step-checkout-electron
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
- *step-install-gnutar-on-mac
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-setup-goma-for-build
|
||||
- *step-generate-deps-hash
|
||||
- *step-touch-sync-done
|
||||
- maybe-restore-portaled-src-cache
|
||||
- *step-maybe-restore-git-cache
|
||||
- *step-set-git-cache-path
|
||||
# This sync call only runs if .circle-sync-done is an EMPTY file
|
||||
- *step-gclient-sync
|
||||
# These next few steps reset Electron to the correct commit regardless of which cache was restored
|
||||
- run:
|
||||
name: Wipe Electron
|
||||
command: rm -rf src/electron
|
||||
- *step-checkout-electron
|
||||
- *step-run-electron-only-hooks
|
||||
- *step-generate-deps-hash-cleanly
|
||||
- *step-mark-sync-done
|
||||
- *step-minimize-workspace-size-from-checkout
|
||||
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-setup-env-for-build
|
||||
- *step-wait-for-goma
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-install-npm-deps-on-mac
|
||||
- *step-fix-sync
|
||||
- *step-gn-gen-default
|
||||
- *step-install-npm-deps
|
||||
|
||||
#Compile ts/js to verify doc change didn't break anything
|
||||
- *step-ts-compile
|
||||
|
||||
steps-native-tests: &steps-native-tests
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-setup-env-for-build
|
||||
- *step-setup-goma-for-build
|
||||
- *step-wait-for-goma
|
||||
- *step-gn-gen-default
|
||||
|
||||
- run:
|
||||
name: Build tests
|
||||
command: |
|
||||
cd src
|
||||
ninja -C out/Default $BUILD_TARGET
|
||||
- *step-show-goma-stats
|
||||
|
||||
- *step-setup-linux-for-headless-testing
|
||||
- run:
|
||||
name: Run tests
|
||||
command: |
|
||||
mkdir test_results
|
||||
python src/electron/script/native-tests.py run \
|
||||
--config $TESTS_CONFIG \
|
||||
--tests-dir src/out/Default \
|
||||
--output-dir test_results \
|
||||
$TESTS_ARGS
|
||||
|
||||
- store_artifacts:
|
||||
path: test_results
|
||||
destination: test_results # Put it in the root folder.
|
||||
- store_test_results:
|
||||
path: test_results
|
||||
|
||||
steps-verify-ffmpeg: &steps-verify-ffmpeg
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-electron-dist-unzip
|
||||
- *step-ffmpeg-unzip
|
||||
- *step-setup-linux-for-headless-testing
|
||||
|
||||
- *step-verify-ffmpeg
|
||||
- *step-maybe-notify-slack-failure
|
||||
|
||||
steps-tests: &steps-tests
|
||||
steps:
|
||||
- attach_workspace:
|
||||
@@ -1101,6 +1038,7 @@ steps-tests: &steps-tests
|
||||
- *step-setup-linux-for-headless-testing
|
||||
- *step-restore-brew-cache
|
||||
- *step-fix-known-hosts-linux
|
||||
- install-python2-mac
|
||||
- *step-install-signing-cert-on-mac
|
||||
|
||||
- run:
|
||||
@@ -1190,6 +1128,31 @@ steps-test-node: &steps-test-node
|
||||
|
||||
# Command Aliases
|
||||
commands:
|
||||
install-python2-mac:
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v2.7.18-python-cache-{{ arch }}
|
||||
name: Restore python cache
|
||||
- run:
|
||||
name: Install python2 on macos
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ] && [ "$IS_ELECTRON_RUNNER" != "1" ]; then
|
||||
if [ ! -f "python-downloads/python-2.7.18-macosx10.9.pkg" ]; then
|
||||
mkdir python-downloads
|
||||
echo 'Downloading Python 2.7.18'
|
||||
curl -O https://dev-cdn.electronjs.org/python/python-2.7.18-macosx10.9.pkg
|
||||
mv python-2.7.18-macosx10.9.pkg python-downloads
|
||||
else
|
||||
echo 'Using Python install from cache'
|
||||
fi
|
||||
sudo installer -pkg python-downloads/python-2.7.18-macosx10.9.pkg -target /
|
||||
fi
|
||||
- save_cache:
|
||||
paths:
|
||||
- python-downloads
|
||||
key: v2.7.18-python-cache-{{ arch }}
|
||||
name: Persisting python cache
|
||||
maybe-restore-portaled-src-cache:
|
||||
parameters:
|
||||
halt-if-successful:
|
||||
@@ -1245,6 +1208,7 @@ commands:
|
||||
mv_if_exist src/out/Default/hunspell_dictionaries.zip
|
||||
mv_if_exist src/cross-arch-snapshots
|
||||
mv_if_exist src/out/electron_ninja_log
|
||||
mv_if_exist src/out/Default/.ninja_log
|
||||
when: always
|
||||
- store_artifacts:
|
||||
path: generated_artifacts
|
||||
@@ -1300,8 +1264,6 @@ commands:
|
||||
target_os=linux
|
||||
if [ x"$TARGET_ARCH" == x ]; then
|
||||
target_cpu=x64
|
||||
elif [ "$TARGET_ARCH" == "ia32" ]; then
|
||||
target_cpu=x86
|
||||
else
|
||||
target_cpu="$TARGET_ARCH"
|
||||
fi
|
||||
@@ -1357,6 +1319,7 @@ commands:
|
||||
- run: rm -rf src/electron
|
||||
- *step-restore-brew-cache
|
||||
- *step-install-gnutar-on-mac
|
||||
- install-python2-mac
|
||||
- *step-save-brew-cache
|
||||
- when:
|
||||
condition: << parameters.build >>
|
||||
@@ -1471,7 +1434,7 @@ commands:
|
||||
- *step-electron-build
|
||||
- *step-maybe-electron-dist-strip
|
||||
- step-electron-dist-build:
|
||||
additional-targets: shell_browser_ui_unittests third_party/electron_node:headers electron:hunspell_dictionaries_zip
|
||||
additional-targets: shell_browser_ui_unittests third_party/electron_node:headers third_party/electron_node:overlapped-checker electron:hunspell_dictionaries_zip
|
||||
|
||||
- *step-show-goma-stats
|
||||
|
||||
@@ -1548,6 +1511,7 @@ commands:
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
- install-python2-mac
|
||||
- *step-get-more-space-on-mac
|
||||
- when:
|
||||
condition: << parameters.checkout >>
|
||||
@@ -1607,7 +1571,7 @@ jobs:
|
||||
name: linux-docker
|
||||
size: medium
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-testing-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
<<: *steps-electron-ts-compile-for-doc-change
|
||||
@@ -1744,44 +1708,6 @@ jobs:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
linux-ia32-testing:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: xlarge
|
||||
environment:
|
||||
<<: *env-global
|
||||
<<: *env-ia32
|
||||
<<: *env-testing-build
|
||||
<<: *env-ninja-status
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: true
|
||||
checkout: true
|
||||
use-out-cache: false
|
||||
|
||||
linux-ia32-publish:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: 2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-ia32
|
||||
<<: *env-release-build
|
||||
<<: *env-32bit-release
|
||||
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- run: echo running
|
||||
- when:
|
||||
condition:
|
||||
or:
|
||||
- equal: ["all", << pipeline.parameters.linux-publish-arch-limit >>]
|
||||
- equal: ["ia32", << pipeline.parameters.linux-publish-arch-limit >>]
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
linux-arm-testing:
|
||||
executor:
|
||||
@@ -1906,7 +1832,7 @@ jobs:
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
||||
<<: *steps-electron-gn-check
|
||||
|
||||
osx-publish-x64-skip-checkout:
|
||||
osx-publish-x64:
|
||||
executor:
|
||||
name: macos
|
||||
size: macos.x86.medium.gen2
|
||||
@@ -1927,7 +1853,7 @@ jobs:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
osx-publish-arm64-skip-checkout:
|
||||
osx-publish-arm64:
|
||||
executor:
|
||||
name: macos
|
||||
size: macos.x86.medium.gen2
|
||||
@@ -1997,7 +1923,7 @@ jobs:
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
||||
<<: *steps-electron-gn-check
|
||||
|
||||
mas-publish-x64-skip-checkout:
|
||||
mas-publish-x64:
|
||||
executor:
|
||||
name: macos
|
||||
size: macos.x86.medium.gen2
|
||||
@@ -2018,7 +1944,7 @@ jobs:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
mas-publish-arm64-skip-checkout:
|
||||
mas-publish-arm64:
|
||||
executor:
|
||||
name: macos
|
||||
size: macos.x86.medium.gen2
|
||||
@@ -2104,61 +2030,6 @@ jobs:
|
||||
<<: *env-stack-dumping
|
||||
<<: *steps-test-node
|
||||
|
||||
linux-x64-verify-ffmpeg:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: medium
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-headless-testing
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-verify-ffmpeg
|
||||
|
||||
linux-ia32-testing-tests:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: medium
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-ia32
|
||||
<<: *env-headless-testing
|
||||
<<: *env-stack-dumping
|
||||
parallelism: 3
|
||||
<<: *steps-tests
|
||||
|
||||
linux-ia32-testing-nan:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: medium
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-ia32
|
||||
<<: *env-headless-testing
|
||||
<<: *env-stack-dumping
|
||||
<<: *steps-test-nan
|
||||
|
||||
linux-ia32-testing-node:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: xlarge
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-ia32
|
||||
<<: *env-headless-testing
|
||||
<<: *env-stack-dumping
|
||||
<<: *steps-test-node
|
||||
|
||||
linux-ia32-verify-ffmpeg:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: medium
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-ia32
|
||||
<<: *env-headless-testing
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-verify-ffmpeg
|
||||
|
||||
linux-arm-testing-tests:
|
||||
executor: linux-arm
|
||||
environment:
|
||||
@@ -2180,7 +2051,6 @@ jobs:
|
||||
osx-testing-x64-tests:
|
||||
executor:
|
||||
name: macos
|
||||
xcode: 12.4.0
|
||||
size: macos.x86.medium.gen2
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
@@ -2194,12 +2064,12 @@ jobs:
|
||||
<<: *env-mac-large
|
||||
<<: *env-stack-dumping
|
||||
<<: *env-apple-silicon
|
||||
<<: *env-runner
|
||||
<<: *steps-tests
|
||||
|
||||
mas-testing-x64-tests:
|
||||
executor:
|
||||
name: macos
|
||||
xcode: 12.4.0
|
||||
size: macos.x86.medium.gen2
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
@@ -2213,19 +2083,9 @@ jobs:
|
||||
<<: *env-mac-large
|
||||
<<: *env-stack-dumping
|
||||
<<: *env-apple-silicon
|
||||
<<: *env-runner
|
||||
<<: *steps-tests
|
||||
|
||||
# Layer 4: Summary.
|
||||
linux-release-summary:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: medium
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-send-slack-notifications
|
||||
steps:
|
||||
- *step-maybe-notify-slack-success
|
||||
|
||||
# List all workflows
|
||||
workflows:
|
||||
docs-only:
|
||||
@@ -2242,8 +2102,6 @@ workflows:
|
||||
jobs:
|
||||
- linux-x64-publish:
|
||||
context: release-env
|
||||
- linux-ia32-publish:
|
||||
context: release-env
|
||||
- linux-arm-publish:
|
||||
context: release-env
|
||||
- linux-arm64-publish:
|
||||
@@ -2253,19 +2111,19 @@ workflows:
|
||||
when: << pipeline.parameters.run-macos-publish >>
|
||||
jobs:
|
||||
- mac-checkout
|
||||
- osx-publish-x64-skip-checkout:
|
||||
- osx-publish-x64:
|
||||
requires:
|
||||
- mac-checkout
|
||||
context: release-env
|
||||
- mas-publish-x64-skip-checkout:
|
||||
- mas-publish-x64:
|
||||
requires:
|
||||
- mac-checkout
|
||||
context: release-env
|
||||
- osx-publish-arm64-skip-checkout:
|
||||
- osx-publish-arm64:
|
||||
requires:
|
||||
- mac-checkout
|
||||
context: release-env
|
||||
- mas-publish-arm64-skip-checkout:
|
||||
- mas-publish-arm64:
|
||||
requires:
|
||||
- mac-checkout
|
||||
context: release-env
|
||||
@@ -2302,18 +2160,6 @@ workflows:
|
||||
- linux-x64-testing-node:
|
||||
requires:
|
||||
- linux-x64-testing
|
||||
- linux-ia32-testing:
|
||||
requires:
|
||||
- linux-make-src-cache
|
||||
- linux-ia32-testing-tests:
|
||||
requires:
|
||||
- linux-ia32-testing
|
||||
- linux-ia32-testing-nan:
|
||||
requires:
|
||||
- linux-ia32-testing
|
||||
- linux-ia32-testing-node:
|
||||
requires:
|
||||
- linux-ia32-testing
|
||||
- linux-arm-testing:
|
||||
requires:
|
||||
- linux-make-src-cache
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": "standard",
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint"],
|
||||
|
||||
5
.git-blame-ignore-revs
Normal file
@@ -0,0 +1,5 @@
|
||||
# Atom --> Electron rename
|
||||
d9321f4df751fa32813fab1b6387bbd61bd681d0
|
||||
34c4c8d5088fa183f56baea28809de6f2a427e02
|
||||
# Enable JS Semicolons
|
||||
5d657dece4102e5e5304d42e8004b6ad64c0fcda
|
||||
9
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -17,8 +17,11 @@ body:
|
||||
- type: input
|
||||
attributes:
|
||||
label: Electron Version
|
||||
description: What version of Electron are you using?
|
||||
placeholder: 12.0.0
|
||||
description: |
|
||||
What version of Electron are you using?
|
||||
|
||||
Note: Please only report issues for [currently supported versions of Electron](https://www.electronjs.org/docs/latest/tutorial/support#currently-supported-versions).
|
||||
placeholder: 17.0.0
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
@@ -53,7 +56,7 @@ body:
|
||||
attributes:
|
||||
label: Last Known Working Electron version
|
||||
description: What is the last version of Electron this worked in, if applicable?
|
||||
placeholder: 11.0.0
|
||||
placeholder: 16.0.0
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
|
||||
166
.github/workflows/electron_woa_testing.yml
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
name: Electron WOA Testing
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: '**'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
appveyor_job_id:
|
||||
description: 'Job Id of Appveyor WOA job to test'
|
||||
type: text
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
electron-woa-testing:
|
||||
|
||||
runs-on: [self-hosted, woa]
|
||||
|
||||
permissions:
|
||||
checks: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: LouisBrunner/checks-action@v1.1.1
|
||||
if: ${{ github.event_name == 'push' && github.repository == 'electron/electron' }}
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: electron-woa-testing
|
||||
status: in_progress
|
||||
- name: Clean Workspace
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
Remove-Item * -Recurse -Force
|
||||
shell: powershell
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
with:
|
||||
path: src\electron
|
||||
fetch-depth: 0
|
||||
- name: Yarn install
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
cd src\electron
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
- name: Download and extract dist.zip for test
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
$localArtifactPath = "$pwd\dist.zip"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/dist.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -osrc\out\Default -y $localArtifactPath
|
||||
shell: powershell
|
||||
- name: Download and extract native test executables for test
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
$localArtifactPath = "src\out\Default\shell_browser_ui_unittests.exe"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/shell_browser_ui_unittests.exe"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
shell: powershell
|
||||
- name: Download and extract ffmpeg.zip for test
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
$localArtifactPath = "$pwd\ffmpeg.zip"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/ffmpeg.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -osrc\out\ffmpeg $localArtifactPath
|
||||
shell: powershell
|
||||
- name: Download node headers for test
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
$localArtifactPath = "src\node_headers.zip"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/node_headers.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
cd src
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y node_headers.zip
|
||||
shell: powershell
|
||||
- name: Download electron.lib for test
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
$localArtifactPath = "src\out\Default\electron.lib"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/electron.lib"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
shell: powershell
|
||||
# Uncomment the following block if pdb files are needed to debug issues
|
||||
# - name: Download pdb files for detailed stacktraces
|
||||
# if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
# run: |
|
||||
# try {
|
||||
# $localArtifactPath = "src\pdb.zip"
|
||||
# $serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/pdb.zip"
|
||||
# Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
# cd src
|
||||
# & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y pdb.zip
|
||||
# } catch {
|
||||
# Write-Host "There was an exception encountered while downloading pdb files:" $_.Exception.Message
|
||||
# } finally {
|
||||
# $global:LASTEXITCODE = 0
|
||||
# }
|
||||
# shell: powershell
|
||||
- name: Setup node headers
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
New-Item src\out\Default\gen\node_headers\Release -Type directory
|
||||
Copy-Item -path src\out\Default\electron.lib -destination src\out\Default\gen\node_headers\Release\node.lib
|
||||
shell: powershell
|
||||
- name: Run Electron Main process tests
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
cd src
|
||||
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
set npm_config_arch=arm64
|
||||
cd electron
|
||||
node script/yarn test --runners=main --enable-logging --disable-features=CalculateNativeWinOcclusion
|
||||
env:
|
||||
ELECTRON_ENABLE_STACK_DUMPING: true
|
||||
ELECTRON_OUT_DIR: Default
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
|
||||
- name: Run Electron Remote based tests
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && (success() || failure()) }}
|
||||
run: |
|
||||
cd src
|
||||
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
set npm_config_arch=arm64
|
||||
cd electron
|
||||
node script/yarn test --runners=remote --enable-logging --disable-features=CalculateNativeWinOcclusion
|
||||
env:
|
||||
ELECTRON_OUT_DIR: Default
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
|
||||
- name: Publish Test Results
|
||||
uses: EnricoMi/publish-unit-test-result-action/composite@v1
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && (success() || failure()) }}
|
||||
with:
|
||||
files: "src/junit/**/*.xml"
|
||||
check_name: "electron-woa-testing"
|
||||
- name: Verify ffmpeg
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
cd src
|
||||
echo "Verifying non proprietary ffmpeg"
|
||||
python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
|
||||
shell: cmd
|
||||
- name: Kill processes left running from last test run
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && (success() || failure()) || cancelled() }}
|
||||
run: |
|
||||
Get-Process | Where Name -Like "electron*" | Stop-Process
|
||||
Get-Process | Where Name -Like "msedge*" | Stop-Process
|
||||
shell: powershell
|
||||
- name: Delete user app data directories
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && (success() || failure()) || cancelled() }}
|
||||
run: |
|
||||
Remove-Item -path $env:APPDATA/Electron* -Recurse -Force -ErrorAction Ignore
|
||||
shell: powershell
|
||||
- uses: LouisBrunner/checks-action@v1.1.1
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && (success() || failure()) || cancelled() }}
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: electron-woa-testing
|
||||
conclusion: "${{ job.status }}"
|
||||
31
.github/workflows/release_dependency_versions.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: Trigger Major Release Dependency Updates
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
jobs:
|
||||
check_tag:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Check Tag
|
||||
run: |
|
||||
if [[ ${{ github.event.ref }} =~ ^refs/tags/v[0-9]+\.0\.0$ ]]; then
|
||||
echo ::set-output name=should_release::true
|
||||
fi
|
||||
trigger:
|
||||
runs-on: ubuntu-latest
|
||||
needs: check_tag
|
||||
if: jobs.check_tag.outputs.should_release == 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Trigger New chromedriver Release
|
||||
run: |
|
||||
gh api /repos/:owner/chromedriver/actions/workflows/release.yml/dispatches --input - <<< '{"ref":"main","inputs":{"version":"${{ github.event.release.tag_name }}"}}'
|
||||
- name: Trigger New mksnapshot Release
|
||||
run: |
|
||||
gh api /repos/:owner/mksnapshot/actions/workflows/release.yml/dispatches --input - <<< '{"ref":"main","inputs":{"version":"${{ github.event.release.tag_name }}"}}'
|
||||
6
.github/workflows/semantic.yml
vendored
@@ -7,8 +7,14 @@ on:
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
main:
|
||||
permissions:
|
||||
pull-requests: read # for amannn/action-semantic-pull-request to analyze PRs
|
||||
statuses: write # for amannn/action-semantic-pull-request to mark status of analyzed PR
|
||||
name: Validate PR Title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
1
.husky/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
_
|
||||
@@ -23,7 +23,5 @@
|
||||
"br_spaces": 0
|
||||
},
|
||||
"single-h1": false,
|
||||
"no-inline-html": {
|
||||
"allowed_elements": ["br"]
|
||||
}
|
||||
"no-inline-html": false
|
||||
}
|
||||
|
||||
98
BUILD.gn
@@ -37,7 +37,7 @@ if (is_mac) {
|
||||
import("build/rules.gni")
|
||||
|
||||
assert(
|
||||
mac_deployment_target == "10.11.0",
|
||||
mac_deployment_target == "10.13",
|
||||
"Chromium has updated the mac_deployment_target, please update this assert, update the supported versions documentation (docs/tutorial/support.md) and flag this as a breaking change")
|
||||
}
|
||||
|
||||
@@ -79,8 +79,18 @@ if (is_linux) {
|
||||
]
|
||||
}
|
||||
|
||||
# Generates electron_gtk_stubs.h header which contains
|
||||
# stubs for extracting function ptrs from the gtk library.
|
||||
# Function signatures for which stubs are required should be
|
||||
# declared in electron_gtk.sigs, currently this file contains
|
||||
# signatures for the functions used with native file chooser
|
||||
# implementation. In future, this file can be extended to contain
|
||||
# gtk4 stubs to switch gtk version in runtime.
|
||||
generate_stubs("electron_gtk_stubs") {
|
||||
sigs = [ "shell/browser/ui/electron_gtk.sigs" ]
|
||||
sigs = [
|
||||
"shell/browser/ui/electron_gdk_pixbuf.sigs",
|
||||
"shell/browser/ui/electron_gtk.sigs",
|
||||
]
|
||||
extra_header = "shell/browser/ui/electron_gtk.fragment"
|
||||
output_name = "electron_gtk_stubs"
|
||||
public_deps = [ "//ui/gtk:gtk_config" ]
|
||||
@@ -125,7 +135,7 @@ config("electron_lib_config") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
||||
|
||||
# We geneate the definitions twice here, once in //electron/electron.d.ts
|
||||
# We generate the definitions twice here, once in //electron/electron.d.ts
|
||||
# and once in $target_gen_dir
|
||||
# The one in $target_gen_dir is used for the actual TSC build later one
|
||||
# and the one in //electron/electron.d.ts is used by your IDE (vscode)
|
||||
@@ -359,10 +369,12 @@ source_set("electron_lib") {
|
||||
"shell/common/api:mojo",
|
||||
"//base:base_static",
|
||||
"//base/allocator:buildflags",
|
||||
"//chrome:strings",
|
||||
"//chrome/app:command_ids",
|
||||
"//chrome/app/resources:platform_locale_settings",
|
||||
"//components/autofill/core/common:features",
|
||||
"//components/certificate_transparency",
|
||||
"//components/embedder_support:browser_util",
|
||||
"//components/language/core/browser",
|
||||
"//components/net_log",
|
||||
"//components/network_hints/browser",
|
||||
@@ -378,6 +390,7 @@ source_set("electron_lib") {
|
||||
"//components/user_prefs",
|
||||
"//components/viz/host",
|
||||
"//components/viz/service",
|
||||
"//components/webrtc",
|
||||
"//content/public/browser",
|
||||
"//content/public/child",
|
||||
"//content/public/gpu",
|
||||
@@ -510,6 +523,8 @@ source_set("electron_lib") {
|
||||
"StoreKit.framework",
|
||||
]
|
||||
|
||||
weak_frameworks = [ "QuickLookThumbnailing.framework" ]
|
||||
|
||||
sources += [
|
||||
"shell/browser/ui/views/autofill_popup_view.cc",
|
||||
"shell/browser/ui/views/autofill_popup_view.h",
|
||||
@@ -551,7 +566,8 @@ source_set("electron_lib") {
|
||||
"//ui/base/ime/linux",
|
||||
"//ui/events/devices/x11",
|
||||
"//ui/events/platform/x11",
|
||||
"//ui/gtk",
|
||||
"//ui/linux:linux_ui",
|
||||
"//ui/linux:linux_ui_factory",
|
||||
"//ui/views/controls/webview",
|
||||
"//ui/wm",
|
||||
]
|
||||
@@ -657,8 +673,6 @@ source_set("electron_lib") {
|
||||
|
||||
if (enable_basic_printing) {
|
||||
sources += [
|
||||
"shell/browser/printing/print_preview_message_handler.cc",
|
||||
"shell/browser/printing/print_preview_message_handler.h",
|
||||
"shell/browser/printing/print_view_manager_electron.cc",
|
||||
"shell/browser/printing/print_view_manager_electron.h",
|
||||
"shell/renderer/printing/print_render_frame_helper_delegate.cc",
|
||||
@@ -706,7 +720,7 @@ source_set("electron_lib") {
|
||||
"//components/pdf/browser:interceptors",
|
||||
"//components/pdf/common",
|
||||
"//components/pdf/renderer",
|
||||
"//pdf:pdf_ppapi",
|
||||
"//pdf",
|
||||
]
|
||||
sources += [
|
||||
"shell/browser/electron_pdf_web_contents_helper_client.cc",
|
||||
@@ -716,14 +730,6 @@ source_set("electron_lib") {
|
||||
|
||||
sources += get_target_outputs(":electron_fuses")
|
||||
|
||||
if (is_win && enable_win_dark_mode_window_ui) {
|
||||
sources += [
|
||||
"shell/browser/win/dark_mode.cc",
|
||||
"shell/browser/win/dark_mode.h",
|
||||
]
|
||||
libs += [ "uxtheme.lib" ]
|
||||
}
|
||||
|
||||
if (allow_runtime_configurable_key_storage) {
|
||||
defines += [ "ALLOW_RUNTIME_CONFIGURABLE_KEY_STORAGE" ]
|
||||
}
|
||||
@@ -808,16 +814,11 @@ if (is_mac) {
|
||||
# Add the SwiftShader .dylibs in the Libraries directory of the Framework.
|
||||
bundle_data("electron_swiftshader_binaries") {
|
||||
sources = [
|
||||
"$root_out_dir/egl_intermediates/libswiftshader_libEGL.dylib",
|
||||
"$root_out_dir/egl_intermediates/libswiftshader_libGLESv2.dylib",
|
||||
"$root_out_dir/vk_intermediates/libvk_swiftshader.dylib",
|
||||
"$root_out_dir/vk_intermediates/vk_swiftshader_icd.json",
|
||||
]
|
||||
outputs = [ "{{bundle_contents_dir}}/Libraries/{{source_file_part}}" ]
|
||||
public_deps = [
|
||||
"//ui/gl:swiftshader_egl_library_copy",
|
||||
"//ui/gl:swiftshader_vk_library_copy",
|
||||
]
|
||||
public_deps = [ "//ui/gl:swiftshader_vk_library_copy" ]
|
||||
}
|
||||
}
|
||||
group("electron_angle_library") {
|
||||
@@ -906,7 +907,10 @@ if (is_mac) {
|
||||
assert(defined(invoker.helper_name_suffix))
|
||||
|
||||
output_name = electron_helper_name + invoker.helper_name_suffix
|
||||
deps = [ ":electron_framework+link" ]
|
||||
deps = [
|
||||
":electron_framework+link",
|
||||
"//base/allocator:early_zone_registration_mac",
|
||||
]
|
||||
if (!is_mas_build) {
|
||||
deps += [ "//sandbox/mac:seatbelt" ]
|
||||
}
|
||||
@@ -1014,14 +1018,14 @@ if (is_mac) {
|
||||
action("electron_app_lproj_dirs") {
|
||||
outputs = []
|
||||
|
||||
foreach(locale, locales_as_mac_outputs) {
|
||||
foreach(locale, locales_as_apple_outputs) {
|
||||
outputs += [ "$target_gen_dir/app_infoplist_strings/$locale.lproj" ]
|
||||
}
|
||||
script = "build/mac/make_locale_dirs.py"
|
||||
args = rebase_path(outputs)
|
||||
}
|
||||
|
||||
foreach(locale, locales_as_mac_outputs) {
|
||||
foreach(locale, locales_as_apple_outputs) {
|
||||
bundle_data("electron_app_strings_${locale}_bundle_data") {
|
||||
sources = [ "$target_gen_dir/app_infoplist_strings/$locale.lproj" ]
|
||||
outputs = [ "{{bundle_resources_dir}}/$locale.lproj" ]
|
||||
@@ -1030,7 +1034,7 @@ if (is_mac) {
|
||||
}
|
||||
group("electron_app_strings_bundle_data") {
|
||||
public_deps = []
|
||||
foreach(locale, locales_as_mac_outputs) {
|
||||
foreach(locale, locales_as_apple_outputs) {
|
||||
public_deps += [ ":electron_app_strings_${locale}_bundle_data" ]
|
||||
}
|
||||
}
|
||||
@@ -1066,6 +1070,7 @@ if (is_mac) {
|
||||
":electron_app_plist",
|
||||
":electron_app_resources",
|
||||
":electron_fuses",
|
||||
"//base/allocator:early_zone_registration_mac",
|
||||
"//electron/buildflags",
|
||||
]
|
||||
if (is_mas_build) {
|
||||
@@ -1109,21 +1114,18 @@ if (is_mac) {
|
||||
deps = [ ":electron_app" ]
|
||||
}
|
||||
|
||||
extract_symbols("swiftshader_egl_syms") {
|
||||
binary = "$root_out_dir/libswiftshader_libEGL.dylib"
|
||||
extract_symbols("egl_syms") {
|
||||
binary = "$root_out_dir/libEGL.dylib"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/libswiftshader_libEGL.dylib.dSYM/Contents/Resources/DWARF/libswiftshader_libEGL.dylib"
|
||||
deps =
|
||||
[ "//third_party/swiftshader/src/OpenGL/libEGL:swiftshader_libEGL" ]
|
||||
dsym_file = "$root_out_dir/libEGL.dylib.dSYM/Contents/Resources/DWARF/libEGL.dylib"
|
||||
deps = [ "//third_party/angle:libEGL" ]
|
||||
}
|
||||
|
||||
extract_symbols("swiftshader_gles_syms") {
|
||||
binary = "$root_out_dir/libswiftshader_libGLESv2.dylib"
|
||||
extract_symbols("gles_syms") {
|
||||
binary = "$root_out_dir/libGLESv2.dylib"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/libswiftshader_libGLESv2.dylib.dSYM/Contents/Resources/DWARF/libswiftshader_libGLESv2.dylib"
|
||||
deps = [
|
||||
"//third_party/swiftshader/src/OpenGL/libGLESv2:swiftshader_libGLESv2",
|
||||
]
|
||||
dsym_file = "$root_out_dir/libGLESv2.dylib.dSYM/Contents/Resources/DWARF/libGLESv2.dylib"
|
||||
deps = [ "//third_party/angle:libGLESv2" ]
|
||||
}
|
||||
|
||||
extract_symbols("crashpad_handler_syms") {
|
||||
@@ -1135,10 +1137,10 @@ if (is_mac) {
|
||||
|
||||
group("electron_symbols") {
|
||||
deps = [
|
||||
":egl_syms",
|
||||
":electron_app_syms",
|
||||
":electron_framework_syms",
|
||||
":swiftshader_egl_syms",
|
||||
":swiftshader_gles_syms",
|
||||
":gles_syms",
|
||||
]
|
||||
|
||||
if (!is_mas_build) {
|
||||
@@ -1297,27 +1299,23 @@ if (is_mac) {
|
||||
deps = [ ":electron_app" ]
|
||||
}
|
||||
|
||||
extract_symbols("swiftshader_egl_symbols") {
|
||||
binary = "$root_out_dir/swiftshader/libEGL$_target_shared_library_suffix"
|
||||
extract_symbols("egl_symbols") {
|
||||
binary = "$root_out_dir/libEGL$_target_shared_library_suffix"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
deps =
|
||||
[ "//third_party/swiftshader/src/OpenGL/libEGL:swiftshader_libEGL" ]
|
||||
deps = [ "//third_party/angle:libEGL" ]
|
||||
}
|
||||
|
||||
extract_symbols("swiftshader_gles_symbols") {
|
||||
binary =
|
||||
"$root_out_dir/swiftshader/libGLESv2$_target_shared_library_suffix"
|
||||
extract_symbols("gles_symbols") {
|
||||
binary = "$root_out_dir/libGLESv2$_target_shared_library_suffix"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
deps = [
|
||||
"//third_party/swiftshader/src/OpenGL/libGLESv2:swiftshader_libGLESv2",
|
||||
]
|
||||
deps = [ "//third_party/angle:libGLESv2" ]
|
||||
}
|
||||
|
||||
group("electron_symbols") {
|
||||
deps = [
|
||||
":egl_symbols",
|
||||
":electron_app_symbols",
|
||||
":swiftshader_egl_symbols",
|
||||
":swiftshader_gles_symbols",
|
||||
":gles_symbols",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
24
DEPS
@@ -1,28 +1,12 @@
|
||||
gclient_gn_args_file = 'src/build/config/gclient_args.gni'
|
||||
gclient_gn_args = [
|
||||
'build_with_chromium',
|
||||
'checkout_android',
|
||||
'checkout_android_native_support',
|
||||
'checkout_libaom',
|
||||
'checkout_nacl',
|
||||
'checkout_pgo_profiles',
|
||||
'checkout_oculus_sdk',
|
||||
'checkout_openxr',
|
||||
'checkout_google_benchmark',
|
||||
'mac_xcode_version',
|
||||
'generate_location_tags',
|
||||
]
|
||||
gclient_gn_args_from = 'src'
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'100.0.4896.160',
|
||||
'105.0.5187.0',
|
||||
'node_version':
|
||||
'v16.13.2',
|
||||
'v16.16.0',
|
||||
'nan_version':
|
||||
# The following commit hash of NAN is v2.14.2 with *only* changes to the
|
||||
# test suite. This should be updated to a specific tag when one becomes
|
||||
# available.
|
||||
'65b32af46e9d7fab2e4ff657751205b3865f4920',
|
||||
'16fa32231e2ccd89d2804b3f765319128b20c4ac',
|
||||
'squirrel.mac_version':
|
||||
'0e5d146ba13101a1302d59ea6e6e0b3cace4ae38',
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
18.2.4
|
||||
21.0.0-nightly.20220729
|
||||
37
README.md
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://circleci.com/gh/electron/electron/tree/main)
|
||||
[](https://ci.appveyor.com/project/electron-bot/electron-ljo26/branch/main)
|
||||
[](https://discord.com/invite/APGC3k5yaH)
|
||||
[](https://discord.gg/electronjs)
|
||||
|
||||
:memo: Available Translations: 🇨🇳 🇧🇷 🇪🇸 🇯🇵 🇷🇺 🇫🇷 🇺🇸 🇩🇪.
|
||||
View these docs in other languages at [electron/i18n](https://github.com/electron/i18n/tree/master/content/).
|
||||
@@ -34,6 +34,17 @@ For more installation options and troubleshooting tips, see
|
||||
[installation](docs/tutorial/installation.md). For info on how to manage Electron versions in your apps, see
|
||||
[Electron versioning](docs/tutorial/electron-versioning.md).
|
||||
|
||||
## Platform support
|
||||
|
||||
Each Electron release provides binaries for macOS, Windows, and Linux.
|
||||
|
||||
* macOS (El Capitan and up): Electron provides 64-bit Intel and ARM binaries for macOS. Apple Silicon support was added in Electron 11.
|
||||
* Windows (Windows 7 and up): Electron provides `ia32` (`x86`), `x64` (`amd64`), and `arm64` binaries for Windows. Windows on ARM support was added in Electron 5.0.8.
|
||||
* Linux: The prebuilt binaries of Electron are built on Ubuntu 20.04. They have also been verified to work on:
|
||||
* Ubuntu 14.04 and newer
|
||||
* Fedora 24 and newer
|
||||
* Debian 8 and newer
|
||||
|
||||
## Quick start & Electron Fiddle
|
||||
|
||||
Use [`Electron Fiddle`](https://github.com/electron/fiddle)
|
||||
@@ -54,12 +65,10 @@ npm start
|
||||
|
||||
## Resources for learning Electron
|
||||
|
||||
- [electronjs.org/docs](https://electronjs.org/docs) - All of Electron's documentation
|
||||
- [electron/fiddle](https://github.com/electron/fiddle) - A tool to build, run, and package small Electron experiments
|
||||
- [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - A very basic starter Electron app
|
||||
- [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - Sample starter apps created by the community
|
||||
- [electron/simple-samples](https://github.com/electron/simple-samples) - Small applications with ideas for taking them further
|
||||
- [electron/electron-api-demos](https://github.com/electron/electron-api-demos) - An Electron app that teaches you how to use Electron
|
||||
* [electronjs.org/docs](https://electronjs.org/docs) - All of Electron's documentation
|
||||
* [electron/fiddle](https://github.com/electron/fiddle) - A tool to build, run, and package small Electron experiments
|
||||
* [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - A very basic starter Electron app
|
||||
* [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - Sample starter apps created by the community
|
||||
|
||||
## Programmatic usage
|
||||
|
||||
@@ -80,11 +89,15 @@ const child = proc.spawn(electron)
|
||||
|
||||
### Mirrors
|
||||
|
||||
- [China](https://npmmirror.com/mirrors/electron)
|
||||
* [China](https://npmmirror.com/mirrors/electron/)
|
||||
|
||||
## Documentation Translations
|
||||
See the [Advanced Installation Instructions](https://www.electronjs.org/docs/latest/tutorial/installation#mirror) to learn how to use a custom mirror.
|
||||
|
||||
Find documentation translations in [electron/i18n](https://github.com/electron/i18n).
|
||||
## Documentation translations
|
||||
|
||||
We crowdsource translations for our documentation via [Crowdin](https://crowdin.com/project/electron).
|
||||
We currently accept translations for Chinese (Simplified), French, German, Japanese, Portuguese,
|
||||
Russian, and Spanish.
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -93,10 +106,10 @@ If you are interested in reporting/fixing issues and contributing directly to th
|
||||
## Community
|
||||
|
||||
Info on reporting bugs, getting help, finding third-party tools and sample apps,
|
||||
and more can be found in the [support document](docs/tutorial/support.md#finding-support).
|
||||
and more can be found on the [Community page](https://www.electronjs.org/community).
|
||||
|
||||
## License
|
||||
|
||||
[MIT](https://github.com/electron/electron/blob/main/LICENSE)
|
||||
|
||||
When using the Electron or other GitHub logos, be sure to follow the [GitHub logo guidelines](https://github.com/logos).
|
||||
When using Electron logos, make sure to follow [OpenJS Foundation Trademark Policy](https://openjsf.org/wp-content/uploads/sites/84/2021/01/OpenJS-Foundation-Trademark-Policy-2021-01-12.docx.pdf).
|
||||
|
||||
67
appveyor.yml
@@ -3,7 +3,7 @@
|
||||
# - "GN_EXTRA_ARGS" Additional gn arguments for a build config,
|
||||
# e.g. 'target_cpu="x86"' to build for a 32bit platform.
|
||||
# https://gn.googlesource.com/gn/+/master/docs/reference.md#target_cpu
|
||||
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordningly
|
||||
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordingly
|
||||
# if you pass a custom value for 'target_cpu'.
|
||||
# - "ELECTRON_RELEASE" Set it to '1' upload binaries on success.
|
||||
# - "NPM_CONFIG_ARCH" E.g. 'x86'. Is used to build native Node.js modules.
|
||||
@@ -12,7 +12,7 @@
|
||||
# Is used in some publishing scripts, but does NOT affect the Electron binary.
|
||||
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "NPM_CONFIG_ARCH" value.
|
||||
# - "UPLOAD_TO_STORAGE" Set it to '1' upload a release to the Azure bucket.
|
||||
# Otherwise the release will be uploaded to the Github Releases.
|
||||
# Otherwise the release will be uploaded to the GitHub Releases.
|
||||
# (The value is only checked if "ELECTRON_RELEASE" is defined.)
|
||||
#
|
||||
# The publishing scripts expect access tokens to be defined as env vars,
|
||||
@@ -23,13 +23,9 @@
|
||||
# https://www.appveyor.com/docs/build-configuration/#secure-variables
|
||||
# https://www.appveyor.com/docs/build-configuration/#custom-environment-variables
|
||||
|
||||
# Uncomment these lines to enable RDP
|
||||
#on_finish:
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electron-16-core
|
||||
image: vs2019bt-16.6.2
|
||||
image: vs2019bt-16.16.11
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\electron\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
@@ -38,16 +34,6 @@ environment:
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
|
||||
GOMA_FALLBACK_ON_AUTH_FAILURE: true
|
||||
notifications:
|
||||
- provider: Webhook
|
||||
url: https://electron-mission-control.herokuapp.com/rest/appveyor-hook
|
||||
method: POST
|
||||
headers:
|
||||
x-mission-control-secret:
|
||||
secure: 90BLVPcqhJPG7d24v0q/RRray6W3wDQ8uVQlQjOHaBWkw1i8FoA1lsjr2C/v1dVok+tS2Pi6KxDctPUkwIb4T27u4RhvmcPzQhVpfwVJAG9oNtq+yKN7vzHfg7k/pojEzVdJpQLzeJGcSrZu7VY39Q==
|
||||
on_build_success: false
|
||||
on_build_failure: true
|
||||
on_build_status_changed: false
|
||||
build_script:
|
||||
- ps: >-
|
||||
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
|
||||
@@ -154,6 +140,12 @@ build_script:
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-warning "Failed to add third_party\angle\.git; continuing anyway"
|
||||
}
|
||||
# build time generation of file dawn/common/Version_autogen.h depends on third_party/dawn/.git/HEAD
|
||||
# https://dawn-review.googlesource.com/c/dawn/+/83901
|
||||
$(7z a $zipfile src\third_party\dawn\.git)
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-warning "Failed to add third_party\dawn\.git; continuing anyway"
|
||||
}
|
||||
}
|
||||
- cd src
|
||||
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
|
||||
@@ -176,17 +168,8 @@ build_script:
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default third_party/electron_node:headers
|
||||
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
|
||||
- python electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
- appveyor PushArtifact out/Default/windows_toolchain_profile.json
|
||||
- appveyor PushArtifact out/Default/dist.zip
|
||||
- appveyor PushArtifact out/Default/shell_browser_ui_unittests.exe
|
||||
- appveyor PushArtifact out/Default/chromedriver.zip
|
||||
- appveyor PushArtifact out/ffmpeg/ffmpeg.zip
|
||||
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
- appveyor PushArtifact node_headers.zip
|
||||
- appveyor PushArtifact out/Default/mksnapshot.zip
|
||||
- appveyor PushArtifact out/Default/hunspell_dictionaries.zip
|
||||
- appveyor PushArtifact out/Default/electron.lib
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
@@ -201,7 +184,6 @@ build_script:
|
||||
# It's useful to have pdb files when debugging testing builds that are
|
||||
# built on CI.
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
appveyor-retry appveyor PushArtifact pdb.zip
|
||||
}
|
||||
- python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
test_script:
|
||||
@@ -219,10 +201,9 @@ test_script:
|
||||
echo "Skipping tests for $env:GN_CONFIG build"
|
||||
}
|
||||
- cd electron
|
||||
# CalculateNativeWinOcclusion is disabled due to https://bugs.chromium.org/p/chromium/issues/detail?id=1139022
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running main test suite & node script/yarn test -- --trace-uncaught --runners=main --enable-logging=file --log-file=%cd%\electron.log --disable-features=CalculateNativeWinOcclusion )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running remote test suite & node script/yarn test -- --trace-uncaught --runners=remote --runTestFilesSeperately --enable-logging=file --log-file=%cd%\electron.log --disable-features=CalculateNativeWinOcclusion )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running native test suite & node script/yarn test -- --trace-uncaught --runners=native --enable-logging=file --log-file=%cd%\electron.log --disable-features=CalculateNativeWinOcclusion )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running main test suite & node script/yarn test -- --trace-uncaught --runners=main --enable-logging=file --log-file=%cd%\electron.log )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running remote test suite & node script/yarn test -- --trace-uncaught --runners=remote --runTestFilesSeparately --enable-logging=file --log-file=%cd%\electron.log )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running native test suite & node script/yarn test -- --trace-uncaught --runners=native --enable-logging=file --log-file=%cd%\electron.log )
|
||||
- cd ..
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- echo "About to verify mksnapshot"
|
||||
@@ -230,7 +211,6 @@ test_script:
|
||||
- echo "Done verifying mksnapshot"
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd% )
|
||||
- echo "Done verifying chromedriver"
|
||||
- if exist %cd%\electron.log ( appveyor-retry appveyor PushArtifact %cd%\electron.log )
|
||||
deploy_script:
|
||||
- cd electron
|
||||
- ps: >-
|
||||
@@ -243,7 +223,24 @@ deploy_script:
|
||||
& python script\release\uploaders\upload.py --verbose
|
||||
}
|
||||
} elseif (Test-Path Env:\TEST_WOA) {
|
||||
node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
|
||||
node script/release/ci-release-build.js --job=electron-woa-testing --ci=GHA --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
|
||||
}
|
||||
on_finish:
|
||||
- if exist src\electron\electron.log ( appveyor-retry appveyor PushArtifact src\electron\electron.log )
|
||||
# Uncomment this lines to enable RDP
|
||||
#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
- cd ..
|
||||
- if exist out\Default\windows_toolchain_profile.json ( appveyor-retry appveyor PushArtifact out\Default\windows_toolchain_profile.json )
|
||||
- if exist out\Default\dist.zip (appveyor-retry appveyor PushArtifact out\Default\dist.zip)
|
||||
- if exist out\Default\shell_browser_ui_unittests.exe (appveyor-retry appveyor PushArtifact out\Default\shell_browser_ui_unittests.exe)
|
||||
- if exist out\Default\chromedriver.zip (appveyor-retry appveyor PushArtifact out\Default\chromedriver.zip)
|
||||
- if exist out\ffmpeg\ffmpeg.zip (appveyor-retry appveyor PushArtifact out\ffmpeg\ffmpeg.zip)
|
||||
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
|
||||
- if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
|
||||
- if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
|
||||
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
|
||||
- ps: >-
|
||||
if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
|
||||
appveyor-retry appveyor PushArtifact pdb.zip
|
||||
}
|
||||
|
||||
- if exist electron\electron.log ( appveyor-retry appveyor PushArtifact electron\electron.log )
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
steps:
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy Files to: src/electron'
|
||||
inputs:
|
||||
TargetFolder: src/electron
|
||||
|
||||
- bash: |
|
||||
cd src/electron
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
displayName: 'Yarn install'
|
||||
|
||||
- bash: |
|
||||
export ZIP_DEST=$PWD/src/out/Default
|
||||
echo "##vso[task.setvariable variable=ZIP_DEST]$ZIP_DEST"
|
||||
mkdir -p $ZIP_DEST
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=dist.zip --dest=$ZIP_DEST
|
||||
cd $ZIP_DEST
|
||||
unzip -o dist.zip
|
||||
xattr -cr Electron.app
|
||||
displayName: 'Download and unzip dist files for test'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
export FFMPEG_ZIP_DEST=$PWD/src/out/ffmpeg
|
||||
mkdir -p $FFMPEG_ZIP_DEST
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=ffmpeg.zip --dest=$FFMPEG_ZIP_DEST
|
||||
cd $FFMPEG_ZIP_DEST
|
||||
unzip -o ffmpeg.zip
|
||||
displayName: 'Download and unzip ffmpeg for test'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
export NODE_HEADERS_DEST=$PWD/src/out/Default/gen
|
||||
mkdir -p $NODE_HEADERS_DEST
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=node_headers.tar.gz --dest=$NODE_HEADERS_DEST
|
||||
cd $NODE_HEADERS_DEST
|
||||
tar xzf node_headers.tar.gz
|
||||
displayName: 'Download and untar node header files for test'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
export CROSS_ARCH_SNAPSHOTS=$PWD/src/out/Default/cross-arch-snapshots
|
||||
mkdir -p $CROSS_ARCH_SNAPSHOTS
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/snapshot_blob.bin --dest=$CROSS_ARCH_SNAPSHOTS
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/v8_context_snapshot.arm64.bin --dest=$CROSS_ARCH_SNAPSHOTS
|
||||
displayName: 'Download cross arch snapshot files'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
export ELECTRON_OUT_DIR=Default
|
||||
export npm_config_arch=arm64
|
||||
(cd electron && node script/yarn test --enable-logging --runners main)
|
||||
displayName: 'Run Electron main tests'
|
||||
timeoutInMinutes: 20
|
||||
env:
|
||||
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
export ELECTRON_OUT_DIR=Default
|
||||
export npm_config_arch=arm64
|
||||
(cd electron && node script/yarn test --enable-logging --runners remote)
|
||||
displayName: 'Run Electron remote tests'
|
||||
timeoutInMinutes: 20
|
||||
condition: succeededOrFailed()
|
||||
env:
|
||||
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
python electron/script/verify-ffmpeg.py --source-root "$PWD" --build-dir out/Default --ffmpeg-path out/ffmpeg
|
||||
displayName: Verify non proprietary ffmpeg
|
||||
timeoutInMinutes: 5
|
||||
condition: succeededOrFailed()
|
||||
env:
|
||||
TARGET_ARCH: arm64
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
echo Verify cross arch snapshot
|
||||
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/out/Default/cross-arch-snapshots
|
||||
displayName: Verify cross arch snapshot
|
||||
timeoutInMinutes: 5
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results'
|
||||
inputs:
|
||||
testResultsFiles: '*.xml'
|
||||
|
||||
searchFolder: '$(System.DefaultWorkingDirectory)/src/junit/'
|
||||
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- bash: killall Electron || echo "No Electron processes left running"
|
||||
displayName: 'Kill processes left running from last test run'
|
||||
condition: always()
|
||||
|
||||
- bash: |
|
||||
rm -rf ~/Library/Application\ Support/Electron*
|
||||
rm -rf ~/Library/Application\ Support/electron*
|
||||
displayName: 'Delete user app data directories'
|
||||
condition: always()
|
||||
|
||||
- task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3
|
||||
displayName: 'Clean Agent Directories'
|
||||
|
||||
condition: always()
|
||||
@@ -1,130 +0,0 @@
|
||||
workspace:
|
||||
clean: all
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
path: src\electron
|
||||
|
||||
- script: |
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
displayName: 'Yarn install'
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$pwd\dist.zip"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/dist.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -o$(Pipeline.Workspace)\src\out\Default -y $localArtifactPath
|
||||
displayName: 'Download and extract dist.zip for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$(Pipeline.Workspace)\src\out\Default\shell_browser_ui_unittests.exe"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/shell_browser_ui_unittests.exe"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
displayName: 'Download and extract native test executables for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$pwd\ffmpeg.zip"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/ffmpeg.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -o$(Pipeline.Workspace)\src\out\ffmpeg $localArtifactPath
|
||||
displayName: 'Download and extract ffmpeg.zip for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$(Pipeline.Workspace)\src\node_headers.zip"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/node_headers.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
cd $(Pipeline.Workspace)\src
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y node_headers.zip
|
||||
displayName: 'Download node headers for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$(Pipeline.Workspace)\src\out\Default\electron.lib"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/electron.lib"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
displayName: 'Download electron.lib for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
# Uncomment the following block if pdb files are needed to debug issues
|
||||
# - powershell: |
|
||||
# try {
|
||||
# $localArtifactPath = "$(Pipeline.Workspace)\src\pdb.zip"
|
||||
# $serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/pdb.zip"
|
||||
# Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
# cd $(Pipeline.Workspace)\src
|
||||
# & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y pdb.zip
|
||||
# } catch {
|
||||
# Write-Host "There was an exception encountered while downloading pdb files:" $_.Exception.Message
|
||||
# } finally {
|
||||
# $global:LASTEXITCODE = 0
|
||||
# }
|
||||
# displayName: 'Download pdb files for detailed stacktraces'
|
||||
# env:
|
||||
# APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
New-Item $(Pipeline.Workspace)\src\out\Default\gen\node_headers\Release -Type directory
|
||||
Copy-Item -path $(Pipeline.Workspace)\src\out\Default\electron.lib -destination $(Pipeline.Workspace)\src\out\Default\gen\node_headers\Release\node.lib
|
||||
displayName: 'Setup node headers'
|
||||
|
||||
- script: |
|
||||
cd $(Pipeline.Workspace)\src
|
||||
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
set npm_config_arch=arm64
|
||||
cd electron
|
||||
node script/yarn test --runners=main --enable-logging --disable-features=CalculateNativeWinOcclusion
|
||||
displayName: 'Run Electron Main process tests'
|
||||
env:
|
||||
ELECTRON_ENABLE_STACK_DUMPING: true
|
||||
ELECTRON_OUT_DIR: Default
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
|
||||
- script: |
|
||||
cd $(Pipeline.Workspace)\src
|
||||
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
set npm_config_arch=arm64
|
||||
cd electron
|
||||
node script/yarn test --runners=remote --enable-logging --disable-features=CalculateNativeWinOcclusion
|
||||
displayName: 'Run Electron Remote based tests'
|
||||
env:
|
||||
ELECTRON_OUT_DIR: Default
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results'
|
||||
inputs:
|
||||
testResultsFiles: '*.xml'
|
||||
searchFolder: '$(Pipeline.Workspace)/src/junit/'
|
||||
condition: always()
|
||||
|
||||
- script: |
|
||||
cd $(Pipeline.Workspace)\src
|
||||
echo "Verifying non proprietary ffmpeg"
|
||||
python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
|
||||
displayName: 'Verify ffmpeg'
|
||||
|
||||
- powershell: |
|
||||
Get-Process | Where Name –Like "electron*" | Stop-Process
|
||||
Get-Process | Where Name –Like "msedge*" | Stop-Process
|
||||
displayName: 'Kill processes left running from last test run'
|
||||
condition: always()
|
||||
|
||||
- powershell: |
|
||||
Remove-Item -path $env:APPDATA/Electron* -Recurse -Force -ErrorAction Ignore
|
||||
displayName: 'Delete user app data directories'
|
||||
condition: always()
|
||||
@@ -2,7 +2,7 @@ is_electron_build = true
|
||||
root_extra_deps = [ "//electron" ]
|
||||
|
||||
# Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json
|
||||
node_module_version = 103
|
||||
node_module_version = 107
|
||||
|
||||
v8_promise_internal_field_count = 1
|
||||
v8_embedder_string = "-electron.0"
|
||||
@@ -27,17 +27,21 @@ enable_basic_printing = true
|
||||
angle_enable_vulkan_validation_layers = false
|
||||
dawn_enable_vulkan_validation_layers = false
|
||||
|
||||
# This breaks native node modules
|
||||
libcxx_abi_unstable = false
|
||||
|
||||
# These are disabled because they cause the zip manifest to differ between
|
||||
# testing and release builds.
|
||||
# See https://chromium-review.googlesource.com/c/chromium/src/+/2774898.
|
||||
enable_pseudolocales = false
|
||||
|
||||
is_cfi = false
|
||||
|
||||
# Make application name configurable at runtime for cookie crypto
|
||||
allow_runtime_configurable_key_storage = true
|
||||
|
||||
# CET shadow stack is incompatible with v8, until v8 is CET compliant
|
||||
# enabling this flag causes main process crashes where CET is enabled
|
||||
# Ref: https://source.chromium.org/chromium/chromium/src/+/45fba672185aae233e75d6ddc81ea1e0b30db050:v8/BUILD.gn;l=357
|
||||
enable_cet_shadow_stack = false
|
||||
|
||||
# For similar reasons, disable CFI, which is not well supported in V8.
|
||||
# Chromium doesn't have any problems with this because they do not run
|
||||
# V8 in the browser process.
|
||||
# Ref: https://source.chromium.org/chromium/chromium/src/+/45fba672185aae233e75d6ddc81ea1e0b30db050:v8/BUILD.gn;l=281
|
||||
is_cfi = false
|
||||
|
||||
@@ -1,33 +1,22 @@
|
||||
import("node.gni")
|
||||
template("node_action") {
|
||||
assert(defined(invoker.script), "Need script path to run")
|
||||
assert(defined(invoker.args), "Need script arguments")
|
||||
|
||||
# TODO(MarshallOfSound): Move to electron/node, this is the only place it is used now
|
||||
# Run an action with a given working directory. Behaves identically to the
|
||||
# action() target type, with the exception that it changes directory before
|
||||
# running the script.
|
||||
#
|
||||
# Parameters:
|
||||
# cwd [required]: Directory to change to before running the script.
|
||||
template("chdir_action") {
|
||||
action(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
"*",
|
||||
[
|
||||
"script",
|
||||
"args",
|
||||
"deps",
|
||||
"public_deps",
|
||||
"sources",
|
||||
"inputs",
|
||||
"outputs",
|
||||
])
|
||||
assert(defined(cwd), "Need cwd in $target_name")
|
||||
script = "//electron/build/run-in-dir.py"
|
||||
if (defined(sources)) {
|
||||
sources += [ invoker.script ]
|
||||
} else {
|
||||
assert(defined(inputs))
|
||||
inputs += [ invoker.script ]
|
||||
if (!defined(inputs)) {
|
||||
inputs = []
|
||||
}
|
||||
args = [
|
||||
rebase_path(cwd),
|
||||
rebase_path(invoker.script),
|
||||
]
|
||||
args += invoker.args
|
||||
inputs += [ invoker.script ]
|
||||
script = "//electron/build/run-node.py"
|
||||
args = [ rebase_path(invoker.script) ] + invoker.args
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,11 @@ template("extract_symbols") {
|
||||
assert(defined(invoker.binary), "Need binary to dump")
|
||||
assert(defined(invoker.symbol_dir), "Need directory for symbol output")
|
||||
|
||||
dump_syms_label = "//third_party/breakpad:dump_syms($host_toolchain)"
|
||||
if (host_os == "win" && target_cpu == "x86") {
|
||||
dump_syms_label = "//third_party/breakpad:dump_syms(//build/toolchain/win:win_clang_x64)"
|
||||
} else {
|
||||
dump_syms_label = "//third_party/breakpad:dump_syms($host_toolchain)"
|
||||
}
|
||||
dump_syms_binary = get_label_info(dump_syms_label, "root_out_dir") +
|
||||
"/dump_syms$_host_executable_suffix"
|
||||
|
||||
|
||||
@@ -19,17 +19,13 @@ TEMPLATE_H = """
|
||||
#define FUSE_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace fuses {
|
||||
namespace electron::fuses {
|
||||
|
||||
extern const volatile char kFuseWire[];
|
||||
|
||||
{getters}
|
||||
|
||||
} // namespace fuses
|
||||
|
||||
} // namespace electron
|
||||
} // namespace electron::fuses
|
||||
|
||||
#endif // ELECTRON_FUSES_H_
|
||||
"""
|
||||
@@ -37,17 +33,13 @@ extern const volatile char kFuseWire[];
|
||||
TEMPLATE_CC = """
|
||||
#include "electron/fuses.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace fuses {
|
||||
namespace electron::fuses {
|
||||
|
||||
const volatile char kFuseWire[] = { /* sentinel */ {sentinel}, /* fuse_version */ {fuse_version}, /* fuse_wire_length */ {fuse_wire_length}, /* fuse_wire */ {initial_config}};
|
||||
|
||||
{getters}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace electron:fuses
|
||||
"""
|
||||
|
||||
with open(os.path.join(dir_path, "fuses.json5"), 'r') as f:
|
||||
|
||||
@@ -8,9 +8,7 @@ TEMPLATE = """
|
||||
#include "node_native_module.h"
|
||||
#include "node_internals.h"
|
||||
|
||||
namespace node {{
|
||||
|
||||
namespace native_module {{
|
||||
namespace node::native_module {{
|
||||
|
||||
{definitions}
|
||||
|
||||
@@ -18,9 +16,7 @@ void NativeModuleLoader::LoadEmbedderJavaScriptSource() {{
|
||||
{initializers}
|
||||
}}
|
||||
|
||||
}} // namespace native_module
|
||||
|
||||
}} // namespace node
|
||||
}} // namespace node::native_module
|
||||
"""
|
||||
|
||||
def main():
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Cocoa .app bundle. The presence of these empty directories is sufficient to
|
||||
# convince Cocoa that the application supports the named localization, even if
|
||||
# an InfoPlist.strings file is not provided. Chrome uses these empty locale
|
||||
# directoires for its helper executable bundles, which do not otherwise
|
||||
# directories for its helper executable bundles, which do not otherwise
|
||||
# require any direct Cocoa locale support.
|
||||
|
||||
import os
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
template("node_action") {
|
||||
assert(defined(invoker.script), "Need script path to run")
|
||||
assert(defined(invoker.args), "Need script argumets")
|
||||
|
||||
action(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"deps",
|
||||
"public_deps",
|
||||
"sources",
|
||||
"inputs",
|
||||
"outputs",
|
||||
])
|
||||
if (!defined(inputs)) {
|
||||
inputs = []
|
||||
}
|
||||
inputs += [ invoker.script ]
|
||||
script = "//electron/build/run-node.py"
|
||||
args = [ rebase_path(invoker.script) ] + invoker.args
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
template("npm_action") {
|
||||
assert(defined(invoker.script),
|
||||
"Need script name to run (must be defined in package.json)")
|
||||
assert(defined(invoker.args), "Need script argumets")
|
||||
assert(defined(invoker.args), "Need script arguments")
|
||||
|
||||
action("npm_pre_flight_" + target_name) {
|
||||
inputs = [
|
||||
|
||||
@@ -51,7 +51,7 @@ template("compile_ib_files") {
|
||||
# Template to compile and package Mac XIB files as bundle data.
|
||||
# Arguments
|
||||
# sources:
|
||||
# list of string, sources to comiple
|
||||
# list of string, sources to compile
|
||||
# output_path:
|
||||
# (optional) string, the path to use for the outputs list in the
|
||||
# bundle_data step. If unspecified, defaults to bundle_resources_dir.
|
||||
|
||||
@@ -19,7 +19,6 @@ buildflag_header("buildflags") {
|
||||
"ENABLE_ELECTRON_EXTENSIONS=$enable_electron_extensions",
|
||||
"ENABLE_BUILTIN_SPELLCHECKER=$enable_builtin_spellchecker",
|
||||
"ENABLE_PICTURE_IN_PICTURE=$enable_picture_in_picture",
|
||||
"ENABLE_WIN_DARK_MODE_WINDOW_UI=$enable_win_dark_mode_window_ui",
|
||||
"OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -31,7 +31,4 @@ declare_args() {
|
||||
|
||||
# Enable Spellchecker support
|
||||
enable_builtin_spellchecker = true
|
||||
|
||||
# Undocumented Windows dark mode API
|
||||
enable_win_dark_mode_window_ui = false
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ static_library("chrome") {
|
||||
"//chrome/browser/ui/exclusive_access/keyboard_lock_controller.h",
|
||||
"//chrome/browser/ui/exclusive_access/mouse_lock_controller.cc",
|
||||
"//chrome/browser/ui/exclusive_access/mouse_lock_controller.h",
|
||||
"//chrome/browser/ui/native_window_tracker.h",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper.cc",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper.h",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc",
|
||||
@@ -88,7 +89,10 @@ static_library("chrome") {
|
||||
"//chrome/browser/icon_loader_mac.mm",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_mac.h",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.h",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.mm",
|
||||
"//chrome/browser/media/webrtc/window_icon_util_mac.mm",
|
||||
"//chrome/browser/platform_util_mac.mm",
|
||||
"//chrome/browser/process_singleton_mac.mm",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.h",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm",
|
||||
@@ -119,6 +123,8 @@ static_library("chrome") {
|
||||
if (use_aura) {
|
||||
sources += [
|
||||
"//chrome/browser/platform_util_aura.cc",
|
||||
"//chrome/browser/ui/aura/native_window_tracker_aura.cc",
|
||||
"//chrome/browser/ui/aura/native_window_tracker_aura.h",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view_aura.cc",
|
||||
]
|
||||
}
|
||||
@@ -211,6 +217,8 @@ static_library("chrome") {
|
||||
"//chrome/browser/printing/printer_query.h",
|
||||
"//chrome/browser/printing/printing_service.cc",
|
||||
"//chrome/browser/printing/printing_service.h",
|
||||
"//components/printing/browser/print_to_pdf/pdf_print_utils.cc",
|
||||
"//components/printing/browser/print_to_pdf/pdf_print_utils.h",
|
||||
]
|
||||
|
||||
if (enable_oop_printing) {
|
||||
@@ -306,8 +314,6 @@ static_library("chrome") {
|
||||
"//chrome/browser/pdf/pdf_frame_util.h",
|
||||
"//chrome/browser/plugins/pdf_iframe_navigation_throttle.cc",
|
||||
"//chrome/browser/plugins/pdf_iframe_navigation_throttle.h",
|
||||
"//chrome/renderer/pepper/chrome_pdf_print_client.cc",
|
||||
"//chrome/renderer/pepper/chrome_pdf_print_client.h",
|
||||
]
|
||||
deps += [
|
||||
"//components/pdf/browser",
|
||||
@@ -345,8 +351,6 @@ source_set("plugins") {
|
||||
sources += [
|
||||
"//chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc",
|
||||
"//chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h",
|
||||
"//chrome/renderer/pepper/pepper_flash_font_file_host.cc",
|
||||
"//chrome/renderer/pepper/pepper_flash_font_file_host.h",
|
||||
"//chrome/renderer/pepper/pepper_shared_memory_message_filter.cc",
|
||||
"//chrome/renderer/pepper/pepper_shared_memory_message_filter.h",
|
||||
]
|
||||
@@ -384,14 +388,19 @@ source_set("chrome_spellchecker") {
|
||||
"//chrome/browser/spellchecker/spellcheck_factory.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_blocklist_policy_handler.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_blocklist_policy_handler.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_service.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_service.h",
|
||||
]
|
||||
|
||||
if (!is_mac) {
|
||||
sources += [
|
||||
"//chrome/browser/spellchecker/spellcheck_language_blocklist_policy_handler.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_blocklist_policy_handler.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (has_spellcheck_panel) {
|
||||
sources += [
|
||||
"//chrome/browser/spellchecker/spell_check_panel_host_impl.cc",
|
||||
|
||||
@@ -66,9 +66,9 @@ async function createWindow (backgroundColor?: string) {
|
||||
mainWindow = new BrowserWindow(options);
|
||||
mainWindow.on('ready-to-show', () => mainWindow!.show());
|
||||
|
||||
mainWindow.webContents.on('new-window', (event, url) => {
|
||||
event.preventDefault();
|
||||
shell.openExternal(decorateURL(url));
|
||||
mainWindow.webContents.setWindowOpenHandler(details => {
|
||||
shell.openExternal(decorateURL(details.url));
|
||||
return { action: 'deny' };
|
||||
});
|
||||
|
||||
mainWindow.webContents.session.setPermissionRequestHandler((webContents, permission, done) => {
|
||||
|
||||
@@ -64,15 +64,11 @@ an issue:
|
||||
* [Automated Testing](tutorial/automated-testing.md)
|
||||
* [REPL](tutorial/repl.md)
|
||||
* [Distribution](tutorial/application-distribution.md)
|
||||
* [Supported Platforms](tutorial/support.md#supported-platforms)
|
||||
* [Code Signing](tutorial/code-signing.md)
|
||||
* [Mac App Store](tutorial/mac-app-store-submission-guide.md)
|
||||
* [Windows Store](tutorial/windows-store-guide.md)
|
||||
* [Snapcraft](tutorial/snapcraft.md)
|
||||
* [Updates](tutorial/updates.md)
|
||||
* [Deploying an Update Server](tutorial/updates.md#deploying-an-update-server)
|
||||
* [Implementing Updates in Your App](tutorial/updates.md#implementing-updates-in-your-app)
|
||||
* [Applying Updates](tutorial/updates.md#applying-updates)
|
||||
* [Getting Support](tutorial/support.md)
|
||||
|
||||
## Detailed Tutorials
|
||||
|
||||
@@ -130,6 +130,11 @@ set `NSPrincipalClass` to `AtomApplication`.
|
||||
|
||||
You should call `event.preventDefault()` if you want to handle this event.
|
||||
|
||||
As with the `open-file` event, be sure to register a listener for the `open-url`
|
||||
event early in your application startup to detect if the the application being
|
||||
is being opened to handle a URL. If you register the listener in response to a
|
||||
`ready` event, you'll miss URLs that trigger the launch of your application.
|
||||
|
||||
### Event: 'activate' _macOS_
|
||||
|
||||
Returns:
|
||||
@@ -484,7 +489,6 @@ Returns:
|
||||
* `argv` string[] - An array of the second instance's command line arguments
|
||||
* `workingDirectory` string - The second instance's working directory
|
||||
* `additionalData` unknown - A JSON object of additional data passed from the second instance
|
||||
* `ackCallback` unknown - A function that can be used to send data back to the second instance
|
||||
|
||||
This event will be emitted inside the primary instance of your application
|
||||
when a second instance has been executed and calls `app.requestSingleInstanceLock()`.
|
||||
@@ -496,35 +500,12 @@ non-minimized.
|
||||
|
||||
**Note:** If the second instance is started by a different user than the first, the `argv` array will not include the arguments.
|
||||
|
||||
**Note:** `ackCallback` allows the user to send data back to the
|
||||
second instance during the `app.requestSingleInstanceLock()` flow.
|
||||
This callback can be used for cases where the second instance
|
||||
needs to obtain additional information from the first instance
|
||||
before quitting.
|
||||
|
||||
Currently, the limit on the message size is kMaxMessageLength,
|
||||
or around 32kB. To be safe, keep the amount of data passed to 31kB at most.
|
||||
|
||||
In order to call the callback, `event.preventDefault()` must be called, first.
|
||||
If the callback is not called in either case, `null` will be sent back.
|
||||
If `event.preventDefault()` is not called, but `ackCallback` is called
|
||||
by the user in the event, then the behaviour is undefined.
|
||||
|
||||
This event is guaranteed to be emitted after the `ready` event of `app`
|
||||
gets emitted.
|
||||
|
||||
**Note:** Extra command line arguments might be added by Chromium,
|
||||
such as `--original-process-start-time`.
|
||||
|
||||
### Event: 'first-instance-ack'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `additionalData` unknown - A JSON object of additional data passed from the first instance, in response to the first instance's `second-instance` event.
|
||||
|
||||
This event will be emitted within the second instance during the call to `app.requestSingleInstanceLock()`, when the first instance calls the `ackCallback` provided by the `second-instance` event handler.
|
||||
|
||||
## Methods
|
||||
|
||||
The `app` object has the following methods:
|
||||
@@ -606,6 +587,10 @@ You should seek to use the `steal` option as sparingly as possible.
|
||||
|
||||
Hides all application windows without minimizing them.
|
||||
|
||||
### `app.isHidden()` _macOS_
|
||||
|
||||
Returns `boolean` - `true` if the application—including all of its windows—is hidden (e.g. with `Command-H`), `false` otherwise.
|
||||
|
||||
### `app.show()` _macOS_
|
||||
|
||||
Shows application windows after they were hidden. Does not automatically focus
|
||||
@@ -631,9 +616,18 @@ Returns `string` - The current application directory.
|
||||
* `%APPDATA%` on Windows
|
||||
* `$XDG_CONFIG_HOME` or `~/.config` on Linux
|
||||
* `~/Library/Application Support` on macOS
|
||||
* `userData` The directory for storing your app's configuration files, which by
|
||||
default it is the `appData` directory appended with your app's name.
|
||||
* `cache`
|
||||
* `userData` The directory for storing your app's configuration files, which
|
||||
by default is the `appData` directory appended with your app's name. By
|
||||
convention files storing user data should be written to this directory, and
|
||||
it is not recommended to write large files here because some environments
|
||||
may backup this directory to cloud storage.
|
||||
* `sessionData` The directory for storing data generated by `Session`, such
|
||||
as localStorage, cookies, disk cache, downloaded dictionaries, network
|
||||
state, devtools files. By default this points to `userData`. Chromium may
|
||||
write very large disk cache here, so if your app does not rely on browser
|
||||
storage like localStorage or cookies to save user data, it is recommended
|
||||
to set this directory to other locations to avoid polluting the `userData`
|
||||
directory.
|
||||
* `temp` Temporary directory.
|
||||
* `exe` The current executable file.
|
||||
* `module` The `libchromiumcontent` library.
|
||||
@@ -683,9 +677,9 @@ In that case, the directory should be created with `fs.mkdirSync` or similar.
|
||||
|
||||
You can only override paths of a `name` defined in `app.getPath`.
|
||||
|
||||
By default, web pages' cookies and caches will be stored under the `userData`
|
||||
By default, web pages' cookies and caches will be stored under the `sessionData`
|
||||
directory. If you want to change this location, you have to override the
|
||||
`userData` path before the `ready` event of the `app` module is emitted.
|
||||
`sessionData` path before the `ready` event of the `app` module is emitted.
|
||||
|
||||
### `app.getVersion()`
|
||||
|
||||
@@ -714,7 +708,7 @@ Overrides the current application's name.
|
||||
### `app.getLocale()`
|
||||
|
||||
Returns `string` - The current application locale, fetched using Chromium's `l10n_util` library.
|
||||
Possible return values are documented [here](https://source.chromium.org/chromium/chromium/src/+/master:ui/base/l10n/l10n_util.cc).
|
||||
Possible return values are documented [here](https://source.chromium.org/chromium/chromium/src/+/main:ui/base/l10n/l10n_util.cc).
|
||||
|
||||
To set the locale, you'll want to use a command line switch at app startup, which may be found [here](command-line-switches.md).
|
||||
|
||||
@@ -985,33 +979,21 @@ starts:
|
||||
const { app } = require('electron')
|
||||
let myWindow = null
|
||||
|
||||
app.on('first-instance-ack', (event, additionalData) => {
|
||||
// Print out the ack received from the first instance.
|
||||
// Note this event handler must come before the requestSingleInstanceLock call.
|
||||
// Expected output: '{"myAckKey":"myAckValue"}'
|
||||
console.log(JSON.stringify(additionalData))
|
||||
})
|
||||
|
||||
const additionalData = { myKey: 'myValue' }
|
||||
const gotTheLock = app.requestSingleInstanceLock(additionalData)
|
||||
|
||||
if (!gotTheLock) {
|
||||
app.quit()
|
||||
} else {
|
||||
app.on('second-instance', (event, commandLine, workingDirectory, additionalData, ackCallback) => {
|
||||
// We must call preventDefault if we're sending back data.
|
||||
event.preventDefault()
|
||||
app.on('second-instance', (event, commandLine, workingDirectory, additionalData) => {
|
||||
// Print out data received from the second instance.
|
||||
// Expected output: '{"myKey":"myValue"}'
|
||||
console.log(JSON.stringify(additionalData))
|
||||
console.log(additionalData)
|
||||
|
||||
// Someone tried to run a second instance, we should focus our window.
|
||||
if (myWindow) {
|
||||
if (myWindow.isMinimized()) myWindow.restore()
|
||||
myWindow.focus()
|
||||
}
|
||||
const ackData = { myAckKey: 'myAckValue' }
|
||||
ackCallback(ackData)
|
||||
})
|
||||
|
||||
// Create myWindow, load the rest of the app, etc...
|
||||
@@ -1095,7 +1077,7 @@ Activation policy types:
|
||||
|
||||
Imports the certificate in pkcs12 format into the platform certificate store.
|
||||
`callback` is called with the `result` of import operation, a value of `0`
|
||||
indicates success while any other value indicates failure according to Chromium [net_error_list](https://source.chromium.org/chromium/chromium/src/+/master:net/base/net_error_list.h).
|
||||
indicates success while any other value indicates failure according to Chromium [net_error_list](https://source.chromium.org/chromium/chromium/src/+/main:net/base/net_error_list.h).
|
||||
|
||||
### `app.configureHostResolver(options)`
|
||||
|
||||
@@ -1404,7 +1386,7 @@ method returns false. If we fail to perform the copy, then this method will
|
||||
throw an error. The message in the error should be informative and tell
|
||||
you exactly what went wrong.
|
||||
|
||||
By default, if an app of the same name as the one being moved exists in the Applications directory and is _not_ running, the existing app will be trashed and the active app moved into its place. If it _is_ running, the pre-existing running app will assume focus and the previously active app will quit itself. This behavior can be changed by providing the optional conflict handler, where the boolean returned by the handler determines whether or not the move conflict is resolved with default behavior. i.e. returning `false` will ensure no further action is taken, returning `true` will result in the default behavior and the method continuing.
|
||||
By default, if an app of the same name as the one being moved exists in the Applications directory and is _not_ running, the existing app will be trashed and the active app moved into its place. If it _is_ running, the preexisting running app will assume focus and the previously active app will quit itself. This behavior can be changed by providing the optional conflict handler, where the boolean returned by the handler determines whether or not the move conflict is resolved with default behavior. i.e. returning `false` will ensure no further action is taken, returning `true` will result in the default behavior and the method continuing.
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@ relative to its owning window. It is meant to be an alternative to the
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
|
||||
This module cannot be used until the `ready` event of the `app`
|
||||
module is emitted.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
|
||||
This module cannot be used until the `ready` event of the `app`
|
||||
module is emitted.
|
||||
|
||||
```javascript
|
||||
// In the main process.
|
||||
const { BrowserWindow } = require('electron')
|
||||
@@ -64,7 +67,7 @@ win.loadURL('https://github.com')
|
||||
```
|
||||
|
||||
Note that even for apps that use `ready-to-show` event, it is still recommended
|
||||
to set `backgroundColor` to make app feel more native.
|
||||
to set `backgroundColor` to make the app feel more native.
|
||||
|
||||
Some examples of valid `backgroundColor` values include:
|
||||
|
||||
@@ -158,20 +161,20 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
* `useContentSize` boolean (optional) - The `width` and `height` would be used as web
|
||||
page's size, which means the actual window's size will include window
|
||||
frame's size and be slightly larger. Default is `false`.
|
||||
* `center` boolean (optional) - Show window in the center of the screen.
|
||||
* `center` boolean (optional) - Show window in the center of the screen. Default is `false`.
|
||||
* `minWidth` Integer (optional) - Window's minimum width. Default is `0`.
|
||||
* `minHeight` Integer (optional) - Window's minimum height. Default is `0`.
|
||||
* `maxWidth` Integer (optional) - Window's maximum width. Default is no limit.
|
||||
* `maxHeight` Integer (optional) - Window's maximum height. Default is no limit.
|
||||
* `resizable` boolean (optional) - Whether window is resizable. Default is `true`.
|
||||
* `movable` boolean (optional) - Whether window is movable. This is not implemented
|
||||
on Linux. Default is `true`.
|
||||
* `minimizable` boolean (optional) - Whether window is minimizable. This is not
|
||||
implemented on Linux. Default is `true`.
|
||||
* `maximizable` boolean (optional) - Whether window is maximizable. This is not
|
||||
implemented on Linux. Default is `true`.
|
||||
* `closable` boolean (optional) - Whether window is closable. This is not implemented
|
||||
on Linux. Default is `true`.
|
||||
* `movable` boolean (optional) _macOS_ _Windows_ - Whether window is
|
||||
movable. This is not implemented on Linux. Default is `true`.
|
||||
* `minimizable` boolean (optional) _macOS_ _Windows_ - Whether window is
|
||||
minimizable. This is not implemented on Linux. Default is `true`.
|
||||
* `maximizable` boolean (optional) _macOS_ _Windows_ - Whether window is
|
||||
maximizable. This is not implemented on Linux. Default is `true`.
|
||||
* `closable` boolean (optional) _macOS_ _Windows_ - Whether window is
|
||||
closable. This is not implemented on Linux. Default is `true`.
|
||||
* `focusable` boolean (optional) - Whether the window can be focused. Default is
|
||||
`true`. On Windows setting `focusable: false` also implies setting
|
||||
`skipTaskbar: true`. On Linux setting `focusable: false` makes the window
|
||||
@@ -185,9 +188,10 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
* `fullscreenable` boolean (optional) - Whether the window can be put into fullscreen
|
||||
mode. On macOS, also whether the maximize/zoom button should toggle full
|
||||
screen mode or maximize window. Default is `true`.
|
||||
* `simpleFullscreen` boolean (optional) - Use pre-Lion fullscreen on macOS. Default is `false`.
|
||||
* `skipTaskbar` boolean (optional) - Whether to show the window in taskbar. Default is
|
||||
`false`.
|
||||
* `simpleFullscreen` boolean (optional) _macOS_ - Use pre-Lion fullscreen on
|
||||
macOS. Default is `false`.
|
||||
* `skipTaskbar` boolean (optional) _macOS_ _Windows_ - Whether to show the window in taskbar.
|
||||
Default is `false`.
|
||||
* `kiosk` boolean (optional) - Whether the window is in kiosk mode. Default is `false`.
|
||||
* `title` string (optional) - Default window title. Default is `"Electron"`. If the HTML tag `<title>` is defined in the HTML file loaded by `loadURL()`, this property will be ignored.
|
||||
* `icon` ([NativeImage](native-image.md) | string) (optional) - The window icon. On Windows it is
|
||||
@@ -201,27 +205,30 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
* `parent` BrowserWindow (optional) - Specify parent window. Default is `null`.
|
||||
* `modal` boolean (optional) - Whether this is a modal window. This only works when the
|
||||
window is a child window. Default is `false`.
|
||||
* `acceptFirstMouse` boolean (optional) - Whether clicking an inactive window will also
|
||||
click through to the web contents. Default is `false` on macOS. This option is not
|
||||
configurable on other platforms.
|
||||
* `acceptFirstMouse` boolean (optional) _macOS_ - Whether clicking an
|
||||
inactive window will also click through to the web contents. Default is
|
||||
`false` on macOS. This option is not configurable on other platforms.
|
||||
* `disableAutoHideCursor` boolean (optional) - Whether to hide cursor when typing.
|
||||
Default is `false`.
|
||||
* `autoHideMenuBar` boolean (optional) - Auto hide the menu bar unless the `Alt`
|
||||
key is pressed. Default is `false`.
|
||||
* `enableLargerThanScreen` boolean (optional) - Enable the window to be resized larger
|
||||
than screen. Only relevant for macOS, as other OSes allow
|
||||
larger-than-screen windows by default. Default is `false`.
|
||||
* `enableLargerThanScreen` boolean (optional) _macOS_ - Enable the window to
|
||||
be resized larger than screen. Only relevant for macOS, as other OSes
|
||||
allow larger-than-screen windows by default. Default is `false`.
|
||||
* `backgroundColor` string (optional) - The window's background color in Hex, RGB, RGBA, HSL, HSLA or named CSS color format. Alpha in #AARRGGBB format is supported if `transparent` is set to `true`. Default is `#FFF` (white). See [win.setBackgroundColor](browser-window.md#winsetbackgroundcolorbackgroundcolor) for more information.
|
||||
* `hasShadow` boolean (optional) - Whether window should have a shadow. Default is `true`.
|
||||
* `opacity` number (optional) - Set the initial opacity of the window, between 0.0 (fully
|
||||
transparent) and 1.0 (fully opaque). This is only implemented on Windows and macOS.
|
||||
* `opacity` number (optional) _macOS_ _Windows_ - Set the initial opacity of
|
||||
the window, between 0.0 (fully transparent) and 1.0 (fully opaque). This
|
||||
is only implemented on Windows and macOS.
|
||||
* `darkTheme` boolean (optional) - Forces using dark theme for the window, only works on
|
||||
some GTK+3 desktop environments. Default is `false`.
|
||||
* `transparent` boolean (optional) - Makes the window [transparent](../tutorial/window-customization.md#create-transparent-windows).
|
||||
Default is `false`. On Windows, does not work unless the window is frameless.
|
||||
* `type` string (optional) - The type of window, default is normal window. See more about
|
||||
this below.
|
||||
* `visualEffectState` string (optional) - Specify how the material appearance should reflect window activity state on macOS. Must be used with the `vibrancy` property. Possible values are:
|
||||
* `visualEffectState` string (optional) _macOS_ - Specify how the material
|
||||
appearance should reflect window activity state on macOS. Must be used
|
||||
with the `vibrancy` property. Possible values are:
|
||||
* `followWindow` - The backdrop should automatically appear active when the window is active, and inactive when it is not. This is the default.
|
||||
* `active` - The backdrop should always appear active.
|
||||
* `inactive` - The backdrop should always appear inactive.
|
||||
@@ -229,36 +236,41 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
Default is `default`. Possible values are:
|
||||
* `default` - Results in the standard title bar for macOS or Windows respectively.
|
||||
* `hidden` - Results in a hidden title bar and a full size content window. On macOS, the window still has the standard window controls (“traffic lights”) in the top left. On Windows, when combined with `titleBarOverlay: true` it will activate the Window Controls Overlay (see `titleBarOverlay` for more information), otherwise no window controls will be shown.
|
||||
* `hiddenInset` - Only on macOS, results in a hidden title bar with an alternative look
|
||||
where the traffic light buttons are slightly more inset from the window edge.
|
||||
* `customButtonsOnHover` - Only on macOS, results in a hidden title bar and a full size
|
||||
content window, the traffic light buttons will display when being hovered
|
||||
over in the top left of the window. **Note:** This option is currently
|
||||
experimental.
|
||||
* `trafficLightPosition` [Point](structures/point.md) (optional) - Set a
|
||||
custom position for the traffic light buttons in frameless windows.
|
||||
* `roundedCorners` boolean (optional) - Whether frameless window should have
|
||||
rounded corners on macOS. Default is `true`.
|
||||
* `fullscreenWindowTitle` boolean (optional) _Deprecated_ - Shows the title in
|
||||
the title bar in full screen mode on macOS for `hiddenInset` titleBarStyle.
|
||||
Default is `false`.
|
||||
* `hiddenInset` _macOS_ - Only on macOS, results in a hidden title bar
|
||||
with an alternative look where the traffic light buttons are slightly
|
||||
more inset from the window edge.
|
||||
* `customButtonsOnHover` _macOS_ - Only on macOS, results in a hidden
|
||||
title bar and a full size content window, the traffic light buttons will
|
||||
display when being hovered over in the top left of the window.
|
||||
**Note:** This option is currently experimental.
|
||||
* `trafficLightPosition` [Point](structures/point.md) (optional) _macOS_ -
|
||||
Set a custom position for the traffic light buttons in frameless windows.
|
||||
* `roundedCorners` boolean (optional) _macOS_ - Whether frameless window
|
||||
should have rounded corners on macOS. Default is `true`.
|
||||
* `fullscreenWindowTitle` boolean (optional) _macOS_ _Deprecated_ - Shows
|
||||
the title in the title bar in full screen mode on macOS for `hiddenInset`
|
||||
titleBarStyle. Default is `false`.
|
||||
* `thickFrame` boolean (optional) - Use `WS_THICKFRAME` style for frameless windows on
|
||||
Windows, which adds standard window frame. Setting it to `false` will remove
|
||||
window shadow and window animations. Default is `true`.
|
||||
* `vibrancy` string (optional) - Add a type of vibrancy effect to the window, only on
|
||||
macOS. Can be `appearance-based`, `light`, `dark`, `titlebar`, `selection`,
|
||||
`menu`, `popover`, `sidebar`, `medium-light`, `ultra-dark`, `header`, `sheet`, `window`, `hud`, `fullscreen-ui`, `tooltip`, `content`, `under-window`, or `under-page`. Please note that `appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark` are deprecated and have been removed in macOS Catalina (10.15).
|
||||
* `zoomToPageWidth` boolean (optional) - Controls the behavior on macOS when
|
||||
option-clicking the green stoplight button on the toolbar or by clicking the
|
||||
Window > Zoom menu item. If `true`, the window will grow to the preferred
|
||||
width of the web page when zoomed, `false` will cause it to zoom to the
|
||||
width of the screen. This will also affect the behavior when calling
|
||||
`maximize()` directly. Default is `false`.
|
||||
* `tabbingIdentifier` string (optional) - Tab group name, allows opening the
|
||||
window as a native tab on macOS 10.12+. Windows with the same tabbing
|
||||
identifier will be grouped together. This also adds a native new tab button
|
||||
to your window's tab bar and allows your `app` and window to receive the
|
||||
`new-window-for-tab` event.
|
||||
* `vibrancy` string (optional) _macOS_ - Add a type of vibrancy effect to
|
||||
the window, only on macOS. Can be `appearance-based`, `light`, `dark`,
|
||||
`titlebar`, `selection`, `menu`, `popover`, `sidebar`, `medium-light`,
|
||||
`ultra-dark`, `header`, `sheet`, `window`, `hud`, `fullscreen-ui`,
|
||||
`tooltip`, `content`, `under-window`, or `under-page`. Please note that
|
||||
`appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark` are
|
||||
deprecated and have been removed in macOS Catalina (10.15).
|
||||
* `zoomToPageWidth` boolean (optional) _macOS_ - Controls the behavior on
|
||||
macOS when option-clicking the green stoplight button on the toolbar or by
|
||||
clicking the Window > Zoom menu item. If `true`, the window will grow to
|
||||
the preferred width of the web page when zoomed, `false` will cause it to
|
||||
zoom to the width of the screen. This will also affect the behavior when
|
||||
calling `maximize()` directly. Default is `false`.
|
||||
* `tabbingIdentifier` string (optional) _macOS_ - Tab group name, allows
|
||||
opening the window as a native tab on macOS 10.12+. Windows with the same
|
||||
tabbing identifier will be grouped together. This also adds a native new
|
||||
tab button to your window's tab bar and allows your `app` and window to
|
||||
receive the `new-window-for-tab` event.
|
||||
* `webPreferences` Object (optional) - Settings of web page's features.
|
||||
* `devTools` boolean (optional) - Whether to enable DevTools. If it is set to `false`, can not use `BrowserWindow.webContents.openDevTools()` to open DevTools. Default is `true`.
|
||||
* `nodeIntegration` boolean (optional) - Whether node integration is enabled.
|
||||
@@ -310,8 +322,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
* `plugins` boolean (optional) - Whether plugins should be enabled. Default is `false`.
|
||||
* `experimentalFeatures` boolean (optional) - Enables Chromium's experimental features.
|
||||
Default is `false`.
|
||||
* `scrollBounce` boolean (optional) - Enables scroll bounce (rubber banding) effect on
|
||||
macOS. Default is `false`.
|
||||
* `scrollBounce` boolean (optional) _macOS_ - Enables scroll bounce
|
||||
(rubber banding) effect on macOS. Default is `false`.
|
||||
* `enableBlinkFeatures` string (optional) - A list of feature strings separated by `,`, like
|
||||
`CSSVariables,KeyboardEventKey` to enable. The full list of supported feature
|
||||
strings can be found in the [RuntimeEnabledFeatures.json5][runtime-enabled-features]
|
||||
@@ -413,13 +425,17 @@ Possible values are:
|
||||
|
||||
* On Linux, possible types are `desktop`, `dock`, `toolbar`, `splash`,
|
||||
`notification`.
|
||||
* On macOS, possible types are `desktop`, `textured`.
|
||||
* On macOS, possible types are `desktop`, `textured`, `panel`.
|
||||
* The `textured` type adds metal gradient appearance
|
||||
(`NSTexturedBackgroundWindowMask`).
|
||||
(`NSWindowStyleMaskTexturedBackground`).
|
||||
* The `desktop` type places the window at the desktop background window level
|
||||
(`kCGDesktopWindowLevel - 1`). Note that desktop window will not receive
|
||||
focus, keyboard or mouse events, but you can use `globalShortcut` to receive
|
||||
input sparingly.
|
||||
* The `panel` type enables the window to float on top of full-screened apps
|
||||
by adding the `NSWindowStyleMaskNonactivatingPanel` style mask,normally
|
||||
reserved for NSPanel, at runtime. Also, the window will appear on all
|
||||
spaces (desktops).
|
||||
* On Windows, possible type is `toolbar`.
|
||||
|
||||
### Instance Events
|
||||
@@ -774,7 +790,7 @@ A `boolean` property that determines whether the window is in fullscreen mode.
|
||||
|
||||
A `boolean` property that determines whether the window is focusable.
|
||||
|
||||
#### `win.visibleOnAllWorkspaces`
|
||||
#### `win.visibleOnAllWorkspaces` _macOS_ _Linux_
|
||||
|
||||
A `boolean` property that determines whether the window is visible on all workspaces.
|
||||
|
||||
@@ -811,13 +827,13 @@ A `string` property that determines the title of the native window.
|
||||
|
||||
**Note:** The title of the web page can be different from the title of the native window.
|
||||
|
||||
#### `win.minimizable`
|
||||
#### `win.minimizable` _macOS_ _Windows_
|
||||
|
||||
A `boolean` property that determines whether the window can be manually minimized by user.
|
||||
|
||||
On Linux the setter is a no-op, although the getter returns `true`.
|
||||
|
||||
#### `win.maximizable`
|
||||
#### `win.maximizable` _macOS_ _Windows_
|
||||
|
||||
A `boolean` property that determines whether the window can be manually maximized by user.
|
||||
|
||||
@@ -832,13 +848,13 @@ maximizes the window.
|
||||
|
||||
A `boolean` property that determines whether the window can be manually resized by user.
|
||||
|
||||
#### `win.closable`
|
||||
#### `win.closable` _macOS_ _Windows_
|
||||
|
||||
A `boolean` property that determines whether the window can be manually closed by user.
|
||||
|
||||
On Linux the setter is a no-op, although the getter returns `true`.
|
||||
|
||||
#### `win.movable`
|
||||
#### `win.movable` _macOS_ _Windows_
|
||||
|
||||
A `boolean` property that determines Whether the window can be moved by user.
|
||||
|
||||
@@ -1635,7 +1651,7 @@ Changes window icon.
|
||||
|
||||
Sets whether the window traffic light buttons should be visible.
|
||||
|
||||
#### `win.setAutoHideMenuBar(hide)`
|
||||
#### `win.setAutoHideMenuBar(hide)` _Windows_ _Linux_
|
||||
|
||||
* `hide` boolean
|
||||
|
||||
@@ -1644,7 +1660,7 @@ menu bar will only show when users press the single `Alt` key.
|
||||
|
||||
If the menu bar is already visible, calling `setAutoHideMenuBar(true)` won't hide it immediately.
|
||||
|
||||
#### `win.isMenuBarAutoHide()`
|
||||
#### `win.isMenuBarAutoHide()` _Windows_ _Linux_
|
||||
|
||||
Returns `boolean` - Whether menu bar automatically hides itself.
|
||||
|
||||
@@ -1654,11 +1670,11 @@ Returns `boolean` - Whether menu bar automatically hides itself.
|
||||
|
||||
Sets whether the menu bar should be visible. If the menu bar is auto-hide, users can still bring up the menu bar by pressing the single `Alt` key.
|
||||
|
||||
#### `win.isMenuBarVisible()`
|
||||
#### `win.isMenuBarVisible()` _Windows_ _Linux_
|
||||
|
||||
Returns `boolean` - Whether the menu bar is visible.
|
||||
|
||||
#### `win.setVisibleOnAllWorkspaces(visible[, options])`
|
||||
#### `win.setVisibleOnAllWorkspaces(visible[, options])` _macOS_ _Linux_
|
||||
|
||||
* `visible` boolean
|
||||
* `options` Object (optional)
|
||||
@@ -1676,7 +1692,7 @@ Sets whether the window should be visible on all workspaces.
|
||||
|
||||
**Note:** This API does nothing on Windows.
|
||||
|
||||
#### `win.isVisibleOnAllWorkspaces()`
|
||||
#### `win.isVisibleOnAllWorkspaces()` _macOS_ _Linux_
|
||||
|
||||
Returns `boolean` - Whether the window is visible on all workspaces.
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ the first write will throw an error. If the passed value is not a `string`, its
|
||||
|
||||
Certain headers are restricted from being set by apps. These headers are
|
||||
listed below. More information on restricted headers can be found in
|
||||
[Chromium's header utils](https://source.chromium.org/chromium/chromium/src/+/master:services/network/public/cpp/header_util.cc;drc=1562cab3f1eda927938f8f4a5a91991fefde66d3;bpv=1;bpt=1;l=22).
|
||||
[Chromium's header utils](https://source.chromium.org/chromium/chromium/src/+/main:services/network/public/cpp/header_util.cc;drc=1562cab3f1eda927938f8f4a5a91991fefde66d3;bpv=1;bpt=1;l=22).
|
||||
|
||||
* `Content-Length`
|
||||
* `Host`
|
||||
|
||||
@@ -274,8 +274,8 @@ By default inspector websocket url is available in stderr and under /json/list e
|
||||
[ready]: app.md#event-ready
|
||||
[play-silent-audio]: https://github.com/atom/atom/pull/9485/files
|
||||
[debugging-main-process]: ../tutorial/debugging-main-process.md
|
||||
[logging]: https://source.chromium.org/chromium/chromium/src/+/master:base/logging.h
|
||||
[logging]: https://source.chromium.org/chromium/chromium/src/+/main:base/logging.h
|
||||
[node-cli]: https://nodejs.org/api/cli.html
|
||||
[play-silent-audio]: https://github.com/atom/atom/pull/9485/files
|
||||
[ready]: app.md#event-ready
|
||||
[severities]: https://source.chromium.org/chromium/chromium/src/+/master:base/logging.h?q=logging::LogSeverity&ss=chromium
|
||||
[severities]: https://source.chromium.org/chromium/chromium/src/+/main:base/logging.h?q=logging::LogSeverity&ss=chromium
|
||||
|
||||
@@ -36,7 +36,7 @@ Returns `Promise<string[]>` - resolves with an array of category groups once all
|
||||
|
||||
Get a set of category groups. The category groups can change as new code paths
|
||||
are reached. See also the [list of built-in tracing
|
||||
categories](https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/builtin_categories.h).
|
||||
categories](https://chromium.googlesource.com/chromium/src/+/main/base/trace_event/builtin_categories.h).
|
||||
|
||||
> **NOTE:** Electron adds a non-default tracing category called `"electron"`.
|
||||
> This category can be used to capture Electron-specific tracing events.
|
||||
|
||||
@@ -35,7 +35,7 @@ page you load in your renderer executes code in this world.
|
||||
|
||||
When `contextIsolation` is enabled in your `webPreferences` (this is the default behavior since Electron 12.0.0), your `preload` scripts run in an
|
||||
"Isolated World". You can read more about context isolation and what it affects in the
|
||||
[security](../tutorial/security.md#3-enable-context-isolation-for-remote-content) docs.
|
||||
[security](../tutorial/security.md#3-enable-context-isolation) docs.
|
||||
|
||||
## Methods
|
||||
|
||||
|
||||
@@ -139,8 +139,7 @@ green and non-draggable regions will be colored red to aid debugging.
|
||||
|
||||
### `ELECTRON_DEBUG_NOTIFICATIONS`
|
||||
|
||||
Adds extra logs to [`Notification`](./notification.md) lifecycles on macOS to aid in debugging. Extra logging will be displayed when new Notifications are created or activated. They will also be displayed when common a
|
||||
tions are taken: a notification is shown, dismissed, its button is clicked, or it is replied to.
|
||||
Adds extra logs to [`Notification`](./notification.md) lifecycles on macOS to aid in debugging. Extra logging will be displayed when new Notifications are created or activated. They will also be displayed when common actions are taken: a notification is shown, dismissed, its button is clicked, or it is replied to.
|
||||
|
||||
Sample output:
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
---
|
||||
title: "ipcMain"
|
||||
description: "Communicate asynchronously from the main process to renderer processes."
|
||||
slug: ipc-main
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
# ipcMain
|
||||
|
||||
> Communicate asynchronously from the main process to renderer processes.
|
||||
@@ -9,7 +16,9 @@ process, it handles asynchronous and synchronous messages sent from a renderer
|
||||
process (web page). Messages sent from a renderer will be emitted to this
|
||||
module.
|
||||
|
||||
## Sending Messages
|
||||
For usage examples, check out the [IPC tutorial].
|
||||
|
||||
## Sending messages
|
||||
|
||||
It is also possible to send messages from the main process to the renderer
|
||||
process, see [webContents.send][web-contents-send] for more information.
|
||||
@@ -21,36 +30,6 @@ process, see [webContents.send][web-contents-send] for more information.
|
||||
coming from frames that aren't the main frame (e.g. iframes) whereas
|
||||
`event.sender.send(...)` will always send to the main frame.
|
||||
|
||||
An example of sending and handling messages between the render and main
|
||||
processes:
|
||||
|
||||
```javascript
|
||||
// In main process.
|
||||
const { ipcMain } = require('electron')
|
||||
ipcMain.on('asynchronous-message', (event, arg) => {
|
||||
console.log(arg) // prints "ping"
|
||||
event.reply('asynchronous-reply', 'pong')
|
||||
})
|
||||
|
||||
ipcMain.on('synchronous-message', (event, arg) => {
|
||||
console.log(arg) // prints "ping"
|
||||
event.returnValue = 'pong'
|
||||
})
|
||||
```
|
||||
|
||||
```javascript
|
||||
// In renderer process (web page).
|
||||
// NB. Electron APIs are only accessible from preload, unless contextIsolation is disabled.
|
||||
// See https://www.electronjs.org/docs/tutorial/process-model#preload-scripts for more details.
|
||||
const { ipcRenderer } = require('electron')
|
||||
console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) // prints "pong"
|
||||
|
||||
ipcRenderer.on('asynchronous-reply', (event, arg) => {
|
||||
console.log(arg) // prints "pong"
|
||||
})
|
||||
ipcRenderer.send('asynchronous-message', 'ping')
|
||||
```
|
||||
|
||||
## Methods
|
||||
|
||||
The `ipcMain` module has the following method to listen for events:
|
||||
@@ -59,7 +38,7 @@ The `ipcMain` module has the following method to listen for events:
|
||||
|
||||
* `channel` string
|
||||
* `listener` Function
|
||||
* `event` IpcMainEvent
|
||||
* `event` [IpcMainEvent][ipc-main-event]
|
||||
* `...args` any[]
|
||||
|
||||
Listens to `channel`, when a new message arrives `listener` would be called with
|
||||
@@ -69,7 +48,7 @@ Listens to `channel`, when a new message arrives `listener` would be called with
|
||||
|
||||
* `channel` string
|
||||
* `listener` Function
|
||||
* `event` IpcMainEvent
|
||||
* `event` [IpcMainEvent][ipc-main-event]
|
||||
* `...args` any[]
|
||||
|
||||
Adds a one time `listener` function for the event. This `listener` is invoked
|
||||
@@ -93,8 +72,8 @@ Removes listeners of the specified `channel`.
|
||||
### `ipcMain.handle(channel, listener)`
|
||||
|
||||
* `channel` string
|
||||
* `listener` Function<Promise\<void> | any>
|
||||
* `event` IpcMainInvokeEvent
|
||||
* `listener` Function<Promise\<void> | any>
|
||||
* `event` [IpcMainInvokeEvent][ipc-main-invoke-event]
|
||||
* `...args` any[]
|
||||
|
||||
Adds a handler for an `invoke`able IPC. This handler will be called whenever a
|
||||
@@ -104,14 +83,14 @@ If `listener` returns a Promise, the eventual result of the promise will be
|
||||
returned as a reply to the remote caller. Otherwise, the return value of the
|
||||
listener will be used as the value of the reply.
|
||||
|
||||
```js
|
||||
// Main process
|
||||
```js title='Main Process'
|
||||
ipcMain.handle('my-invokable-ipc', async (event, ...args) => {
|
||||
const result = await somePromise(...args)
|
||||
return result
|
||||
})
|
||||
```
|
||||
|
||||
// Renderer process
|
||||
```js title='Renderer Process'
|
||||
async () => {
|
||||
const result = await ipcRenderer.invoke('my-invokable-ipc', arg1, arg2)
|
||||
// ...
|
||||
@@ -130,7 +109,7 @@ provided to the renderer process. Please refer to
|
||||
### `ipcMain.handleOnce(channel, listener)`
|
||||
|
||||
* `channel` string
|
||||
* `listener` Function<Promise\<void> | any>
|
||||
* `listener` Function<Promise\<void> | any>
|
||||
* `event` IpcMainInvokeEvent
|
||||
* `...args` any[]
|
||||
|
||||
@@ -146,13 +125,16 @@ Removes any handler for `channel`, if present.
|
||||
## IpcMainEvent object
|
||||
|
||||
The documentation for the `event` object passed to the `callback` can be found
|
||||
in the [`ipc-main-event`](structures/ipc-main-event.md) structure docs.
|
||||
in the [`ipc-main-event`][ipc-main-event] structure docs.
|
||||
|
||||
## IpcMainInvokeEvent object
|
||||
|
||||
The documentation for the `event` object passed to `handle` callbacks can be
|
||||
found in the [`ipc-main-invoke-event`](structures/ipc-main-invoke-event.md)
|
||||
found in the [`ipc-main-invoke-event`][ipc-main-invoke-event]
|
||||
structure docs.
|
||||
|
||||
[IPC tutorial]: ../tutorial/ipc.md
|
||||
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
|
||||
[web-contents-send]: web-contents.md#contentssendchannel-args
|
||||
[web-contents-send]: ../api/web-contents.md#contentssendchannel-args
|
||||
[ipc-main-event]:../api/structures/ipc-main-event.md
|
||||
[ipc-main-invoke-event]:../api/structures/ipc-main-invoke-event.md
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
---
|
||||
title: "ipcRenderer"
|
||||
description: "Communicate asynchronously from a renderer process to the main process."
|
||||
slug: ipc-renderer
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
# ipcRenderer
|
||||
|
||||
> Communicate asynchronously from a renderer process to the main process.
|
||||
@@ -9,7 +16,7 @@ methods so you can send synchronous and asynchronous messages from the render
|
||||
process (web page) to the main process. You can also receive replies from the
|
||||
main process.
|
||||
|
||||
See [ipcMain](ipc-main.md) for code examples.
|
||||
See [IPC tutorial](../tutorial/ipc.md) for code examples.
|
||||
|
||||
## Methods
|
||||
|
||||
@@ -70,7 +77,7 @@ throw an exception.
|
||||
> them. Attempting to send such objects over IPC will result in an error.
|
||||
|
||||
The main process handles it by listening for `channel` with the
|
||||
[`ipcMain`](ipc-main.md) module.
|
||||
[`ipcMain`](./ipc-main.md) module.
|
||||
|
||||
If you need to transfer a [`MessagePort`][] to the main process, use [`ipcRenderer.postMessage`](#ipcrendererpostmessagechannel-message-transfer).
|
||||
|
||||
@@ -98,7 +105,7 @@ throw an exception.
|
||||
> them. Attempting to send such objects over IPC will result in an error.
|
||||
|
||||
The main process should listen for `channel` with
|
||||
[`ipcMain.handle()`](ipc-main.md#ipcmainhandlechannel-listener).
|
||||
[`ipcMain.handle()`](./ipc-main.md#ipcmainhandlechannel-listener).
|
||||
|
||||
For example:
|
||||
|
||||
@@ -124,11 +131,11 @@ If you do not need a response to the message, consider using [`ipcRenderer.send`
|
||||
* `channel` string
|
||||
* `...args` any[]
|
||||
|
||||
Returns `any` - The value sent back by the [`ipcMain`](ipc-main.md) handler.
|
||||
Returns `any` - The value sent back by the [`ipcMain`](./ipc-main.md) handler.
|
||||
|
||||
Send a message to the main process via `channel` and expect a result
|
||||
synchronously. Arguments will be serialized with the [Structured Clone
|
||||
Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will not be
|
||||
Algorithm][SCA], just like [`window.postMessage`], so prototype chains will not be
|
||||
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||
throw an exception.
|
||||
|
||||
@@ -140,13 +147,13 @@ throw an exception.
|
||||
> Electron's IPC to the main process, as the main process would have no way to decode
|
||||
> them. Attempting to send such objects over IPC will result in an error.
|
||||
|
||||
The main process handles it by listening for `channel` with [`ipcMain`](ipc-main.md) module,
|
||||
The main process handles it by listening for `channel` with [`ipcMain`](./ipc-main.md) module,
|
||||
and replies by setting `event.returnValue`.
|
||||
|
||||
> :warning: **WARNING**: Sending a synchronous message will block the whole
|
||||
> renderer process until the reply is received, so use this method only as a
|
||||
> last resort. It's much better to use the asynchronous version,
|
||||
> [`invoke()`](ipc-renderer.md#ipcrendererinvokechannel-args).
|
||||
> [`invoke()`](./ipc-renderer.md#ipcrendererinvokechannel-args).
|
||||
|
||||
### `ipcRenderer.postMessage(channel, message, [transfer])`
|
||||
|
||||
@@ -158,7 +165,7 @@ Send a message to the main process, optionally transferring ownership of zero
|
||||
or more [`MessagePort`][] objects.
|
||||
|
||||
The transferred `MessagePort` objects will be available in the main process as
|
||||
[`MessagePortMain`](message-port-main.md) objects by accessing the `ports`
|
||||
[`MessagePortMain`](./message-port-main.md) objects by accessing the `ports`
|
||||
property of the emitted event.
|
||||
|
||||
For example:
|
||||
@@ -197,7 +204,7 @@ the host page instead of the main process.
|
||||
## Event object
|
||||
|
||||
The documentation for the `event` object passed to the `callback` can be found
|
||||
in the [`ipc-renderer-event`](structures/ipc-renderer-event.md) structure docs.
|
||||
in the [`ipc-renderer-event`](./structures/ipc-renderer-event.md) structure docs.
|
||||
|
||||
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
|
||||
[SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
|
||||
|
||||
@@ -149,7 +149,7 @@ console.log(image)
|
||||
* `options` Object
|
||||
* `width` Integer
|
||||
* `height` Integer
|
||||
* `scaleFactor` Double (optional) - Defaults to 1.0.
|
||||
* `scaleFactor` Number (optional) - Defaults to 1.0.
|
||||
|
||||
Returns `NativeImage`
|
||||
|
||||
@@ -162,7 +162,7 @@ pixel data returned by `toBitmap()`. The specific format is platform-dependent.
|
||||
* `options` Object (optional)
|
||||
* `width` Integer (optional) - Required for bitmap buffers.
|
||||
* `height` Integer (optional) - Required for bitmap buffers.
|
||||
* `scaleFactor` Double (optional) - Defaults to 1.0.
|
||||
* `scaleFactor` Number (optional) - Defaults to 1.0.
|
||||
|
||||
Returns `NativeImage`
|
||||
|
||||
@@ -225,7 +225,7 @@ The following methods are available on instances of the `NativeImage` class:
|
||||
#### `image.toPNG([options])`
|
||||
|
||||
* `options` Object (optional)
|
||||
* `scaleFactor` Double (optional) - Defaults to 1.0.
|
||||
* `scaleFactor` Number (optional) - Defaults to 1.0.
|
||||
|
||||
Returns `Buffer` - A [Buffer][buffer] that contains the image's `PNG` encoded data.
|
||||
|
||||
@@ -238,7 +238,7 @@ Returns `Buffer` - A [Buffer][buffer] that contains the image's `JPEG` encoded d
|
||||
#### `image.toBitmap([options])`
|
||||
|
||||
* `options` Object (optional)
|
||||
* `scaleFactor` Double (optional) - Defaults to 1.0.
|
||||
* `scaleFactor` Number (optional) - Defaults to 1.0.
|
||||
|
||||
Returns `Buffer` - A [Buffer][buffer] that contains a copy of the image's raw bitmap pixel
|
||||
data.
|
||||
@@ -246,14 +246,14 @@ data.
|
||||
#### `image.toDataURL([options])`
|
||||
|
||||
* `options` Object (optional)
|
||||
* `scaleFactor` Double (optional) - Defaults to 1.0.
|
||||
* `scaleFactor` Number (optional) - Defaults to 1.0.
|
||||
|
||||
Returns `string` - The data URL of the image.
|
||||
|
||||
#### `image.getBitmap([options])`
|
||||
|
||||
* `options` Object (optional)
|
||||
* `scaleFactor` Double (optional) - Defaults to 1.0.
|
||||
* `scaleFactor` Number (optional) - Defaults to 1.0.
|
||||
|
||||
Returns `Buffer` - A [Buffer][buffer] that contains the image's raw bitmap pixel data.
|
||||
|
||||
@@ -276,7 +276,7 @@ Returns `boolean` - Whether the image is empty.
|
||||
|
||||
#### `image.getSize([scaleFactor])`
|
||||
|
||||
* `scaleFactor` Double (optional) - Defaults to 1.0.
|
||||
* `scaleFactor` Number (optional) - Defaults to 1.0.
|
||||
|
||||
Returns [`Size`](structures/size.md).
|
||||
|
||||
@@ -317,20 +317,20 @@ will be preserved in the resized image.
|
||||
|
||||
#### `image.getAspectRatio([scaleFactor])`
|
||||
|
||||
* `scaleFactor` Double (optional) - Defaults to 1.0.
|
||||
* `scaleFactor` Number (optional) - Defaults to 1.0.
|
||||
|
||||
Returns `Float` - The image's aspect ratio.
|
||||
Returns `Number` - The image's aspect ratio.
|
||||
|
||||
If `scaleFactor` is passed, this will return the aspect ratio corresponding to the image representation most closely matching the passed value.
|
||||
|
||||
#### `image.getScaleFactors()`
|
||||
|
||||
Returns `Float[]` - An array of all scale factors corresponding to representations for a given nativeImage.
|
||||
Returns `Number[]` - An array of all scale factors corresponding to representations for a given nativeImage.
|
||||
|
||||
#### `image.addRepresentation(options)`
|
||||
|
||||
* `options` Object
|
||||
* `scaleFactor` Double - The scale factor to add the image representation for.
|
||||
* `scaleFactor` Number (optional) - The scale factor to add the image representation for.
|
||||
* `width` Integer (optional) - Defaults to 0. Required if a bitmap buffer
|
||||
is specified as `buffer`.
|
||||
* `height` Integer (optional) - Defaults to 0. Required if a bitmap buffer
|
||||
|
||||
48
docs/api/push-notifications.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# pushNotifications
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
|
||||
> Register for and receive notifications from remote push notification services
|
||||
|
||||
For example, when registering for push notifications via Apple push notification services (APNS):
|
||||
|
||||
```javascript
|
||||
const { pushNotifications, Notification } = require('electron')
|
||||
|
||||
pushNotifications.registerForAPNSNotifications().then((token) => {
|
||||
// forward token to your remote notification server
|
||||
})
|
||||
|
||||
pushNotifications.on('received-apns-notification', (event, userInfo) => {
|
||||
// generate a new Notification object with the relevant userInfo fields
|
||||
})
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
The `pushNotification` module emits the following events:
|
||||
|
||||
#### Event: 'received-apns-notification' _macOS_
|
||||
|
||||
Returns:
|
||||
|
||||
* `userInfo` Record<String, any>
|
||||
|
||||
Emitted when the app receives a remote notification while running.
|
||||
See: https://developer.apple.com/documentation/appkit/nsapplicationdelegate/1428430-application?language=objc
|
||||
|
||||
## Methods
|
||||
|
||||
The `pushNotification` module has the following methods:
|
||||
|
||||
### `pushNotifications.registerForAPNSNotifications()` _macOS_
|
||||
|
||||
Returns `Promise<string>`
|
||||
|
||||
Registers the app with Apple Push Notification service (APNS) to receive [Badge, Sound, and Alert](https://developer.apple.com/documentation/appkit/sremotenotificationtype?language=objc) notifications. If registration is successful, the promise will be resolved with the APNS device token. Otherwise, the promise will be rejected with an error message.
|
||||
See: https://developer.apple.com/documentation/appkit/nsapplication/1428476-registerforremotenotificationtyp?language=objc
|
||||
|
||||
### `pushNotifications.unregisterForAPNSNotifications()` _macOS_
|
||||
|
||||
Unregisters the app from notifications received from APNS.
|
||||
See: https://developer.apple.com/documentation/appkit/nsapplication/1428747-unregisterforremotenotifications?language=objc
|
||||
@@ -253,9 +253,11 @@ Returns:
|
||||
* `device` [HIDDevice[]](structures/hid-device.md)
|
||||
* `frame` [WebFrameMain](web-frame-main.md)
|
||||
|
||||
Emitted when a new HID device becomes available. For example, when a new USB device is plugged in.
|
||||
|
||||
This event will only be emitted after `navigator.hid.requestDevice` has been called and `select-hid-device` has fired.
|
||||
Emitted after `navigator.hid.requestDevice` has been called and
|
||||
`select-hid-device` has fired if a new device becomes available before
|
||||
the callback from `select-hid-device` is called. This event is intended for
|
||||
use when using a UI to ask users to pick a device so that the UI can be updated
|
||||
with the newly added device.
|
||||
|
||||
#### Event: 'hid-device-removed'
|
||||
|
||||
@@ -266,9 +268,24 @@ Returns:
|
||||
* `device` [HIDDevice[]](structures/hid-device.md)
|
||||
* `frame` [WebFrameMain](web-frame-main.md)
|
||||
|
||||
Emitted when a HID device has been removed. For example, this event will fire when a USB device is unplugged.
|
||||
Emitted after `navigator.hid.requestDevice` has been called and
|
||||
`select-hid-device` has fired if a device has been removed before the callback
|
||||
from `select-hid-device` is called. This event is intended for use when using
|
||||
a UI to ask users to pick a device so that the UI can be updated to remove the
|
||||
specified device.
|
||||
|
||||
This event will only be emitted after `navigator.hid.requestDevice` has been called and `select-hid-device` has fired.
|
||||
#### Event: 'hid-device-revoked'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `device` [HIDDevice[]](structures/hid-device.md)
|
||||
* `origin` string (optional) - The origin that the device has been revoked from.
|
||||
|
||||
Emitted after `HIDDevice.forget()` has been called. This event can be used
|
||||
to help maintain persistent storage of permissions when
|
||||
`setDevicePermissionHandler` is used.
|
||||
|
||||
#### Event: 'select-serial-port'
|
||||
|
||||
@@ -348,7 +365,11 @@ Returns:
|
||||
* `port` [SerialPort](structures/serial-port.md)
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
|
||||
Emitted after `navigator.serial.requestPort` has been called and `select-serial-port` has fired if a new serial port becomes available. For example, this event will fire when a new USB device is plugged in.
|
||||
Emitted after `navigator.serial.requestPort` has been called and
|
||||
`select-serial-port` has fired if a new serial port becomes available before
|
||||
the callback from `select-serial-port` is called. This event is intended for
|
||||
use when using a UI to ask users to pick a port so that the UI can be updated
|
||||
with the newly added port.
|
||||
|
||||
#### Event: 'serial-port-removed'
|
||||
|
||||
@@ -358,7 +379,11 @@ Returns:
|
||||
* `port` [SerialPort](structures/serial-port.md)
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
|
||||
Emitted after `navigator.serial.requestPort` has been called and `select-serial-port` has fired if a serial port has been removed. For example, this event will fire when a USB device is unplugged.
|
||||
Emitted after `navigator.serial.requestPort` has been called and
|
||||
`select-serial-port` has fired if a serial port has been removed before the
|
||||
callback from `select-serial-port` is called. This event is intended for use
|
||||
when using a UI to ask users to pick a port so that the UI can be updated
|
||||
to remove the specified port.
|
||||
|
||||
### Instance Methods
|
||||
|
||||
@@ -567,7 +592,7 @@ the original network configuration.
|
||||
* `errorCode` Integer - Error code.
|
||||
* `callback` Function
|
||||
* `verificationResult` Integer - Value can be one of certificate error codes
|
||||
from [here](https://source.chromium.org/chromium/chromium/src/+/master:net/base/net_error_list.h).
|
||||
from [here](https://source.chromium.org/chromium/chromium/src/+/main:net/base/net_error_list.h).
|
||||
Apart from the certificate error codes, the following special codes can be used.
|
||||
* `0` - Indicates success and disables Certificate Transparency verification.
|
||||
* `-2` - Indicates failure.
|
||||
@@ -680,7 +705,6 @@ session.fromPartition('some-partition').setPermissionCheckHandler((webContents,
|
||||
* `deviceType` string - The type of device that permission is being requested on, can be `hid` or `serial`.
|
||||
* `origin` string - The origin URL of the device permission check.
|
||||
* `device` [HIDDevice](structures/hid-device.md) | [SerialPort](structures/serial-port.md)- the device that permission is being requested for.
|
||||
* `frame` [WebFrameMain](web-frame-main.md) - WebFrameMain checking the device permission.
|
||||
|
||||
Sets the handler which can be used to respond to device permission checks for the `session`.
|
||||
Returning `true` will allow the device to be permitted and `false` will reject it.
|
||||
@@ -688,8 +712,8 @@ To clear the handler, call `setDevicePermissionHandler(null)`.
|
||||
This handler can be used to provide default permissioning to devices without first calling for permission
|
||||
to devices (eg via `navigator.hid.requestDevice`). If this handler is not defined, the default device
|
||||
permissions as granted through device selection (eg via `navigator.hid.requestDevice`) will be used.
|
||||
Additionally, the default behavior of Electron is to store granted device permision through the lifetime
|
||||
of the corresponding WebContents. If longer term storage is needed, a developer can store granted device
|
||||
Additionally, the default behavior of Electron is to store granted device permision in memory.
|
||||
If longer term storage is needed, a developer can store granted device
|
||||
permissions (eg when handling the `select-hid-device` event) and then read from that storage with `setDevicePermissionHandler`.
|
||||
|
||||
```javascript
|
||||
|
||||
@@ -31,4 +31,4 @@
|
||||
* `uploadData` [ProtocolResponseUploadData](protocol-response-upload-data.md) (optional) - The data used as upload data. This is only
|
||||
used for URL responses when `method` is `"POST"`.
|
||||
|
||||
[net-error]: https://source.chromium.org/chromium/chromium/src/+/master:net/base/net_error_list.h
|
||||
[net-error]: https://source.chromium.org/chromium/chromium/src/+/main:net/base/net_error_list.h
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* `enable_argument_filter` boolean (optional) - if true, filter event data
|
||||
according to a specific list of events that have been manually vetted to not
|
||||
include any PII. See [the implementation in
|
||||
Chromium][trace_event_args_whitelist.cc] for specifics.
|
||||
Chromium][trace_event_args_allowlist.cc] for specifics.
|
||||
* `included_categories` string[] (optional) - a list of tracing categories to
|
||||
include. Can include glob-like patterns using `*` at the end of the category
|
||||
name. See [tracing categories][] for the list of categories.
|
||||
@@ -45,7 +45,7 @@ An example TraceConfig that roughly matches what Chrome DevTools records:
|
||||
}
|
||||
```
|
||||
|
||||
[tracing categories]: https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/builtin_categories.h
|
||||
[memory-infra docs]: https://chromium.googlesource.com/chromium/src/+/master/docs/memory-infra/memory_infra_startup_tracing.md#the-advanced-way
|
||||
[trace_event_args_whitelist.cc]: https://chromium.googlesource.com/chromium/src/+/master/services/tracing/public/cpp/trace_event_args_whitelist.cc
|
||||
[tracing categories]: https://chromium.googlesource.com/chromium/src/+/main/base/trace_event/builtin_categories.h
|
||||
[memory-infra docs]: https://chromium.googlesource.com/chromium/src/+/main/docs/memory-infra/memory_infra_startup_tracing.md#the-advanced-way
|
||||
[trace_event_args_allowlist.cc]: https://chromium.googlesource.com/chromium/src/+/main/services/tracing/public/cpp/trace_event_args_allowlist.cc
|
||||
[histogram]: https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md
|
||||
|
||||
@@ -183,11 +183,11 @@ Some popular `key` and `type`s are:
|
||||
* `NSPreferredWebServices`: `dictionary`
|
||||
* `NSUserDictionaryReplacementItems`: `array`
|
||||
|
||||
### `systemPreferences.setUserDefault(key, type, value)` _macOS_
|
||||
### `systemPreferences.setUserDefault<Type extends keyof UserDefaultTypes>(key, type, value)` _macOS_
|
||||
|
||||
* `key` string
|
||||
* `type` string - Can be `string`, `boolean`, `integer`, `float`, `double`, `url`, `array` or `dictionary`.
|
||||
* `value` string
|
||||
* `type` Type - Can be `string`, `boolean`, `integer`, `float`, `double`, `url`, `array` or `dictionary`.
|
||||
* `value` UserDefaultTypes[Type]
|
||||
|
||||
Set the value of `key` in `NSUserDefaults`.
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ for all windows, webviews, opened devtools, and devtools extension background pa
|
||||
|
||||
### `webContents.getFocusedWebContents()`
|
||||
|
||||
Returns `WebContents` - The web contents that is focused in this application, otherwise
|
||||
Returns `WebContents` | null - The web contents that is focused in this application, otherwise
|
||||
returns `null`.
|
||||
|
||||
### `webContents.fromId(id)`
|
||||
@@ -92,7 +92,7 @@ Returns:
|
||||
* `frameRoutingId` Integer
|
||||
|
||||
This event is like `did-finish-load` but emitted when the load failed.
|
||||
The full list of error codes and their meaning is available [here](https://source.chromium.org/chromium/chromium/src/+/master:net/base/net_error_list.h).
|
||||
The full list of error codes and their meaning is available [here](https://source.chromium.org/chromium/chromium/src/+/main:net/base/net_error_list.h).
|
||||
|
||||
#### Event: 'did-fail-provisional-load'
|
||||
|
||||
@@ -820,9 +820,6 @@ This event can be used to configure `webPreferences` for the `webContents`
|
||||
of a `<webview>` before it's loaded, and provides the ability to set settings
|
||||
that can't be set via `<webview>` attributes.
|
||||
|
||||
**Note:** The specified `preload` script option will appear as `preloadURL`
|
||||
(not `preload`) in the `webPreferences` object emitted with this event.
|
||||
|
||||
#### Event: 'did-attach-webview'
|
||||
|
||||
Returns:
|
||||
@@ -1431,7 +1428,7 @@ Returns `Promise<PrinterInfo[]>` - Resolves with a [`PrinterInfo[]`](structures/
|
||||
* `header` string (optional) - string to be printed as page header.
|
||||
* `footer` string (optional) - string to be printed as page footer.
|
||||
* `pageSize` string | Size (optional) - Specify page size of the printed document. Can be `A3`,
|
||||
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height`.
|
||||
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height` and `width`.
|
||||
* `callback` Function (optional)
|
||||
* `success` boolean - Indicates success of the print call.
|
||||
* `failureReason` string - Error description called back if the print fails.
|
||||
@@ -1462,43 +1459,28 @@ win.webContents.print(options, (success, errorType) => {
|
||||
#### `contents.printToPDF(options)`
|
||||
|
||||
* `options` Object
|
||||
* `headerFooter` Record<string, string> (optional) - the header and footer for the PDF.
|
||||
* `title` string - The title for the PDF header.
|
||||
* `url` string - the url for the PDF footer.
|
||||
* `landscape` boolean (optional) - `true` for landscape, `false` for portrait.
|
||||
* `marginsType` Integer (optional) - Specifies the type of margins to use. Uses 0 for
|
||||
default margin, 1 for no margin, and 2 for minimum margin.
|
||||
* `scaleFactor` number (optional) - The scale factor of the web page. Can range from 0 to 100.
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print.
|
||||
* `from` number - Index of the first page to print (0-based).
|
||||
* `to` number - Index of the last page to print (inclusive) (0-based).
|
||||
* `pageSize` string | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
|
||||
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height` and `width` in microns.
|
||||
* `printBackground` boolean (optional) - Whether to print CSS backgrounds.
|
||||
* `printSelectionOnly` boolean (optional) - Whether to print selection only.
|
||||
* `landscape` boolean (optional) - Paper orientation.`true` for landscape, `false` for portrait. Defaults to false.
|
||||
* `displayHeaderFooter` boolean (optional) - Whether to display header and footer. Defaults to false.
|
||||
* `printBackground` boolean (optional) - Whether to print background graphics. Defaults to false.
|
||||
* `scale` number(optional) - Scale of the webpage rendering. Defaults to 1.
|
||||
* `pageSize` string | Size (optional) - Specify page size of the generated PDF. Can be `A0`, `A1`, `A2`, `A3`,
|
||||
`A4`, `A5`, `A6`, `Legal`, `Letter`, `Tabloid`, `Ledger`, or an Object containing `height` and `width` in inches. Defaults to `Letter`.
|
||||
* `margins` Object (optional)
|
||||
* `top` number (optional) - Top margin in inches. Defaults to 1cm (~0.4 inches).
|
||||
* `bottom` number (optional) - Bottom margin in inches. Defaults to 1cm (~0.4 inches).
|
||||
* `left` number (optional) - Left margin in inches. Defaults to 1cm (~0.4 inches).
|
||||
* `right` number (optional) - Right margin in inches. Defaults to 1cm (~0.4 inches).
|
||||
* `pageRanges` string (optional) - Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages.
|
||||
* `headerTemplate` string (optional) - HTML template for the print header. Should be valid HTML markup with following classes used to inject printing values into them: `date` (formatted print date), `title` (document title), `url` (document location), `pageNumber` (current page number) and `totalPages` (total pages in the document). For example, `<span class=title></span>` would generate span containing the title.
|
||||
* `footerTemplate` string (optional) - HTML template for the print footer. Should use the same format as the `headerTemplate`.
|
||||
* `preferCSSPageSize` boolean (optional) - Whether or not to prefer page size as defined by css. Defaults to false, in which case the content will be scaled to fit the paper size.
|
||||
|
||||
Returns `Promise<Buffer>` - Resolves with the generated PDF data.
|
||||
|
||||
Prints window's web page as PDF with Chromium's preview printing custom
|
||||
settings.
|
||||
Prints the window's web page as PDF.
|
||||
|
||||
The `landscape` will be ignored if `@page` CSS at-rule is used in the web page.
|
||||
|
||||
By default, an empty `options` will be regarded as:
|
||||
|
||||
```javascript
|
||||
{
|
||||
marginsType: 0,
|
||||
printBackground: false,
|
||||
printSelectionOnly: false,
|
||||
landscape: false,
|
||||
pageSize: 'A4',
|
||||
scaleFactor: 100
|
||||
}
|
||||
```
|
||||
|
||||
Use `page-break-before: always;` CSS style to force to print to a new page.
|
||||
|
||||
An example of `webContents.printToPDF`:
|
||||
|
||||
```javascript
|
||||
@@ -1507,7 +1489,7 @@ const fs = require('fs')
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
const win = new BrowserWindow()
|
||||
win.loadURL('http://github.com')
|
||||
|
||||
win.webContents.on('did-finish-load', () => {
|
||||
@@ -1524,6 +1506,8 @@ win.webContents.on('did-finish-load', () => {
|
||||
})
|
||||
```
|
||||
|
||||
See [Page.printToPdf](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF) for more information.
|
||||
|
||||
#### `contents.addWorkSpace(path)`
|
||||
|
||||
* `path` string
|
||||
|
||||
@@ -16,7 +16,7 @@ win.loadURL('https://twitter.com')
|
||||
|
||||
win.webContents.on(
|
||||
'did-frame-navigate',
|
||||
(event, url, isMainFrame, frameProcessId, frameRoutingId) => {
|
||||
(event, url, httpResponseCode, httpStatusText, isMainFrame, frameProcessId, frameRoutingId) => {
|
||||
const frame = webFrameMain.fromId(frameProcessId, frameRoutingId)
|
||||
if (frame) {
|
||||
const code = 'document.body.innerHTML = document.body.innerHTML.replaceAll("heck", "h*ck")'
|
||||
@@ -195,3 +195,6 @@ have the same `routingId`.
|
||||
A `string` representing the [visibility state](https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilityState) of the frame.
|
||||
|
||||
See also how the [Page Visibility API](browser-window.md#page-visibility) is affected by other Electron APIs.
|
||||
|
||||
[SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
|
||||
[`postMessage`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
|
||||
|
||||
@@ -110,7 +110,7 @@ webFrame.setSpellCheckProvider('en-US', {
|
||||
})
|
||||
```
|
||||
|
||||
#### `webFrame.insertCSS(css[, options])`
|
||||
### `webFrame.insertCSS(css[, options])`
|
||||
|
||||
* `css` string
|
||||
* `options` Object (optional)
|
||||
|
||||
@@ -158,9 +158,6 @@ When the guest page doesn't have node integration this script will still have
|
||||
access to all Node APIs, but global objects injected by Node will be deleted
|
||||
after this script has finished executing.
|
||||
|
||||
**Note:** This option will appear as `preloadURL` (not `preload`) in
|
||||
the `webPreferences` specified to the `will-attach-webview` event.
|
||||
|
||||
### `httpreferrer`
|
||||
|
||||
```html
|
||||
@@ -559,7 +556,7 @@ Stops any `findInPage` request for the `webview` with the provided `action`.
|
||||
* `header` string (optional) - string to be printed as page header.
|
||||
* `footer` string (optional) - string to be printed as page footer.
|
||||
* `pageSize` string | Size (optional) - Specify page size of the printed document. Can be `A3`,
|
||||
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height`.
|
||||
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height` in microns.
|
||||
|
||||
Returns `Promise<void>`
|
||||
|
||||
@@ -568,21 +565,21 @@ Prints `webview`'s web page. Same as `webContents.print([options])`.
|
||||
### `<webview>.printToPDF(options)`
|
||||
|
||||
* `options` Object
|
||||
* `headerFooter` Record<string, string> (optional) - the header and footer for the PDF.
|
||||
* `title` string - The title for the PDF header.
|
||||
* `url` string - the url for the PDF footer.
|
||||
* `landscape` boolean (optional) - `true` for landscape, `false` for portrait.
|
||||
* `marginsType` Integer (optional) - Specifies the type of margins to use. Uses 0 for
|
||||
default margin, 1 for no margin, and 2 for minimum margin.
|
||||
and `width` in microns.
|
||||
* `scaleFactor` number (optional) - The scale factor of the web page. Can range from 0 to 100.
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print. On macOS, only the first range is honored.
|
||||
* `from` number - Index of the first page to print (0-based).
|
||||
* `to` number - Index of the last page to print (inclusive) (0-based).
|
||||
* `pageSize` string | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
|
||||
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height`
|
||||
* `printBackground` boolean (optional) - Whether to print CSS backgrounds.
|
||||
* `printSelectionOnly` boolean (optional) - Whether to print selection only.
|
||||
* `landscape` boolean (optional) - Paper orientation.`true` for landscape, `false` for portrait. Defaults to false.
|
||||
* `displayHeaderFooter` boolean (optional) - Whether to display header and footer. Defaults to false.
|
||||
* `printBackground` boolean (optional) - Whether to print background graphics. Defaults to false.
|
||||
* `scale` number(optional) - Scale of the webpage rendering. Defaults to 1.
|
||||
* `pageSize` string | Size (optional) - Specify page size of the generated PDF. Can be `A0`, `A1`, `A2`, `A3`,
|
||||
`A4`, `A5`, `A6`, `Legal`, `Letter`, `Tabloid`, `Ledger`, or an Object containing `height` and `width` in inches. Defaults to `Letter`.
|
||||
* `margins` Object (optional)
|
||||
* `top` number (optional) - Top margin in inches. Defaults to 1cm (~0.4 inches).
|
||||
* `bottom` number (optional) - Bottom margin in inches. Defaults to 1cm (~0.4 inches).
|
||||
* `left` number (optional) - Left margin in inches. Defaults to 1cm (~0.4 inches).
|
||||
* `right` number (optional) - Right margin in inches. Defaults to 1cm (~0.4 inches).
|
||||
* `pageRanges` string (optional) - Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages.
|
||||
* `headerTemplate` string (optional) - HTML template for the print header. Should be valid HTML markup with following classes used to inject printing values into them: `date` (formatted print date), `title` (document title), `url` (document location), `pageNumber` (current page number) and `totalPages` (total pages in the document). For example, `<span class=title></span>` would generate span containing the title.
|
||||
* `footerTemplate` string (optional) - HTML template for the print footer. Should use the same format as the `headerTemplate`.
|
||||
* `preferCSSPageSize` boolean (optional) - Whether or not to prefer page size as defined by css. Defaults to false, in which case the content will be scaled to fit the paper size.
|
||||
|
||||
Returns `Promise<Uint8Array>` - Resolves with the generated PDF data.
|
||||
|
||||
|
||||
@@ -73,6 +73,11 @@ creating the window. Note that this is more powerful than passing options
|
||||
through the feature string, as the renderer has more limited privileges in
|
||||
deciding security preferences than the main process.
|
||||
|
||||
In addition to passing in `action` and `overrideBrowserWindowOptions`,
|
||||
`outlivesOpener` can be passed like: `{ action: 'allow', outlivesOpener: true,
|
||||
overrideBrowserWindowOptions: { ... } }`. If set to `true`, the newly created
|
||||
window will not close when the opener window closes. The default value is `false`.
|
||||
|
||||
### Native `Window` example
|
||||
|
||||
```javascript
|
||||
|
||||
@@ -14,6 +14,68 @@ This document uses the following convention to categorize breaking changes:
|
||||
|
||||
## Planned Breaking API Changes (20.0)
|
||||
|
||||
### Behavior Changed: V8 Memory Cage enabled
|
||||
|
||||
The V8 memory cage has been enabled, which has implications for native modules
|
||||
which wrap non-V8 memory with `ArrayBuffer` or `Buffer`. See the [blog post
|
||||
about the V8 memory cage](https://www.electronjs.org/blog/v8-memory-cage) for
|
||||
more details.
|
||||
|
||||
### API Changed: `webContents.printToPDF()`
|
||||
|
||||
`webContents.printToPDF()` has been modified to conform to [`Page.printToPDF`](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF) in the Chrome DevTools Protocol. This has been changes in order to
|
||||
address changes upstream that made our previous implementation untenable and rife with bugs.
|
||||
|
||||
**Arguments Changed**
|
||||
|
||||
* `pageRanges`
|
||||
|
||||
**Arguments Removed**
|
||||
|
||||
* `printSelectionOnly`
|
||||
* `marginsType`
|
||||
* `headerFooter`
|
||||
* `scaleFactor`
|
||||
|
||||
**Arguments Added**
|
||||
|
||||
* `headerTemplate`
|
||||
* `footerTemplate`
|
||||
* `displayHeaderFooter`
|
||||
* `margins`
|
||||
* `scale`
|
||||
* `preferCSSPageSize`
|
||||
|
||||
```js
|
||||
// Main process
|
||||
const { webContents } = require('electron')
|
||||
|
||||
webContents.printToPDF({
|
||||
landscape: true,
|
||||
displayHeaderFooter: true,
|
||||
printBackground: true,
|
||||
scale: 2,
|
||||
pageSize: 'Ledger',
|
||||
margins: {
|
||||
top: 2,
|
||||
bottom: 2,
|
||||
left: 2,
|
||||
right: 2
|
||||
},
|
||||
pageRanges: '1-5, 8, 11-13',
|
||||
headerTemplate: '<h1>Title</h1>',
|
||||
footerTemplate: '<div><span class="pageNumber"></span></div>',
|
||||
preferCSSPageSize: true
|
||||
}).then(data => {
|
||||
fs.writeFile(pdfPath, data, (error) => {
|
||||
if (error) throw error
|
||||
console.log(`Wrote PDF successfully to ${pdfPath}`)
|
||||
})
|
||||
}).catch(error => {
|
||||
console.log(`Failed to write PDF to ${pdfPath}: `, error)
|
||||
})
|
||||
```
|
||||
|
||||
### Default Changed: renderers without `nodeIntegration: true` are sandboxed by default
|
||||
|
||||
Previously, renderers that specified a preload script defaulted to being
|
||||
@@ -34,9 +96,19 @@ window manager. There is not a direct equivalent for Wayland, and the known
|
||||
workarounds have unacceptable tradeoffs (e.g. Window.is_skip_taskbar in GNOME
|
||||
requires unsafe mode), so Electron is unable to support this feature on Linux.
|
||||
|
||||
### API Changed: `session.setDevicePermissionHandler(handler)`
|
||||
|
||||
The handler invoked when `session.setDevicePermissionHandler(handler)` is used
|
||||
has a change to its arguments. This handler no longer is passed a frame
|
||||
`[WebFrameMain](api/web-frame-main.md)`, but instead is passed the `origin`, which
|
||||
is the origin that is checking for device permission.
|
||||
|
||||
## Planned Breaking API Changes (19.0)
|
||||
|
||||
*None (yet)*
|
||||
### Removed: IA32 Linux binaries
|
||||
|
||||
This is a result of Chromium 102.0.4999.0 dropping support for IA32 Linux.
|
||||
This concludes the [removal of support for IA32 Linux](#removed-ia32-linux-support).
|
||||
|
||||
## Planned Breaking API Changes (18.0)
|
||||
|
||||
@@ -372,7 +444,7 @@ value.
|
||||
In Electron 12, `contextIsolation` will be enabled by default. To restore
|
||||
the previous behavior, `contextIsolation: false` must be specified in WebPreferences.
|
||||
|
||||
We [recommend having contextIsolation enabled](tutorial/security.md#3-enable-context-isolation-for-remote-content) for the security of your application.
|
||||
We [recommend having contextIsolation enabled](tutorial/security.md#3-enable-context-isolation) for the security of your application.
|
||||
|
||||
Another implication is that `require()` cannot be used in the renderer process unless
|
||||
`nodeIntegration` is `true` and `contextIsolation` is `false`.
|
||||
@@ -1203,6 +1275,10 @@ not present, then the native module will fail to load on Windows, with an error
|
||||
message like `Cannot find module`. See the [native module
|
||||
guide](/docs/tutorial/using-native-node-modules.md) for more.
|
||||
|
||||
### Removed: IA32 Linux support
|
||||
|
||||
Electron 18 will no longer run on 32-bit Linux systems. See [discontinuing support for 32-bit Linux](https://www.electronjs.org/blog/linux-32bit-support) for more information.
|
||||
|
||||
## Breaking API Changes (3.0)
|
||||
|
||||
The following list includes the breaking API changes in Electron 3.0.
|
||||
|
||||
@@ -64,7 +64,7 @@ If you want to add a new API module to Electron, you'll want to look in [creatin
|
||||
|
||||
Electron has a fully-fledged governance system that oversees activity in Electron and whose working groups are responsible for areas like APIs, releases, and upgrades to Electron's dependencies including Chromium and Node.js. Depending on how frequently and to what end you want to contribute, you may want to consider joining a working group.
|
||||
|
||||
Details about each group and their reponsibilities can be found in the [governance repo](https://github.com/electron/governance).
|
||||
Details about each group and their responsibilities can be found in the [governance repo](https://github.com/electron/governance).
|
||||
|
||||
## Patches in Electron
|
||||
|
||||
|
||||
@@ -196,12 +196,12 @@ If you test other combinations and find them to work, please update this documen
|
||||
See the GN reference for allowable values of [`target_os`][target_os values]
|
||||
and [`target_cpu`][target_cpu values].
|
||||
|
||||
[target_os values]: https://gn.googlesource.com/gn/+/master/docs/reference.md#built_in-predefined-variables-target_os_the-desired-operating-system-for-the-build-possible-values
|
||||
[target_cpu values]: https://gn.googlesource.com/gn/+/master/docs/reference.md#built_in-predefined-variables-target_cpu_the-desired-cpu-architecture-for-the-build-possible-values
|
||||
[target_os values]: https://gn.googlesource.com/gn/+/main/docs/reference.md#built_in-predefined-variables-target_os_the-desired-operating-system-for-the-build-possible-values
|
||||
[target_cpu values]: https://gn.googlesource.com/gn/+/main/docs/reference.md#built_in-predefined-variables-target_cpu_the-desired-cpu-architecture-for-the-build-possible-values
|
||||
|
||||
#### Windows on Arm (experimental)
|
||||
|
||||
To cross-compile for Windows on Arm, [follow Chromium's guide](https://chromium.googlesource.com/chromium/src/+/refs/heads/master/docs/windows_build_instructions.md#Visual-Studio) to get the necessary dependencies, SDK and libraries, then build with `ELECTRON_BUILDING_WOA=1` in your environment before running `gclient sync`.
|
||||
To cross-compile for Windows on Arm, [follow Chromium's guide](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/windows_build_instructions.md#Visual-Studio) to get the necessary dependencies, SDK and libraries, then build with `ELECTRON_BUILDING_WOA=1` in your environment before running `gclient sync`.
|
||||
|
||||
```bat
|
||||
set ELECTRON_BUILDING_WOA=1
|
||||
|
||||
@@ -47,10 +47,10 @@ $ sudo yum install clang dbus-devel gtk3-devel libnotify-devel \
|
||||
On Fedora, install the following libraries:
|
||||
|
||||
```sh
|
||||
$ sudo dnf install clang dbus-devel gtk3-devel libnotify-devel \
|
||||
libgnome-keyring-devel xorg-x11-server-utils libcap-devel \
|
||||
$ sudo dnf install clang dbus-devel gperf gtk3-devel \
|
||||
libnotify-devel libgnome-keyring-devel libcap-devel \
|
||||
cups-devel libXtst-devel alsa-lib-devel libXrandr-devel \
|
||||
nss-devel python-dbusmock openjdk-8-jre
|
||||
nss-devel python-dbusmock
|
||||
```
|
||||
|
||||
On Arch Linux / Manjaro, install the following libraries:
|
||||
@@ -82,7 +82,7 @@ $ sudo apt-get install libc6-dev-arm64-cross linux-libc-dev-arm64-cross \
|
||||
g++-aarch64-linux-gnu
|
||||
```
|
||||
|
||||
And to cross-compile for `arm` or `ia32` targets, you should pass the
|
||||
And to cross-compile for `arm` or targets, you should pass the
|
||||
`target_cpu` parameter to `gn gen`:
|
||||
|
||||
```sh
|
||||
|
||||
@@ -9,14 +9,12 @@ Follow the guidelines below for building **Electron itself** on Windows, for the
|
||||
* Windows 10 / Server 2012 R2 or higher
|
||||
* Visual Studio 2017 15.7.2 or higher - [download VS 2019 Community Edition for
|
||||
free](https://www.visualstudio.com/vs/)
|
||||
* See [the Chromium build documentation](https://chromium.googlesource.com/chromium/src/+/master/docs/windows_build_instructions.md#visual-studio) for more details on which Visual Studio
|
||||
* See [the Chromium build documentation](https://chromium.googlesource.com/chromium/src/+/main/docs/windows_build_instructions.md#visual-studio) for more details on which Visual Studio
|
||||
components are required.
|
||||
* If your Visual Studio is installed in a directory other than the default, you'll need to
|
||||
set a few environment variables to point the toolchains to your installation path.
|
||||
* `vs2019_install = DRIVE:\path\to\Microsoft Visual Studio\2019\Community`, replacing `2019` and `Community` with your installed versions and replacing `DRIVE:` with the drive that Visual Studio is on. Often, this will be `C:`.
|
||||
* `WINDOWSSDKDIR = DRIVE:\path\to\Windows Kits\10`, replacing `DRIVE:` with the drive that Windows Kits is on. Often, this will be `C:`.
|
||||
* [Python for Windows (pywin32) Extensions](https://pypi.org/project/pywin32/#files)
|
||||
is also needed in order to run the build process.
|
||||
* [Node.js](https://nodejs.org/download/)
|
||||
* [Git](https://git-scm.com)
|
||||
* Debugging Tools for Windows of Windows SDK 10.0.15063.468 if you plan on
|
||||
|
||||
@@ -9,7 +9,7 @@ Some of the more common approaches are outlined below.
|
||||
|
||||
Chromium contains logging macros which can aid debugging by printing information to console in C++ and Objective-C++.
|
||||
|
||||
You might use this to print out variable values, function names, and line numbers, amonst other things.
|
||||
You might use this to print out variable values, function names, and line numbers, amongst other things.
|
||||
|
||||
Some examples:
|
||||
|
||||
@@ -25,7 +25,7 @@ See [logging.h](https://chromium.googlesource.com/chromium/src/base/+/refs/heads
|
||||
|
||||
## Printing Stacktraces
|
||||
|
||||
Chromium contains a helper to print stack traces to console without interrrupting the program.
|
||||
Chromium contains a helper to print stack traces to console without interrupting the program.
|
||||
|
||||
```cpp
|
||||
#include "base/debug/stack_trace.h"
|
||||
|
||||
@@ -24,7 +24,7 @@ contribute:
|
||||
|
||||
## Asking for General Help
|
||||
|
||||
["Finding Support"](../tutorial/support.md#finding-support) has a
|
||||
[The Electron website](https://electronjs.org/community) has a
|
||||
list of resources for getting programming help, reporting security issues,
|
||||
contributing, and more. Please use the issue tracker for bugs only!
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<div>
|
||||
<h1>Asynchronous messages</h1>
|
||||
<i>Supports: Win, macOS, Linux <span>|</span> Process: Both</i>
|
||||
<div>
|
||||
<div>
|
||||
<button id="async-msg">Ping</button>
|
||||
<span id="async-reply"></span>
|
||||
</div>
|
||||
<p>Using <code>ipc</code> to send messages between processes asynchronously is the preferred method since it will return when finished without blocking other operations in the same process.</p>
|
||||
|
||||
<p>This example sends a "ping" from this process (renderer) to the main process. The main process then replies with "pong".</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// You can also require other files to run in this process
|
||||
require('./renderer.js')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,29 +0,0 @@
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
let mainWindow = null
|
||||
|
||||
function createWindow () {
|
||||
const windowOptions = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
title: 'Asynchronous messages',
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
}
|
||||
|
||||
mainWindow = new BrowserWindow(windowOptions)
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
|
||||
ipcMain.on('asynchronous-message', (event, arg) => {
|
||||
event.sender.send('asynchronous-reply', 'pong')
|
||||
})
|
||||
@@ -1,12 +0,0 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
const asyncMsgBtn = document.getElementById('async-msg')
|
||||
|
||||
asyncMsgBtn.addEventListener('click', () => {
|
||||
ipcRenderer.send('asynchronous-message', 'ping')
|
||||
})
|
||||
|
||||
ipcRenderer.on('asynchronous-reply', (event, arg) => {
|
||||
const message = `Asynchronous message reply: ${arg}`
|
||||
document.getElementById('async-reply').innerHTML = message
|
||||
})
|
||||
@@ -1,27 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<div>
|
||||
<h1>Synchronous messages</h1>
|
||||
<i>Supports: Win, macOS, Linux <span>|</span> Process: Both</i>
|
||||
<div>
|
||||
<div>
|
||||
<button id="sync-msg">Ping</button>
|
||||
<span id="sync-reply"></span>
|
||||
</div>
|
||||
<p>You can use the <code>ipc</code> module to send synchronous messages between processes as well, but note that the synchronous nature of this method means that it <b>will block</b> other operations while completing its task.</p>
|
||||
|
||||
<p>This example sends a synchronous message, "ping", from this process (renderer) to the main process. The main process then replies with "pong".</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// You can also require other files to run in this process
|
||||
require('./renderer.js')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,29 +0,0 @@
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
let mainWindow = null
|
||||
|
||||
function createWindow () {
|
||||
const windowOptions = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
title: 'Synchronous Messages',
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
}
|
||||
|
||||
mainWindow = new BrowserWindow(windowOptions)
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
|
||||
ipcMain.on('synchronous-message', (event, arg) => {
|
||||
event.returnValue = 'pong'
|
||||
})
|
||||
@@ -1,9 +0,0 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
const syncMsgBtn = document.getElementById('sync-msg')
|
||||
|
||||
syncMsgBtn.addEventListener('click', () => {
|
||||
const reply = ipcRenderer.sendSync('synchronous-message', 'ping')
|
||||
const message = `Synchronous message reply: ${reply}`
|
||||
document.getElementById('sync-reply').innerHTML = message
|
||||
})
|
||||
@@ -8,20 +8,24 @@ function createWindow () {
|
||||
})
|
||||
|
||||
mainWindow.webContents.session.on('select-hid-device', (event, details, callback) => {
|
||||
//Add events to handle devices being added or removed before the callback on
|
||||
//`select-hid-device` is called.
|
||||
mainWindow.webContents.session.on('hid-device-added', (event, device) => {
|
||||
console.log('hid-device-added FIRED WITH', device)
|
||||
//Optionally update details.deviceList
|
||||
})
|
||||
|
||||
mainWindow.webContents.session.on('hid-device-removed', (event, device) => {
|
||||
console.log('hid-device-removed FIRED WITH', device)
|
||||
//Optionally update details.deviceList
|
||||
})
|
||||
|
||||
event.preventDefault()
|
||||
if (details.deviceList && details.deviceList.length > 0) {
|
||||
callback(details.deviceList[0].deviceId)
|
||||
}
|
||||
})
|
||||
|
||||
mainWindow.webContents.session.on('hid-device-added', (event, device) => {
|
||||
console.log('hid-device-added FIRED WITH', device)
|
||||
})
|
||||
|
||||
mainWindow.webContents.session.on('hid-device-removed', (event, device) => {
|
||||
console.log('hid-device-removed FIRED WITH', device)
|
||||
})
|
||||
|
||||
mainWindow.webContents.session.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => {
|
||||
if (permission === 'hid' && details.securityOrigin === 'file:///') {
|
||||
return true
|
||||
|
||||
@@ -8,6 +8,19 @@ function createWindow () {
|
||||
})
|
||||
|
||||
mainWindow.webContents.session.on('select-serial-port', (event, portList, webContents, callback) => {
|
||||
|
||||
//Add listeners to handle ports being added or removed before the callback for `select-serial-port`
|
||||
//is called.
|
||||
mainWindow.webContents.session.on('serial-port-added', (event, port) => {
|
||||
console.log('serial-port-added FIRED WITH', port)
|
||||
//Optionally update portList to add the new port
|
||||
})
|
||||
|
||||
mainWindow.webContents.session.on('serial-port-removed', (event, port) => {
|
||||
console.log('serial-port-removed FIRED WITH', port)
|
||||
//Optionally update portList to remove the port
|
||||
})
|
||||
|
||||
event.preventDefault()
|
||||
if (portList && portList.length > 0) {
|
||||
callback(portList[0].portId)
|
||||
@@ -16,14 +29,6 @@ function createWindow () {
|
||||
}
|
||||
})
|
||||
|
||||
mainWindow.webContents.session.on('serial-port-added', (event, port) => {
|
||||
console.log('serial-port-added FIRED WITH', port)
|
||||
})
|
||||
|
||||
mainWindow.webContents.session.on('serial-port-removed', (event, port) => {
|
||||
console.log('serial-port-removed FIRED WITH', port)
|
||||
})
|
||||
|
||||
mainWindow.webContents.session.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => {
|
||||
if (permission === 'serial' && details.securityOrigin === 'file:///') {
|
||||
return true
|
||||
|
||||
21
docs/fiddles/tutorial-first-app/index.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="default-src 'self'; script-src 'self'"
|
||||
/>
|
||||
<meta
|
||||
http-equiv="X-Content-Security-Policy"
|
||||
content="default-src 'self'; script-src 'self'"
|
||||
/>
|
||||
<title>Hello from Electron renderer!</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello from Electron renderer!</h1>
|
||||
<p>👋</p>
|
||||
<p id="info"></p>
|
||||
</body>
|
||||
<script src="./renderer.js"></script>
|
||||
</html>
|
||||
26
docs/fiddles/tutorial-first-app/main.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const { app, BrowserWindow } = require('electron');
|
||||
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
});
|
||||
|
||||
win.loadFile('index.html');
|
||||
};
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow();
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
21
docs/fiddles/tutorial-preload/index.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="default-src 'self'; script-src 'self'"
|
||||
/>
|
||||
<meta
|
||||
http-equiv="X-Content-Security-Policy"
|
||||
content="default-src 'self'; script-src 'self'"
|
||||
/>
|
||||
<title>Hello from Electron renderer!</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello from Electron renderer!</h1>
|
||||
<p>👋</p>
|
||||
<p id="info"></p>
|
||||
</body>
|
||||
<script src="./renderer.js"></script>
|
||||
</html>
|
||||
30
docs/fiddles/tutorial-preload/main.js
Normal file
@@ -0,0 +1,30 @@
|
||||
const { app, BrowserWindow } = require('electron');
|
||||
const path = require('path');
|
||||
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js'),
|
||||
},
|
||||
});
|
||||
|
||||
win.loadFile('index.html');
|
||||
};
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow();
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
7
docs/fiddles/tutorial-preload/preload.js
Normal file
@@ -0,0 +1,7 @@
|
||||
const { contextBridge } = require('electron');
|
||||
|
||||
contextBridge.exposeInMainWorld('versions', {
|
||||
node: () => process.versions.node,
|
||||
chrome: () => process.versions.chrome,
|
||||
electron: () => process.versions.electron,
|
||||
});
|
||||
2
docs/fiddles/tutorial-preload/renderer.js
Normal file
@@ -0,0 +1,2 @@
|
||||
const information = document.getElementById('info');
|
||||
information.innerText = `This app is using Chrome (v${versions.chrome()}), Node.js (v${versions.node()}), and Electron (v${versions.electron()})`;
|
||||
@@ -91,7 +91,7 @@ An IPC system for communicating intra- or inter-process, and that's important
|
||||
because Chrome is keen on being able to split its work into separate processes
|
||||
or not, depending on memory pressures etc.
|
||||
|
||||
See https://chromium.googlesource.com/chromium/src/+/master/mojo/README.md
|
||||
See https://chromium.googlesource.com/chromium/src/+/main/mojo/README.md
|
||||
|
||||
See also: [IPC](#ipc)
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 190 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 44 KiB |
BIN
docs/images/preload-example.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
@@ -1,97 +0,0 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<svg width="520" height="220" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<marker id="arrow" viewBox="-1 0 12 10" refX="10.5" refY="5" markerWidth="8" markerHeight="8" orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10"/>
|
||||
</marker>
|
||||
<g transform="translate(0,40)">
|
||||
<!-- master -->
|
||||
<text x="60" y="30" text-anchor="end" alignment-baseline="middle">master</text>
|
||||
<path d="M70 30 H 500" stroke-width="2" stroke="black"/>
|
||||
<!-- v2.0 -->
|
||||
<g>
|
||||
<path d="M100 30 l 20 30 H 200" stroke-width="2" stroke="black" fill="transparent"/>
|
||||
<text x="110" y="60" text-anchor="end" alignment-baseline="middle">2.0</text>
|
||||
<circle cx="120" cy="60" r="5"/>
|
||||
<text x="110" y="60" text-anchor="end" alignment-baseline="middle" transform="rotate(-60 120,60)">v2.0.0-beta0</text>
|
||||
<circle cx="200" cy="60" r="5"/>
|
||||
<text x="190" y="60" text-anchor="end" alignment-baseline="middle" transform="rotate(-60 200,60)">v2.0.0</text>
|
||||
</g>
|
||||
<!-- v2.1 -->
|
||||
<g transform="translate(130,0)">
|
||||
<path d="M100 30 l 20 30 H 200" stroke-width="2" stroke="black" fill="transparent"/>
|
||||
<text x="110" y="60" text-anchor="end" alignment-baseline="middle">2.1</text>
|
||||
<circle cx="120" cy="60" r="5"/>
|
||||
<text x="110" y="60" text-anchor="end" alignment-baseline="middle" transform="rotate(-60 120,60)">v2.1.0-beta0</text>
|
||||
<circle cx="160" cy="60" r="5"/>
|
||||
<text x="150" y="60" text-anchor="end" alignment-baseline="middle" transform="rotate(-60 160,60)">v2.1.0-beta1</text>
|
||||
<circle cx="200" cy="60" r="5"/>
|
||||
<text x="190" y="60" text-anchor="end" alignment-baseline="middle" transform="rotate(-60 200,60)">v2.1.0</text>
|
||||
</g>
|
||||
<!-- v3.0 -->
|
||||
<g transform="translate(260,0)">
|
||||
<path d="M100 30 l 20 30 H 200" stroke-width="2" stroke="black" fill="transparent"/>
|
||||
<text x="110" y="60" text-anchor="end" alignment-baseline="middle">3.0</text>
|
||||
<circle cx="120" cy="60" r="5"/>
|
||||
<text x="110" y="60" text-anchor="end" alignment-baseline="middle" transform="rotate(-60 120,60)">v3.0.0-beta0</text>
|
||||
<circle cx="200" cy="60" r="5"/>
|
||||
<text x="190" y="60" text-anchor="end" alignment-baseline="middle" transform="rotate(-60 200,60)">v3.0.0</text>
|
||||
</g>
|
||||
<!-- Bug fixes -->
|
||||
<g transform="translate(160,30)">
|
||||
<circle cx="0" cy="0" r="3"/>
|
||||
<text x="10" y="0" text-anchor="start" alignment-baseline="middle" transform="rotate(-60 0,0)">bug fix</text>
|
||||
<path d="M0 0 l0,30" marker-end="url(#arrow)" stroke-dasharray="2,2" stroke="#000"/>
|
||||
</g>
|
||||
<g transform="translate(260,30)">
|
||||
<circle cx="0" cy="0" r="3"/>
|
||||
<text x="10" y="0" text-anchor="start" alignment-baseline="middle" transform="rotate(-60 0,0)">bug fix</text>
|
||||
<path d="M0 0 l0,30" marker-end="url(#arrow)" stroke-dasharray="2,2" stroke="#000"/>
|
||||
</g>
|
||||
<g transform="translate(280,30)">
|
||||
<circle cx="0" cy="0" r="3"/>
|
||||
<text x="10" y="0" text-anchor="start" alignment-baseline="middle" transform="rotate(-60 0,0)">bug fix</text>
|
||||
<path d="M0 0 l0,30" marker-end="url(#arrow)" stroke-dasharray="2,2" stroke="#000"/>
|
||||
</g>
|
||||
<g transform="translate(400,30)">
|
||||
<circle cx="0" cy="0" r="3"/>
|
||||
<text x="10" y="0" text-anchor="start" alignment-baseline="middle" transform="rotate(-60 0,0)">bug fix</text>
|
||||
<path d="M0 0 l0,30" marker-end="url(#arrow)" stroke-dasharray="2,2" stroke="#000"/>
|
||||
</g>
|
||||
<g transform="translate(430,30)">
|
||||
<circle cx="0" cy="0" r="3"/>
|
||||
<text x="10" y="0" text-anchor="start" alignment-baseline="middle" transform="rotate(-60 0,0)">bug fix</text>
|
||||
<path d="M0 0 l0,30" marker-end="url(#arrow)" stroke-dasharray="2,2" stroke="#000"/>
|
||||
</g>
|
||||
<!-- Features -->
|
||||
<g transform="translate(130,30)">
|
||||
<circle cx="0" cy="0" r="3"/>
|
||||
<text x="10" y="0" text-anchor="start" alignment-baseline="middle" transform="rotate(-60 0,0)">feature</text>
|
||||
</g>
|
||||
<g transform="translate(200,30)">
|
||||
<circle cx="0" cy="0" r="3"/>
|
||||
<text x="10" y="0" text-anchor="start" alignment-baseline="middle" transform="rotate(-60 0,0)">feature</text>
|
||||
</g>
|
||||
<g transform="translate(340,30)">
|
||||
<circle cx="0" cy="0" r="3"/>
|
||||
<text x="10" y="0" text-anchor="start" alignment-baseline="middle" transform="rotate(-60 0,0)">feature</text>
|
||||
</g>
|
||||
<!-- Chromium update -->
|
||||
<g transform="translate(310,30)">
|
||||
<circle cx="0" cy="0" r="3"/>
|
||||
<text x="10" y="0" text-anchor="start" alignment-baseline="middle" transform="rotate(-60 0,0)"><tspan>chromium</tspan><tspan dy="10" x="10">update</tspan></text>
|
||||
</g>
|
||||
<!-- Timeline -->
|
||||
<g transform="translate(100,160)">
|
||||
<text x="50" y="0" text-anchor="middle" alignment-baseline="text-after-edge">~1 week</text>
|
||||
<path d="M0 0 l0 10 l0 -5 H100l0 -5l0 10" stroke-width="2" stroke="black" fill="transparent"/>
|
||||
</g>
|
||||
<g transform="translate(230,160)">
|
||||
<text x="50" y="0" text-anchor="middle" alignment-baseline="text-after-edge">~1 week</text>
|
||||
<path d="M0 0 l0 10 l0 -5 H100l0 -5l0 10" stroke-width="2" stroke="black" fill="transparent"/>
|
||||
</g>
|
||||
<g transform="translate(360,160)">
|
||||
<text x="50" y="0" text-anchor="middle" alignment-baseline="text-after-edge">~1 week</text>
|
||||
<path d="M0 0 l0 10 l0 -5 H100l0 -5l0 10" stroke-width="2" stroke="black" fill="transparent"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.3 KiB |
BIN
docs/images/windows-taskbar-icon-overlay.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
docs/images/windows-taskbar-jumplist.png
Normal file
|
After Width: | Height: | Size: 173 KiB |
BIN
docs/images/windows-taskbar-thumbnail-toolbar.png
Normal file
|
After Width: | Height: | Size: 142 KiB |
@@ -1,26 +1,26 @@
|
||||
# Application Distribution
|
||||
---
|
||||
title: 'Application Packaging'
|
||||
description: 'To distribute your app with Electron, you need to package and rebrand it. To do this, you can either use specialized tooling or manual approaches.'
|
||||
slug: application-distribution
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
To distribute your app with Electron, you need to package and rebrand it.
|
||||
To do this, you can either use specialized tooling or manual approaches.
|
||||
To distribute your app with Electron, you need to package and rebrand it. To do this, you
|
||||
can either use specialized tooling or manual approaches.
|
||||
|
||||
## With tooling
|
||||
|
||||
You can use the following tools to distribute your application:
|
||||
There are a couple tools out there that exist to package and distribute your Electron app.
|
||||
We recommend using [Electron Forge](https://www.electronforge.io). You can check out
|
||||
its documentation directly, or refer to the [Packaging and Distribution](./tutorial-5-packaging.md)
|
||||
part of the Electron tutorial.
|
||||
|
||||
* [electron-forge](https://github.com/electron-userland/electron-forge)
|
||||
* [electron-builder](https://github.com/electron-userland/electron-builder)
|
||||
* [electron-packager](https://github.com/electron/electron-packager)
|
||||
## Manual packaging
|
||||
|
||||
These tools will take care of all the steps you need to take to end up with a
|
||||
distributable Electron application, such as bundling your application,
|
||||
rebranding the executable, and setting the right icons.
|
||||
If you prefer the manual approach, there are 2 ways to distribute your application:
|
||||
|
||||
You can check the example of how to package your app with `electron-forge` in
|
||||
the [Quick Start guide](quick-start.md#package-and-distribute-your-application).
|
||||
|
||||
## Manual distribution
|
||||
- With prebuilt binaries
|
||||
- With an app source code archive
|
||||
|
||||
### With prebuilt binaries
|
||||
|
||||
@@ -29,21 +29,19 @@ binaries](https://github.com/electron/electron/releases). Next, the folder
|
||||
containing your app should be named `app` and placed in Electron's resources
|
||||
directory as shown in the following examples.
|
||||
|
||||
> *NOTE:* the location of Electron's prebuilt binaries is indicated
|
||||
:::note
|
||||
The location of Electron's prebuilt binaries is indicated
|
||||
with `electron/` in the examples below.
|
||||
:::
|
||||
|
||||
*On macOS:*
|
||||
|
||||
```plaintext
|
||||
```plain title='macOS'
|
||||
electron/Electron.app/Contents/Resources/app/
|
||||
├── package.json
|
||||
├── main.js
|
||||
└── index.html
|
||||
```
|
||||
|
||||
*On Windows and Linux:*
|
||||
|
||||
```plaintext
|
||||
```plain title='Windows and Linux'
|
||||
electron/resources/app
|
||||
├── package.json
|
||||
├── main.js
|
||||
@@ -54,7 +52,7 @@ Then execute `Electron.app` on macOS, `electron` on Linux, or `electron.exe`
|
||||
on Windows, and Electron will start as your app. The `electron` directory
|
||||
will then be your distribution to deliver to users.
|
||||
|
||||
### With an app source code archive
|
||||
### With an app source code archive (asar)
|
||||
|
||||
Instead of shipping your app by copying all of its source files, you can
|
||||
package your app into an [asar] archive to improve the performance of reading
|
||||
@@ -65,16 +63,12 @@ To use an `asar` archive to replace the `app` folder, you need to rename the
|
||||
archive to `app.asar`, and put it under Electron's resources directory like
|
||||
below, and Electron will then try to read the archive and start from it.
|
||||
|
||||
*On macOS:*
|
||||
|
||||
```plaintext
|
||||
```plain title='macOS'
|
||||
electron/Electron.app/Contents/Resources/
|
||||
└── app.asar
|
||||
```
|
||||
|
||||
*On Windows and Linux:*
|
||||
|
||||
```plaintext
|
||||
```plain title='Windows'
|
||||
electron/resources/
|
||||
└── app.asar
|
||||
```
|
||||
@@ -87,47 +81,44 @@ You can find more details on how to use `asar` in the
|
||||
After bundling your app into Electron, you will want to rebrand Electron
|
||||
before distributing it to users.
|
||||
|
||||
#### macOS
|
||||
- **Windows:** You can rename `electron.exe` to any name you like, and edit
|
||||
its icon and other information with tools like [rcedit](https://github.com/electron/rcedit).
|
||||
- **Linux:** You can rename the `electron` executable to any name you like.
|
||||
- **macOS:** You can rename `Electron.app` to any name you want, and you also have to rename
|
||||
the `CFBundleDisplayName`, `CFBundleIdentifier` and `CFBundleName` fields in the
|
||||
following files:
|
||||
|
||||
You can rename `Electron.app` to any name you want, and you also have to rename
|
||||
the `CFBundleDisplayName`, `CFBundleIdentifier` and `CFBundleName` fields in the
|
||||
following files:
|
||||
- `Electron.app/Contents/Info.plist`
|
||||
- `Electron.app/Contents/Frameworks/Electron Helper.app/Contents/Info.plist`
|
||||
|
||||
* `Electron.app/Contents/Info.plist`
|
||||
* `Electron.app/Contents/Frameworks/Electron Helper.app/Contents/Info.plist`
|
||||
You can also rename the helper app to avoid showing `Electron Helper` in the
|
||||
Activity Monitor, but make sure you have renamed the helper app's executable
|
||||
file's name.
|
||||
|
||||
You can also rename the helper app to avoid showing `Electron Helper` in the
|
||||
Activity Monitor, but make sure you have renamed the helper app's executable
|
||||
file's name.
|
||||
The structure of a renamed app would be like:
|
||||
|
||||
The structure of a renamed app would be like:
|
||||
|
||||
```plaintext
|
||||
```plain
|
||||
MyApp.app/Contents
|
||||
├── Info.plist
|
||||
├── MacOS/
|
||||
│ └── MyApp
|
||||
│ └── MyApp
|
||||
└── Frameworks/
|
||||
└── MyApp Helper.app
|
||||
├── Info.plist
|
||||
└── MacOS/
|
||||
└── MyApp Helper
|
||||
└── MyApp Helper
|
||||
```
|
||||
|
||||
#### Windows
|
||||
:::note
|
||||
|
||||
You can rename `electron.exe` to any name you like, and edit its icon and other
|
||||
information with tools like [rcedit](https://github.com/electron/rcedit).
|
||||
|
||||
#### Linux
|
||||
|
||||
You can rename the `electron` executable to any name you like.
|
||||
|
||||
### Rebranding by rebuilding Electron from source
|
||||
|
||||
It is also possible to rebrand Electron by changing the product name and
|
||||
it is also possible to rebrand Electron by changing the product name and
|
||||
building it from source. To do this you need to set the build argument
|
||||
corresponding to the product name (`electron_product_name = "YourProductName"`)
|
||||
in the `args.gn` file and rebuild.
|
||||
|
||||
Keep in mind this is not recommended as setting up the environment to compile
|
||||
from source is not trivial and takes significant time.
|
||||
|
||||
:::
|
||||
|
||||
[asar]: https://github.com/electron/asar
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
# Code Signing
|
||||
---
|
||||
title: 'Code Signing'
|
||||
description: 'Code signing is a security technology that you use to certify that an app was created by you.'
|
||||
slug: code-signing
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
Code signing is a security technology that you use to certify that an app was
|
||||
created by you.
|
||||
created by you. You should sign your application so it does not trigger any
|
||||
operating system security checks.
|
||||
|
||||
On macOS the system can detect any change to the app, whether the change is
|
||||
On macOS, the system can detect any change to the app, whether the change is
|
||||
introduced accidentally or by malicious code.
|
||||
|
||||
On Windows, the system assigns a trust level to your code signing certificate
|
||||
which if you don't have, or if your trust level is low, will cause security
|
||||
dialogs to appear when users start using your application. Trust level builds
|
||||
dialogs to appear when users start using your application. Trust level builds
|
||||
over time so it's better to start code signing as early as possible.
|
||||
|
||||
While it is possible to distribute unsigned apps, it is not recommended. Both
|
||||
@@ -16,20 +22,19 @@ Windows and macOS will, by default, prevent either the download or the execution
|
||||
of unsigned applications. Starting with macOS Catalina (version 10.15), users
|
||||
have to go through multiple manual steps to open unsigned applications.
|
||||
|
||||

|
||||

|
||||
|
||||
As you can see, users get two options: Move the app straight to the trash or
|
||||
cancel running it. You don't want your users to see that dialog.
|
||||
|
||||
If you are building an Electron app that you intend to package and distribute,
|
||||
it should be code-signed.
|
||||
it should be code signed.
|
||||
|
||||
# Signing & notarizing macOS builds
|
||||
## Signing & notarizing macOS builds
|
||||
|
||||
Properly preparing macOS applications for release requires two steps: First, the
|
||||
app needs to be code-signed. Then, the app needs to be uploaded to Apple for a
|
||||
process called "notarization", where automated systems will further verify that
|
||||
Properly preparing macOS applications for release requires two steps. First, the
|
||||
app needs to be code signed. Then, the app needs to be uploaded to Apple for a
|
||||
process called **notarization**, where automated systems will further verify that
|
||||
your app isn't doing anything to endanger its users.
|
||||
|
||||
To start the process, ensure that you fulfill the requirements for signing and
|
||||
@@ -42,18 +47,18 @@ notarizing your app:
|
||||
Electron's ecosystem favors configuration and freedom, so there are multiple
|
||||
ways to get your application signed and notarized.
|
||||
|
||||
## `electron-forge`
|
||||
### Using Electron Forge
|
||||
|
||||
If you're using Electron's favorite build tool, getting your application signed
|
||||
and notarized requires a few additions to your configuration. [Forge](https://electronforge.io) is a
|
||||
collection of the official Electron tools, using [`electron-packager`],
|
||||
[`electron-osx-sign`], and [`electron-notarize`] under the hood.
|
||||
|
||||
Let's take a look at an example configuration with all required fields. Not all
|
||||
of them are required: the tools will be clever enough to automatically find a
|
||||
suitable `identity`, for instance, but we recommend that you are explicit.
|
||||
Let's take a look at an example `package.json` configuration with all required fields. Not all of them are
|
||||
required: the tools will be clever enough to automatically find a suitable `identity`, for instance,
|
||||
but we recommend that you are explicit.
|
||||
|
||||
```json
|
||||
```json title="package.json" {7}
|
||||
{
|
||||
"name": "my-app",
|
||||
"version": "0.0.1",
|
||||
@@ -69,7 +74,7 @@ suitable `identity`, for instance, but we recommend that you are explicit.
|
||||
},
|
||||
"osxNotarize": {
|
||||
"appleId": "felix@felix.fun",
|
||||
"appleIdPassword": "my-apple-id-password",
|
||||
"appleIdPassword": "my-apple-id-password"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,11 +82,11 @@ suitable `identity`, for instance, but we recommend that you are explicit.
|
||||
}
|
||||
```
|
||||
|
||||
The `plist` file referenced here needs the following macOS-specific entitlements
|
||||
The `entitlements.plist` file referenced here needs the following macOS-specific entitlements
|
||||
to assure the Apple security mechanisms that your app is doing these things
|
||||
without meaning any harm:
|
||||
|
||||
```xml
|
||||
```xml title="entitlements.plist"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
@@ -104,7 +109,7 @@ file](https://github.com/electron/fiddle/blob/master/forge.config.js).
|
||||
If you plan to access the microphone or camera within your app using Electron's APIs, you'll also
|
||||
need to add the following entitlements:
|
||||
|
||||
```xml
|
||||
```xml title="entitlements.plist"
|
||||
<key>com.apple.security.device.audio-input</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.camera</key>
|
||||
@@ -113,28 +118,26 @@ need to add the following entitlements:
|
||||
|
||||
If these are not present in your app's entitlements when you invoke, for example:
|
||||
|
||||
```js
|
||||
```js title="main.js"
|
||||
const { systemPreferences } = require('electron')
|
||||
|
||||
const microphone = systemPreferences.askForMediaAccess('microphone')
|
||||
```
|
||||
|
||||
Your app may crash. See the Resource Access section in [Hardened Runtime](https://developer.apple.com/documentation/security/hardened_runtime) for more information and entitlements you may need.
|
||||
|
||||
## `electron-builder`
|
||||
### Using Electron Builder
|
||||
|
||||
Electron Builder comes with a custom solution for signing your application. You
|
||||
can find [its documentation here](https://www.electron.build/code-signing).
|
||||
|
||||
## `electron-packager`
|
||||
### Using Electron Packager
|
||||
|
||||
If you're not using an integrated build pipeline like Forge or Builder, you
|
||||
are likely using [`electron-packager`], which includes [`electron-osx-sign`] and
|
||||
[`electron-notarize`].
|
||||
|
||||
If you're using Packager's API, you can pass [in configuration that both signs
|
||||
and notarizes your
|
||||
application](https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html).
|
||||
and notarizes your application](https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html).
|
||||
|
||||
```js
|
||||
const packager = require('electron-packager')
|
||||
@@ -155,11 +158,11 @@ packager({
|
||||
})
|
||||
```
|
||||
|
||||
The `plist` file referenced here needs the following macOS-specific entitlements
|
||||
The `entitlements.plist` file referenced here needs the following macOS-specific entitlements
|
||||
to assure the Apple security mechanisms that your app is doing these things
|
||||
without meaning any harm:
|
||||
|
||||
```xml
|
||||
```xml title="entitlements.plist"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
@@ -175,11 +178,11 @@ without meaning any harm:
|
||||
Up until Electron 12, the `com.apple.security.cs.allow-unsigned-executable-memory` entitlement was required
|
||||
as well. However, it should not be used anymore if it can be avoided.
|
||||
|
||||
## Mac App Store
|
||||
### Signing Mac App Store applications
|
||||
|
||||
See the [Mac App Store Guide].
|
||||
|
||||
# Signing Windows builds
|
||||
## Signing Windows builds
|
||||
|
||||
Before signing Windows builds, you must do the following:
|
||||
|
||||
@@ -190,31 +193,140 @@ Before signing Windows builds, you must do the following:
|
||||
You can get a code signing certificate from a lot of resellers. Prices vary, so
|
||||
it may be worth your time to shop around. Popular resellers include:
|
||||
|
||||
* [digicert](https://www.digicert.com/code-signing/microsoft-authenticode.htm)
|
||||
* [Sectigo](https://sectigo.com/ssl-certificates-tls/code-signing)
|
||||
* Amongst others, please shop around to find one that suits your needs, Google
|
||||
is your friend 😄
|
||||
- [digicert](https://www.digicert.com/code-signing/microsoft-authenticode.htm)
|
||||
- [Sectigo](https://sectigo.com/ssl-certificates-tls/code-signing)
|
||||
- Amongst others, please shop around to find one that suits your needs! 😄
|
||||
|
||||
There are a number of tools for signing your packaged app:
|
||||
:::caution Keep your certificate password private
|
||||
Your certificate password should be a **secret**. Do not share it publicly or
|
||||
commit it to your source code.
|
||||
:::
|
||||
|
||||
* [`electron-winstaller`] will generate an installer for windows and sign it for
|
||||
you
|
||||
* [`electron-forge`] can sign installers it generates through the
|
||||
Squirrel.Windows or MSI targets.
|
||||
* [`electron-builder`] can sign some of its windows targets
|
||||
### Using Electron Forge
|
||||
|
||||
## Windows Store
|
||||
Once you have a code signing certificate file (`.pfx`), you can sign
|
||||
[Squirrel.Windows][maker-squirrel] and [MSI][maker-msi] installers in Electron Forge
|
||||
with the `certificateFile` and `certificatePassword` fields in their respective
|
||||
configuration objects.
|
||||
|
||||
For example, if you keep your Forge config in your `package.json` file and are
|
||||
creating a Squirrel.Windows installer:
|
||||
|
||||
```json {9-15} title='package.json'
|
||||
{
|
||||
"name": "my-app",
|
||||
"version": "0.0.1",
|
||||
//...
|
||||
"config": {
|
||||
"forge": {
|
||||
"packagerConfig": {},
|
||||
"makers": [
|
||||
{
|
||||
"name": "@electron-forge/maker-squirrel",
|
||||
"config": {
|
||||
"certificateFile": "./cert.pfx",
|
||||
"certificatePassword": "this-is-a-secret"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
### Using electron-winstaller (Squirrel.Windows)
|
||||
|
||||
[`electron-winstaller`] is a package that can generate Squirrel.Windows installers for your
|
||||
Electron app. This is the tool used under the hood by Electron Forge's
|
||||
[Squirrel.Windows Maker][maker-squirrel]. If you're not using Electron Forge and want to use
|
||||
`electron-winstaller` directly, use the `certificateFile` and `certificatePassword` configuration
|
||||
options when creating your installer.
|
||||
|
||||
```js {10-11}
|
||||
const electronInstaller = require('electron-winstaller')
|
||||
// NB: Use this syntax within an async function, Node does not have support for
|
||||
// top-level await as of Node 12.
|
||||
try {
|
||||
await electronInstaller.createWindowsInstaller({
|
||||
appDirectory: '/tmp/build/my-app-64',
|
||||
outputDirectory: '/tmp/build/installer64',
|
||||
authors: 'My App Inc.',
|
||||
exe: 'myapp.exe',
|
||||
certificateFile: './cert.pfx',
|
||||
certificatePassword: 'this-is-a-secret',
|
||||
})
|
||||
console.log('It worked!')
|
||||
} catch (e) {
|
||||
console.log(`No dice: ${e.message}`)
|
||||
}
|
||||
```
|
||||
|
||||
For full configuration options, check out the [`electron-winstaller`] repository!
|
||||
|
||||
### Using electron-wix-msi (WiX MSI)
|
||||
|
||||
[`electron-wix-msi`] is a package that can generate MSI installers for your
|
||||
Electron app. This is the tool used under the hood by Electron Forge's [MSI Maker][maker-msi].
|
||||
|
||||
If you're not using Electron Forge and want to use `electron-wix-msi` directly, use the
|
||||
`certificateFile` and `certificatePassword` configuration options
|
||||
or pass in parameters directly to [SignTool.exe] with the `signWithParams` option.
|
||||
|
||||
```js {12-13}
|
||||
import { MSICreator } from 'electron-wix-msi'
|
||||
|
||||
// Step 1: Instantiate the MSICreator
|
||||
const msiCreator = new MSICreator({
|
||||
appDirectory: '/path/to/built/app',
|
||||
description: 'My amazing Kitten simulator',
|
||||
exe: 'kittens',
|
||||
name: 'Kittens',
|
||||
manufacturer: 'Kitten Technologies',
|
||||
version: '1.1.2',
|
||||
outputDirectory: '/path/to/output/folder',
|
||||
certificateFile: './cert.pfx',
|
||||
certificatePassword: 'this-is-a-secret',
|
||||
})
|
||||
|
||||
// Step 2: Create a .wxs template file
|
||||
const supportBinaries = await msiCreator.create()
|
||||
|
||||
// 🆕 Step 2a: optionally sign support binaries if you
|
||||
// sign you binaries as part of of your packaging script
|
||||
supportBinaries.forEach(async (binary) => {
|
||||
// Binaries are the new stub executable and optionally
|
||||
// the Squirrel auto updater.
|
||||
await signFile(binary)
|
||||
})
|
||||
|
||||
// Step 3: Compile the template to a .msi file
|
||||
await msiCreator.compile()
|
||||
```
|
||||
|
||||
For full configuration options, check out the [`electron-wix-msi`] repository!
|
||||
|
||||
### Using Electron Builder
|
||||
|
||||
Electron Builder comes with a custom solution for signing your application. You
|
||||
can find [its documentation here](https://www.electron.build/code-signing).
|
||||
|
||||
### Signing Windows Store applications
|
||||
|
||||
See the [Windows Store Guide].
|
||||
|
||||
[Apple Developer Program]: https://developer.apple.com/programs/
|
||||
[apple developer program]: https://developer.apple.com/programs/
|
||||
[`electron-builder`]: https://github.com/electron-userland/electron-builder
|
||||
[`electron-forge`]: https://github.com/electron-userland/electron-forge
|
||||
[`electron-osx-sign`]: https://github.com/electron-userland/electron-osx-sign
|
||||
[`electron-packager`]: https://github.com/electron/electron-packager
|
||||
[`electron-notarize`]: https://github.com/electron/electron-notarize
|
||||
[`electron-winstaller`]: https://github.com/electron/windows-installer
|
||||
[Xcode]: https://developer.apple.com/xcode
|
||||
[`electron-wix-msi`]: https://github.com/felixrieseberg/electron-wix-msi
|
||||
[xcode]: https://developer.apple.com/xcode
|
||||
[signing certificates]: https://github.com/electron/electron-osx-sign/wiki/1.-Getting-Started#certificates
|
||||
[Mac App Store Guide]: mac-app-store-submission-guide.md
|
||||
[Windows Store Guide]: windows-store-guide.md
|
||||
[mac app store guide]: ./mac-app-store-submission-guide.md
|
||||
[windows store guide]: ./windows-store-guide.md
|
||||
[maker-squirrel]: https://www.electronforge.io/config/makers/squirrel.windows
|
||||
[maker-msi]: https://www.electronforge.io/config/makers/wix-msi
|
||||
[signtool.exe]: https://docs.microsoft.com/en-us/dotnet/framework/tools/signtool-exe
|
||||
|
||||
@@ -36,12 +36,14 @@ the WebHID API:
|
||||
can be used to select a HID device when a call to
|
||||
`navigator.hid.requestDevice` is made. Additionally the [`hid-device-added`](../api/session.md#event-hid-device-added)
|
||||
and [`hid-device-removed`](../api/session.md#event-hid-device-removed) events
|
||||
on the Session can be used to handle devices being plugged in or unplugged during the
|
||||
`navigator.hid.requestDevice` process.
|
||||
on the Session can be used to handle devices being plugged in or unplugged
|
||||
when handling the `select-hid-device` event.
|
||||
**Note:** These events only fire until the callback from `select-hid-device`
|
||||
is called. They are not intended to be used as a generic hid device listener.
|
||||
* [`ses.setDevicePermissionHandler(handler)`](../api/session.md#sessetdevicepermissionhandlerhandler)
|
||||
can be used to provide default permissioning to devices without first calling
|
||||
for permission to devices via `navigator.hid.requestDevice`. Additionally,
|
||||
the default behavior of Electron is to store granted device permision through
|
||||
the default behavior of Electron is to store granted device permission through
|
||||
the lifetime of the corresponding WebContents. If longer term storage is
|
||||
needed, a developer can store granted device permissions (eg when handling
|
||||
the `select-hid-device` event) and then read from that storage with
|
||||
@@ -82,12 +84,15 @@ There are several additional APIs for working with the Web Serial API:
|
||||
|
||||
* The [`serial-port-added`](../api/session.md#event-serial-port-added)
|
||||
and [`serial-port-removed`](../api/session.md#event-serial-port-removed) events
|
||||
on the Session can be used to handle devices being plugged in or unplugged during the
|
||||
`navigator.serial.requestPort` process.
|
||||
on the Session can be used to handle devices being plugged in or unplugged
|
||||
when handling the `select-serial-port` event.
|
||||
**Note:** These events only fire until the callback from `select-serial-port`
|
||||
is called. They are not intended to be used as a generic serial port
|
||||
listener.
|
||||
* [`ses.setDevicePermissionHandler(handler)`](../api/session.md#sessetdevicepermissionhandlerhandler)
|
||||
can be used to provide default permissioning to devices without first calling
|
||||
for permission to devices via `navigator.serial.requestPort`. Additionally,
|
||||
the default behavior of Electron is to store granted device permision through
|
||||
the default behavior of Electron is to store granted device permission through
|
||||
the lifetime of the corresponding WebContents. If longer term storage is
|
||||
needed, a developer can store granted device permissions (eg when handling
|
||||
the `select-serial-port` event) and then read from that storage with
|
||||
|
||||
54
docs/tutorial/distribution-overview.md
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
title: 'Distribution Overview'
|
||||
description: 'To distribute your app with Electron, you need to package and rebrand it. To do this, you can either use specialized tooling or manual approaches.'
|
||||
slug: distribution-overview
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
Once your app is ready for production, there are a couple steps you need to take before
|
||||
you can deliver it to your users.
|
||||
|
||||
## Packaging
|
||||
|
||||
To distribute your app with Electron, you need to package all your resources and assets
|
||||
into an executable and rebrand it. To do this, you can either use specialized tooling
|
||||
or do it manually. See the [Application Packaging][application-packaging] tutorial
|
||||
for more information.
|
||||
|
||||
## Code signing
|
||||
|
||||
Code signing is a security technology that you use to certify that an app was
|
||||
created by you. You should sign your application so it does not trigger the
|
||||
security checks of your user's operating system.
|
||||
|
||||
To get started with each operating system's code signing process, please read the
|
||||
[Code Signing][code-signing] docs.
|
||||
|
||||
## Publishing
|
||||
|
||||
Once your app is packaged and signed, you can freely distribute your app directly
|
||||
to users by uploading your installers online.
|
||||
|
||||
To reach more users, you can also choose to upload your app to each operating system's
|
||||
digital distribution platform (i.e. app store). These require another build step aside
|
||||
from your direct download app. For more information, check out each individual app store guide:
|
||||
|
||||
- [Mac App Store][mac-app]
|
||||
- [Windows Store][windows-store]
|
||||
- [Snapcraft (Linux)][snapcraft]
|
||||
|
||||
## Updating
|
||||
|
||||
Electron's auto-updater allows you to deliver application updates to users
|
||||
without forcing them to manually download new versions of your application.
|
||||
Check out the [Updating Applications][updates] guide for details on implementing automatic updates
|
||||
with Electron.
|
||||
|
||||
<!-- Link labels -->
|
||||
|
||||
[application-packaging]: ./application-distribution.md
|
||||
[code-signing]: ./code-signing.md
|
||||
[mac-app]: ./mac-app-store-submission-guide.md
|
||||
[windows-store]: ./windows-store-guide.md
|
||||
[snapcraft]: ./snapcraft.md
|
||||
[updates]: ./updates.md
|
||||
@@ -1,30 +1,102 @@
|
||||
# Electron Release Timelines
|
||||
# Electron Releases
|
||||
|
||||
Special notes:
|
||||
Electron frequently releases major versions alongside every other Chromium release.
|
||||
This document focuses on the release cadence and version support policy.
|
||||
For a more in-depth guide on our git branches and how Electron uses semantic versions,
|
||||
check out our [Electron Versioning](./electron-versioning.md) doc.
|
||||
|
||||
* The `-beta.1` and `stable` dates are our solid release dates.
|
||||
* We strive for weekly beta releases, however we often release more betas than scheduled.
|
||||
## Timeline
|
||||
|
||||
| Electron | Alpha | Beta | Stable | Chrome | Node | Supported |
|
||||
| ------- | ----- | ------- | ------ | ------ | ---- | ---- |
|
||||
| 2.0.0 | -- | 2018-Feb-21 | 2018-May-01 | M61 | v8.9 | 🚫 |
|
||||
| 3.0.0 | -- | 2018-Jun-21 | 2018-Sep-18 | M66 | v10.2 | 🚫 |
|
||||
| 4.0.0 | -- | 2018-Oct-11 | 2018-Dec-20 | M69 | v10.11 | 🚫 |
|
||||
| 5.0.0 | -- | 2019-Jan-22 | 2019-Apr-24 | M73 | v12.0 | 🚫 |
|
||||
| 6.0.0 | -- | 2019-May-01 | 2019-Jul-30 | M76 | v12.4 | 🚫 |
|
||||
| 7.0.0 | -- | 2019-Aug-01 | 2019-Oct-22 | M78 | v12.8 | 🚫 |
|
||||
| 8.0.0 | -- | 2019-Oct-24 | 2020-Feb-04 | M80 | v12.13 | 🚫 |
|
||||
| 9.0.0 | -- | 2020-Feb-06 | 2020-May-19 | M83 | v12.14 | 🚫 |
|
||||
| 10.0.0 | -- | 2020-May-21 | 2020-Aug-25 | M85 | v12.16 | 🚫 |
|
||||
| 11.0.0 | -- | 2020-Aug-27 | 2020-Nov-17 | M87 | v12.18 | 🚫 |
|
||||
| 12.0.0 | -- | 2020-Nov-19 | 2021-Mar-02 | M89 | v14.16 | 🚫 |
|
||||
| 13.0.0 | -- | 2021-Mar-04 | 2021-May-25 | M91 | v14.16 | 🚫 |
|
||||
| 14.0.0 | -- | 2021-May-27 | 2021-Aug-31 | M93 | v14.17 | 🚫 |
|
||||
| 15.0.0 | 2021-Jul-20 | 2021-Sep-01 | 2021-Sep-21 | M94 | v16.5 | 🚫 |
|
||||
| 16.0.0 | 2021-Sep-23 | 2021-Oct-20 | 2021-Nov-16 | M96 | v16.9 | 🚫 |
|
||||
| 17.0.0 | 2021-Nov-18 | 2022-Jan-06 | 2022-Feb-01 | M98 | v16.13 | 🚫 |
|
||||
| 18.0.0 | 2022-Feb-03 | 2022-Mar-03 | 2022-Mar-29 | M100 | v16.13 | ✅ |
|
||||
| 19.0.0 | 2022-Mar-31 | 2022-Apr-26 | 2022-May-24 | M102 | v16.14 | ✅ |
|
||||
| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | M104 | v16.15 | ✅ |
|
||||
| 21.0.0 | 2022-Aug-04 | 2022-Aug-30 | 2022-Sep-27 | M106 | TBD | ✅ |
|
||||
|
||||
**Notes:**
|
||||
|
||||
* The `-alpha.1`, `-beta.1`, and `stable` dates are our solid release dates.
|
||||
* We strive for weekly alpha/beta releases, but we often release more than scheduled.
|
||||
* All dates are our goals but there may be reasons for adjusting the stable deadline, such as security bugs.
|
||||
* Take a look at the [5.0.0 Timeline blog post](https://electronjs.org/blog/electron-5-0-timeline) for info about publicizing our release dates.
|
||||
* Since Electron 6.0, we've been targeting every other Chromium version and releasing our stable on the same day as Chrome stable. You can reference Chromium's release schedule [here](https://chromiumdash.appspot.com/schedule). See [Electron's new release cadence blog post](https://www.electronjs.org/blog/12-week-cadence) for more details on our release schedule.
|
||||
* Starting in Electron 16.0, we will release on an 8-week cadence. See [Electron's new 8-week cadence blog post](https://www.electronjs.org/blog/8-week-cadence) for more details.
|
||||
|
||||
| Electron | Alpha | Beta | Stable | Chrome | Node |
|
||||
| ------- | ----- | ------- | ------ | ------ | ---- |
|
||||
| 2.0.0 | -- | 2018-Feb-21 | 2018-May-01 | M61 | v8.9 |
|
||||
| 3.0.0 | -- | 2018-Jun-21 | 2018-Sep-18 | M66 | v10.2 |
|
||||
| 4.0.0 | -- | 2018-Oct-11 | 2018-Dec-20 | M69 | v10.11 |
|
||||
| 5.0.0 | -- | 2019-Jan-22 | 2019-Apr-24 | M73 | v12.0 |
|
||||
| 6.0.0 | -- | 2019-May-01 | 2019-Jul-30 | M76 | v12.4 |
|
||||
| 7.0.0 | -- | 2019-Aug-01 | 2019-Oct-22 | M78 | v12.8 |
|
||||
| 8.0.0 | -- | 2019-Oct-24 | 2020-Feb-04 | M80 | v12.13 |
|
||||
| 9.0.0 | -- | 2020-Feb-06 | 2020-May-19 | M83 | v12.14 |
|
||||
| 10.0.0 | -- | 2020-May-21 | 2020-Aug-25 | M85 | v12.16 |
|
||||
| 11.0.0 | -- | 2020-Aug-27 | 2020-Nov-17 | M87 | v12.18 |
|
||||
| 12.0.0 | -- | 2020-Nov-19 | 2021-Mar-02 | M89 | v14.16 |
|
||||
| 13.0.0 | -- | 2021-Mar-04 | 2021-May-25 | M91 | v14.16 |
|
||||
| 14.0.0 | -- | 2021-May-27 | 2021-Aug-31 | M93 | v14.17 |
|
||||
| 15.0.0 | 2021-Jul-20 | 2021-Sep-01 | 2021-Sep-21 | M94 | v16.5 |
|
||||
| 16.0.0 | 2021-Sep-23 | 2021-Oct-20 | 2021-Nov-16 | M96 | v16.9 |
|
||||
| 17.0.0 | 2021-Nov-18 | 2022-Jan-06 | 2022-Feb-01 | M98 | v16.13 |
|
||||
| 18.0.0 | 2022-Feb-03 | 2022-Mar-03 | 2022-Mar-29 | M100 | TBD |
|
||||
**Historical changes:**
|
||||
|
||||
* Since Electron 5, Electron has been publicizing its release dates ([see blog post](https://electronjs.org/blog/electron-5-0-timeline)).
|
||||
* Since Electron 6, Electron major versions have been targeting every other Chromium major version. Each Electron stable should happen on the same day as Chrome stable ([see blog post](https://www.electronjs.org/blog/12-week-cadence)).
|
||||
* Since Electron 16, Electron has been releasing major versions on an 8-week cadence in accordance to Chrome's change to a 4-week release cadence ([see blog post](https://www.electronjs.org/blog/8-week-cadence)).
|
||||
|
||||
:::info Chrome release dates
|
||||
|
||||
Chromium has the own public release schedule [here](https://chromiumdash.appspot.com/schedule).
|
||||
|
||||
:::
|
||||
|
||||
## Version support policy
|
||||
|
||||
:::info
|
||||
|
||||
Beginning in September 2021 (Electron 15), the Electron team
|
||||
will temporarily support the latest **four** stable major versions. This
|
||||
extended support is intended to help Electron developers transition to
|
||||
the [new 8-week release cadence](https://electronjs.org/blog/8-week-cadence),
|
||||
and will continue until the release of Electron 19. At that time,
|
||||
the Electron team will drop support back to the latest three stable major versions.
|
||||
|
||||
:::
|
||||
|
||||
The latest three *stable* major versions are supported by the Electron team.
|
||||
For example, if the latest release is 6.1.x, then the 5.0.x as well
|
||||
as the 4.2.x series are supported. We only support the latest minor release
|
||||
for each stable release series. This means that in the case of a security fix,
|
||||
6.1.x will receive the fix, but we will not release a new version of 6.0.x.
|
||||
|
||||
The latest stable release unilaterally receives all fixes from `main`,
|
||||
and the version prior to that receives the vast majority of those fixes
|
||||
as time and bandwidth warrants. The oldest supported release line will receive
|
||||
only security fixes directly.
|
||||
|
||||
### Breaking API changes
|
||||
|
||||
When an API is changed or removed in a way that breaks existing functionality, the
|
||||
previous functionality will be supported for a minimum of two major versions when
|
||||
possible before being removed. For example, if a function takes three arguments,
|
||||
and that number is reduced to two in major version 10, the three-argument version would
|
||||
continue to work until, at minimum, major version 12. Past the minimum two-version
|
||||
threshold, we will attempt to support backwards compatibility beyond two versions
|
||||
until the maintainers feel the maintenance burden is too high to continue doing so.
|
||||
|
||||
### End-of-life
|
||||
|
||||
When a release branch reaches the end of its support cycle, the series
|
||||
will be deprecated in NPM and a final end-of-support release will be
|
||||
made. This release will add a warning to inform that an unsupported
|
||||
version of Electron is in use.
|
||||
|
||||
These steps are to help app developers learn when a branch they're
|
||||
using becomes unsupported, but without being excessively intrusive
|
||||
to end users.
|
||||
|
||||
If an application has exceptional circumstances and needs to stay
|
||||
on an unsupported series of Electron, developers can silence the
|
||||
end-of-support warning by omitting the final release from the app's
|
||||
`package.json` `devDependencies`. For example, since the 1-6-x series
|
||||
ended with an end-of-support 1.6.18 release, developers could choose
|
||||
to stay in the 1-6-x series without warnings with `devDependency` of
|
||||
`"electron": 1.6.0 - 1.6.17`.
|
||||
|
||||
@@ -18,7 +18,7 @@ npm install --save-dev electron@latest
|
||||
|
||||
There are several major changes from our 1.x strategy outlined below. Each change is intended to satisfy the needs and priorities of developers/maintainers and app developers.
|
||||
|
||||
1. Strict use of the the [SemVer](#semver) spec
|
||||
1. Strict use of the [SemVer](#semver) spec
|
||||
2. Introduction of semver-compliant `-beta` tags
|
||||
3. Introduction of [conventional commit messages](https://conventionalcommits.org/)
|
||||
4. Well-defined stabilization branches
|
||||
@@ -48,7 +48,7 @@ Stabilization branches are branches that run parallel to `main`, taking in only
|
||||
|
||||
Since Electron 8, stabilization branches are always **major** version lines, and named against the following template `$MAJOR-x-y` e.g. `8-x-y`. Prior to that we used **minor** version lines and named them as `$MAJOR-$MINOR-x` e.g. `2-0-x`.
|
||||
|
||||
We allow for multiple stabilization branches to exist simultaneously, one for each supported version. For more details on which versions are supported, see our [Electron Release Timelines](./electron-timelines.md) doc.
|
||||
We allow for multiple stabilization branches to exist simultaneously, one for each supported version. For more details on which versions are supported, see our [Electron Releases](./electron-timelines.md) doc.
|
||||
|
||||

|
||||
|
||||
@@ -107,6 +107,15 @@ A few examples of how various SemVer ranges will pick up new releases:
|
||||
|
||||

|
||||
|
||||
### Backport request process
|
||||
|
||||
All supported release lines will accept external pull requests to backport
|
||||
fixes previously merged to `main`, though this may be on a case-by-case
|
||||
basis for some older supported lines. All contested decisions around release
|
||||
line backports will be resolved by the
|
||||
[Releases Working Group](https://github.com/electron/governance/tree/main/wg-releases)
|
||||
as an agenda item at their weekly meeting the week the backport PR is raised.
|
||||
|
||||
## Feature flags
|
||||
|
||||
Feature flags are a common practice in Chromium, and are well-established in the web-development ecosystem. In the context of Electron, a feature flag or **soft branch** must have the following properties:
|
||||
|
||||
56
docs/tutorial/examples.md
Normal file
@@ -0,0 +1,56 @@
|
||||
---
|
||||
title: 'Examples Overview'
|
||||
description: 'A set of examples for common Electron features'
|
||||
slug: examples
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
# Examples Overview
|
||||
|
||||
In this section, we have collected a set of guides for common features
|
||||
that you may want to implement in your Electron application. Each guide
|
||||
contains a practical example in a minimal, self-contained example app.
|
||||
The easiest way to run these examples is by downloading [Electron Fiddle][fiddle].
|
||||
|
||||
Once Fiddle is installed, you can press on the "Open in Fiddle" button that you
|
||||
will find below code samples like the following one:
|
||||
|
||||
```fiddle docs/fiddles/quick-start
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const replaceText = (selector, text) => {
|
||||
const element = document.getElementById(selector)
|
||||
if (element) element.innerText = text
|
||||
}
|
||||
|
||||
for (const type of ['chrome', 'node', 'electron']) {
|
||||
replaceText(`${type}-version`, process.versions[type])
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
If there is still something that you do not know how to do, please take a look at the [API][app]
|
||||
as there is a chance it might be documented just there (and also open an issue requesting the
|
||||
guide!).
|
||||
|
||||
<!-- guide-table-start -->
|
||||
|
||||
| Guide | Description |
|
||||
| :-------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
||||
| [Message ports] | This guide provides some examples of how you might use MessagePorts in your app to communicate different processes. |
|
||||
| [Device access] | Learn how to access the device hardware (Bluetooth, USB, Serial). |
|
||||
| [Keyboard shortcuts] | Configure local and global keyboard shortcuts for your Electron application. |
|
||||
| [Multithreading] | With Web Workers, it is possible to run JavaScript in OS-level threads |
|
||||
| [Offscreen rendering] | Offscreen rendering lets you obtain the content of a BrowserWindow in a bitmap, so it can be rendered anywhere. |
|
||||
| [Spellchecker] | Learn how to use the built-in spellchecker, set languages, etc. |
|
||||
| [Web embeds] | Discover the different ways to embed third-party web content in your application. |
|
||||
|
||||
<!-- guide-table-end -->
|
||||
|
||||
## How to...?
|
||||
|
||||
You can find the full list of "How to?" in the sidebar. If there is
|
||||
something that you would like to do that is not documented, please join
|
||||
our [Discord server][discord] and let us know!
|
||||
|
||||
[discord]: https://discord.gg/electronjs
|
||||
[fiddle]: https://www.electronjs.org/fiddle
|
||||
@@ -116,7 +116,7 @@ inAppPurchase.getProducts(PRODUCT_IDS).then(products => {
|
||||
console.log(`The price of ${product.localizedTitle} is ${product.formattedPrice}.`)
|
||||
})
|
||||
|
||||
// Ask the user which product he/she wants to purchase.
|
||||
// Ask the user which product they want to purchase.
|
||||
const selectedProduct = products[0]
|
||||
const selectedQuantity = 1
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# Introduction
|
||||
---
|
||||
title: 'Introduction'
|
||||
description: 'Welcome to the Electron documentation! If this is your first time developing an Electron app, read through this Getting Started section to get familiar with the basics. Otherwise, feel free to explore our guides and API documentation!'
|
||||
slug: /latest/
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
Welcome to the Electron documentation! If this is your first time developing
|
||||
an Electron app, read through this Getting Started section to get familiar with the
|
||||
basics. Otherwise, feel free to explore our guides and API documentation!
|
||||
|
||||
## What is Electron?
|
||||
# What is Electron?
|
||||
|
||||
Electron is a framework for building desktop applications using JavaScript,
|
||||
HTML, and CSS. By embedding [Chromium][chromium] and [Node.js][node] into its
|
||||
@@ -12,20 +13,12 @@ binary, Electron allows you to maintain one JavaScript codebase and create
|
||||
cross-platform apps that work on Windows, macOS, and Linux — no native development
|
||||
experience required.
|
||||
|
||||
## Prerequisites
|
||||
## Getting started
|
||||
|
||||
These docs operate under the assumption that the reader is familiar with both
|
||||
Node.js and general web development. If you need to get more comfortable with
|
||||
either of these areas, we recommend the following resources:
|
||||
|
||||
* [Getting started with the Web (MDN)][mdn-guide]
|
||||
* [Introduction to Node.js][node-guide]
|
||||
|
||||
Moreover, you'll have a better time understanding how Electron works if you get
|
||||
acquainted with Chromium's process model. You can get a brief overview of
|
||||
Chrome architecture with the [Chrome comic][comic], which was released alongside
|
||||
Chrome's launch back in 2008. Although it's been over a decade since then, the
|
||||
core principles introduced in the comic remain helpful to understand Electron.
|
||||
We recommend you to start with the [tutorial], which guides you through the
|
||||
process of developing an Electron app and distributing it to users.
|
||||
The [examples] and [API documentation] are also good places to browse around
|
||||
and discover new things.
|
||||
|
||||
## Running examples with Electron Fiddle
|
||||
|
||||
@@ -39,21 +32,45 @@ a code block. If you have Fiddle installed, this button will open a
|
||||
`fiddle.electronjs.org` link that will automatically load the example into Fiddle,
|
||||
no copy-pasting required.
|
||||
|
||||
```fiddle docs/fiddles/quick-start
|
||||
```
|
||||
|
||||
## What is in the docs?
|
||||
|
||||
All the official documentation is available from the sidebar. These
|
||||
are the different categories and what you can expect on each one:
|
||||
|
||||
- **Tutorial**: An end-to-end guide on how to create and publish your first Electron
|
||||
application.
|
||||
- **Processes in Electron**: In-depth reference on Electron processes and how to work with them.
|
||||
- **Best Practices**: Important checklists to keep in mind when developing an Electron app.
|
||||
- **How-To Examples**: Quick references to add features to your Electron app.
|
||||
- **Development**: Miscellaneous development guides.
|
||||
- **Distribution**: Learn how to distribute your app to end users.
|
||||
- **Testing and debugging**: How to debug JavaScript, write tests, and other tools used
|
||||
to create quality Electron applications.
|
||||
- **Resources**: Useful links to better understand how the Electron project works
|
||||
and is organized.
|
||||
- **Contributing to Electron**: Compiling Electron and making contributions can be daunting.
|
||||
We try to make it easier in this section.
|
||||
|
||||
## Getting help
|
||||
|
||||
Are you getting stuck anywhere? Here are a few links to places to look:
|
||||
|
||||
* If you need help with developing your app, our [community Discord server][discord]
|
||||
is a great place to get advice from other Electron app developers.
|
||||
* If you suspect you're running into a bug with the `electron` package, please check
|
||||
the [GitHub issue tracker][issue-tracker] to see if any existing issues match your
|
||||
problem. If not, feel free to fill out our bug report template and submit a new issue.
|
||||
- If you need help with developing your app, our [community Discord server][discord]
|
||||
is a great place to get advice from other Electron app developers.
|
||||
- If you suspect you're running into a bug with the `electron` package, please check
|
||||
the [GitHub issue tracker][issue-tracker] to see if any existing issues match your
|
||||
problem. If not, feel free to fill out our bug report template and submit a new issue.
|
||||
|
||||
<!-- Links -->
|
||||
|
||||
[tutorial]: tutorial-1-prerequisites.md
|
||||
[api documentation]: ../api/app.md
|
||||
[chromium]: https://www.chromium.org/
|
||||
[node]: https://nodejs.org/
|
||||
[mdn-guide]: https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web
|
||||
[node-guide]: https://nodejs.dev/learn
|
||||
[comic]: https://www.google.com/googlebooks/chrome/
|
||||
[discord]: https://discord.gg/electronjs
|
||||
[examples]: examples.md
|
||||
[fiddle]: https://electronjs.org/fiddle
|
||||
[issue-tracker]: https://github.com/electron/electron/issues
|
||||
[discord]: https://discord.gg/electronjs
|
||||
[node]: https://nodejs.org/
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
---
|
||||
title: 'Process Model'
|
||||
description: 'Electron inherits its multi-process architecture from Chromium, which makes the framework architecturally very similar to a modern web browser. This guide will expand on the concepts applied in the tutorial.'
|
||||
slug: process-model
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
# Process Model
|
||||
|
||||
Electron inherits its multi-process architecture from Chromium, which makes the framework
|
||||
architecturally very similar to a modern web browser. In this guide, we'll expound on
|
||||
the conceptual knowledge of Electron that we applied in the minimal [quick start app][].
|
||||
architecturally very similar to a modern web browser. This guide will expand on the
|
||||
concepts applied in the [Tutorial][tutorial].
|
||||
|
||||
[quick start app]: ./quick-start.md
|
||||
[tutorial]: ./tutorial-1-prerequisites.md
|
||||
|
||||
## Why not a single process?
|
||||
|
||||
@@ -27,10 +34,10 @@ visualizes this model:
|
||||

|
||||
|
||||
Electron applications are structured very similarly. As an app developer, you control
|
||||
two types of processes: main and renderer. These are analogous to Chrome's own browser
|
||||
and renderer processes outlined above.
|
||||
two types of processes: [main](#the-main-process) and [renderer](#the-renderer-process).
|
||||
These are analogous to Chrome's own browser and renderer processes outlined above.
|
||||
|
||||
[Chrome Comic]: https://www.google.com/googlebooks/chrome/
|
||||
[chrome comic]: https://www.google.com/googlebooks/chrome/
|
||||
|
||||
## The main process
|
||||
|
||||
@@ -68,7 +75,7 @@ When a `BrowserWindow` instance is destroyed, its corresponding renderer process
|
||||
terminated as well.
|
||||
|
||||
[browser-window]: ../api/browser-window.md
|
||||
[web-embed]: ./web-embeds.md
|
||||
[web-embed]: ../tutorial/web-embeds.md
|
||||
[web-contents]: ../api/web-contents.md
|
||||
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
|
||||
|
||||
@@ -76,7 +83,7 @@ terminated as well.
|
||||
|
||||
The main process also controls your application's lifecycle through Electron's
|
||||
[`app`][app] module. This module provides a large set of events and methods
|
||||
that you can use to add custom application behaviour (for instance, programatically
|
||||
that you can use to add custom application behaviour (for instance, programmatically
|
||||
quitting your application, modifying the application dock, or showing an About panel).
|
||||
|
||||
As a practical example, the app shown in the [quick start guide][quick-start-lifecycle]
|
||||
@@ -90,7 +97,7 @@ app.on('window-all-closed', () => {
|
||||
```
|
||||
|
||||
[app]: ../api/app.md
|
||||
[quick-start-lifecycle]: ./quick-start.md#manage-your-windows-lifecycle
|
||||
[quick-start-lifecycle]: ../tutorial/quick-start.md#manage-your-windows-lifecycle
|
||||
|
||||
### Native APIs
|
||||
|
||||
@@ -105,7 +112,7 @@ For a full list of Electron's main process modules, check out our API documentat
|
||||
|
||||
Each Electron app spawns a separate renderer process for each open `BrowserWindow`
|
||||
(and each web embed). As its name implies, a renderer is responsible for
|
||||
*rendering* web content. For all intents and purposes, code ran in renderer processes
|
||||
_rendering_ web content. For all intents and purposes, code ran in renderer processes
|
||||
should behave according to web standards (insofar as Chromium does, at least).
|
||||
|
||||
Therefore, all user interfaces and app functionality within a single browser
|
||||
@@ -115,18 +122,22 @@ web.
|
||||
Although explaining every web spec is out of scope for this guide, the bare minimum
|
||||
to understand is:
|
||||
|
||||
* An HTML file is your entry point for the renderer process.
|
||||
* UI styling is added through Cascading Style Sheets (CSS).
|
||||
* Executable JavaScript code can be added through `<script>` elements.
|
||||
- An HTML file is your entry point for the renderer process.
|
||||
- UI styling is added through Cascading Style Sheets (CSS).
|
||||
- Executable JavaScript code can be added through `<script>` elements.
|
||||
|
||||
Moreover, this also means that the renderer has no direct access to `require`
|
||||
or other Node.js APIs. In order to directly include NPM modules in the renderer,
|
||||
you must use the same bundler toolchains (for example, `webpack` or `parcel`) that you
|
||||
use on the web.
|
||||
|
||||
> Note: Renderer processes can be spawned with a full Node.js environment for ease of
|
||||
> development. Historically, this used to be the default, but this feature was disabled
|
||||
> for security reasons.
|
||||
:::warning
|
||||
|
||||
Renderer processes can be spawned with a full Node.js environment for ease of
|
||||
development. Historically, this used to be the default, but this feature was disabled
|
||||
for security reasons.
|
||||
|
||||
:::
|
||||
|
||||
At this point, you might be wondering how your renderer process user interfaces
|
||||
can interact with Node.js and Electron's native desktop functionality if these
|
||||
@@ -135,8 +146,9 @@ way to import Electron's content scripts.
|
||||
|
||||
## Preload scripts
|
||||
|
||||
<!-- Note: This guide doesn't take sandboxing into account, which might fundamentally
|
||||
<!-- Note: This guide doesn't take sandboxing into account, which might fundamentally
|
||||
change the statements here. -->
|
||||
|
||||
Preload scripts contain code that executes in a renderer process before its web content
|
||||
begins loading. These scripts run within the renderer context, but are granted more
|
||||
privileges by having access to Node.js APIs.
|
||||
@@ -149,8 +161,8 @@ const { BrowserWindow } = require('electron')
|
||||
//...
|
||||
const win = new BrowserWindow({
|
||||
webPreferences: {
|
||||
preload: 'path/to/preload.js'
|
||||
}
|
||||
preload: 'path/to/preload.js',
|
||||
},
|
||||
})
|
||||
//...
|
||||
```
|
||||
@@ -165,7 +177,7 @@ the [`contextIsolation`][context-isolation] default.
|
||||
|
||||
```js title='preload.js'
|
||||
window.myAPI = {
|
||||
desktop: true
|
||||
desktop: true,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -184,7 +196,7 @@ securely:
|
||||
const { contextBridge } = require('electron')
|
||||
|
||||
contextBridge.exposeInMainWorld('myAPI', {
|
||||
desktop: true
|
||||
desktop: true,
|
||||
})
|
||||
```
|
||||
|
||||
@@ -195,14 +207,15 @@ console.log(window.myAPI)
|
||||
|
||||
This feature is incredibly useful for two main purposes:
|
||||
|
||||
* By exposing [`ipcRenderer`][ipcRenderer] helpers to the renderer, you can use
|
||||
- By exposing [`ipcRenderer`][ipcrenderer] helpers to the renderer, you can use
|
||||
inter-process communication (IPC) to trigger main process tasks from the
|
||||
renderer (and vice-versa).
|
||||
* If you're developing an Electron wrapper for an existing web app hosted on a remote
|
||||
- If you're developing an Electron wrapper for an existing web app hosted on a remote
|
||||
URL, you can add custom properties onto the renderer's `window` global that can
|
||||
be used for desktop-only logic on the web client's side.
|
||||
|
||||
[window-mdn]: https://developer.mozilla.org/en-US/docs/Web/API/Window
|
||||
[context-isolation]: ./context-isolation.md
|
||||
[context-bridge]: ../api/context-bridge.md
|
||||
[ipcRenderer]: ../api/ipc-renderer.md
|
||||
[ipcrenderer]: ../api/ipc-renderer.md
|
||||
[tutorial]: ./tutorial-1-prerequisites.md
|
||||
|
||||
@@ -66,7 +66,7 @@ Your `package.json` file should look something like this:
|
||||
Then, install the `electron` package into your app's `devDependencies`.
|
||||
|
||||
```sh npm2yarn
|
||||
$ npm install --save-dev electron
|
||||
npm install --save-dev electron
|
||||
```
|
||||
|
||||
> Note: If you're encountering any issues with installing Electron, please
|
||||
@@ -131,7 +131,6 @@ folder of your project:
|
||||
<meta charset="UTF-8">
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
||||
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
||||
<title>Hello World!</title>
|
||||
</head>
|
||||
<body>
|
||||
@@ -404,7 +403,7 @@ app.on('window-all-closed', () => {
|
||||
```js
|
||||
// preload.js
|
||||
|
||||
// All of the Node.js APIs are available in the preload process.
|
||||
// All the Node.js APIs are available in the preload process.
|
||||
// It has the same sandbox as a Chrome extension.
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const replaceText = (selector, text) => {
|
||||
@@ -427,7 +426,6 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||
<meta charset="UTF-8">
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
||||
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
||||
<title>Hello World!</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -157,7 +157,7 @@ versions of Electron, we do not make a guarantee that every fix will be
|
||||
backported. Your best chance at staying secure is to be on the latest stable
|
||||
version of Electron.
|
||||
|
||||
[sandbox]: https://chromium.googlesource.com/chromium/src/+/master/docs/design/sandbox.md
|
||||
[sandbox]: https://chromium.googlesource.com/chromium/src/+/main/docs/design/sandbox.md
|
||||
[issue-28466]: https://github.com/electron/electron/issues/28466
|
||||
[browser-window]: ../api/browser-window.md
|
||||
[enable-sandbox]: ../api/app.md#appenablesandbox
|
||||
|
||||
@@ -99,7 +99,7 @@ You should at least follow these steps to improve the security of your applicati
|
||||
|
||||
1. [Only load secure content](#1-only-load-secure-content)
|
||||
2. [Disable the Node.js integration in all renderers that display remote content](#2-do-not-enable-nodejs-integration-for-remote-content)
|
||||
3. [Enable context isolation in all renderers that display remote content](#3-enable-context-isolation-for-remote-content)
|
||||
3. [Enable context isolation in all renderers](#3-enable-context-isolation)
|
||||
4. [Enable process sandboxing](#4-enable-process-sandboxing)
|
||||
5. [Use `ses.setPermissionRequestHandler()` in all sessions that load remote content](#5-handle-session-permission-requests-from-remote-content)
|
||||
6. [Do not disable `webSecurity`](#6-do-not-disable-websecurity)
|
||||
@@ -225,7 +225,7 @@ do consume Node.js modules or features. Preload scripts continue to have access
|
||||
to `require` and other Node.js features, allowing developers to expose a custom
|
||||
API to remotely loaded content via the [contextBridge API](../api/context-bridge.md).
|
||||
|
||||
### 3. Enable Context Isolation for remote content
|
||||
### 3. Enable Context Isolation
|
||||
|
||||
:::info
|
||||
This recommendation is the default behavior in Electron since 12.0.0.
|
||||
@@ -279,11 +279,12 @@ security-conscious developers might want to assume the very opposite.
|
||||
|
||||
```js title='main.js (Main Process)'
|
||||
const { session } = require('electron')
|
||||
const URL = require('url').URL
|
||||
|
||||
session
|
||||
.fromPartition('some-partition')
|
||||
.setPermissionRequestHandler((webContents, permission, callback) => {
|
||||
const url = webContents.getURL()
|
||||
const parsedUrl = new URL(webContents.getURL())
|
||||
|
||||
if (permission === 'notifications') {
|
||||
// Approves the permissions request
|
||||
@@ -291,7 +292,7 @@ session
|
||||
}
|
||||
|
||||
// Verify URL
|
||||
if (!url.startsWith('https://example.com/')) {
|
||||
if (parsedUrl.protocol !== 'https:' || parsedUrl.host !== 'example.com') {
|
||||
// Denies the permissions request
|
||||
return callback(false)
|
||||
}
|
||||
@@ -562,7 +563,6 @@ app.on('web-contents-created', (event, contents) => {
|
||||
contents.on('will-attach-webview', (event, webPreferences, params) => {
|
||||
// Strip away preload scripts if unused or verify their location is legitimate
|
||||
delete webPreferences.preload
|
||||
delete webPreferences.preloadURL
|
||||
|
||||
// Disable Node.js integration
|
||||
webPreferences.nodeIntegration = false
|
||||
@@ -724,6 +724,41 @@ Migrate your app one major version at a time, while referring to Electron's
|
||||
[Breaking Changes][breaking-changes] document to see if any code needs to
|
||||
be updated.
|
||||
|
||||
### 17. Validate the `sender` of all IPC messages
|
||||
|
||||
You should always validate incoming IPC messages `sender` property to ensure you
|
||||
aren't performing actions or sending information to untrusted renderers.
|
||||
|
||||
#### Why?
|
||||
|
||||
All Web Frames can in theory send IPC messages to the main process, including
|
||||
iframes and child windows in some scenarios. If you have an IPC message that returns
|
||||
user data to the sender via `event.reply` or performs privileged actions that the renderer
|
||||
can't natively, you should ensure you aren't listening to third party web frames.
|
||||
|
||||
You should be validating the `sender` of **all** IPC messages by default.
|
||||
|
||||
#### How?
|
||||
|
||||
```js title='main.js (Main Process)'
|
||||
// Bad
|
||||
ipcMain.handle('get-secrets', () => {
|
||||
return getSecrets();
|
||||
});
|
||||
|
||||
// Good
|
||||
ipcMain.handle('get-secrets', (e) => {
|
||||
if (!validateSender(e.senderFrame)) return null;
|
||||
return getSecrets();
|
||||
});
|
||||
|
||||
function validateSender(frame) {
|
||||
// Value the host of the URL using an actual URL parser and an allowlist
|
||||
if ((new URL(frame.url)).host === 'electronjs.org') return true;
|
||||
return false;
|
||||
}
|
||||
```
|
||||
|
||||
[breaking-changes]: ../breaking-changes.md
|
||||
[browser-window]: ../api/browser-window.md
|
||||
[browser-view]: ../api/browser-view.md
|
||||
|
||||
@@ -1,128 +1,5 @@
|
||||
# Electron Support
|
||||
# This doc has moved!
|
||||
|
||||
## Finding Support
|
||||
|
||||
If you have a security concern,
|
||||
please see the [security document](https://github.com/electron/electron/tree/main/SECURITY.md).
|
||||
|
||||
If you're looking for programming help,
|
||||
for answers to questions,
|
||||
or to join in discussion with other developers who use Electron,
|
||||
you can interact with the community in these locations:
|
||||
|
||||
* [Electron's Discord server](https://discord.com/invite/APGC3k5yaH) has channels for:
|
||||
* Getting help
|
||||
* Ecosystem apps like [Electron Forge](https://github.com/electron-userland/electron-forge) and [Electron Fiddle](https://github.com/electron/fiddle)
|
||||
* Sharing ideas with other Electron app developers
|
||||
* And more!
|
||||
* [`electron`](https://discuss.atom.io/c/electron) category on the Atom forums
|
||||
* `#electron` channel on [Atom's Slack](https://discuss.atom.io/t/join-us-on-slack/16638?source_topic_id=25406)
|
||||
* [`electron-ru`](https://telegram.me/electron_ru) *(Russian)*
|
||||
* [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
|
||||
* [`electron-kr`](https://electron-kr.github.io/electron-kr) *(Korean)*
|
||||
* [`electron-jp`](https://electron-jp.slack.com) *(Japanese)*
|
||||
* [`electron-tr`](https://electron-tr.herokuapp.com) *(Turkish)*
|
||||
* [`electron-id`](https://electron-id.slack.com) *(Indonesia)*
|
||||
* [`electron-pl`](https://electronpl.github.io) *(Poland)*
|
||||
|
||||
If you'd like to contribute to Electron,
|
||||
see the [contributing document](https://github.com/electron/electron/blob/main/CONTRIBUTING.md).
|
||||
|
||||
If you've found a bug in a [supported version](#supported-versions) of Electron,
|
||||
please report it with the [issue tracker](../development/issues.md).
|
||||
|
||||
[awesome-electron](https://github.com/sindresorhus/awesome-electron)
|
||||
is a community-maintained list of useful example apps,
|
||||
tools and resources.
|
||||
|
||||
## Supported Versions
|
||||
|
||||
_**Note:** Beginning in September 2021 with Electron 15, the Electron team
|
||||
will temporarily support the latest **four** stable major versions. This
|
||||
extended support is intended to help Electron developers transition to
|
||||
the [new eight week release cadence](https://electronjs.org/blog/8-week-cadence), and will continue until May 2022, with
|
||||
the release of Electron 19. At that time, the Electron team will drop support
|
||||
back to the latest three stable major versions._
|
||||
|
||||
The latest three *stable* major versions are supported by the Electron team.
|
||||
For example, if the latest release is 6.1.x, then the 5.0.x as well
|
||||
as the 4.2.x series are supported. We only support the latest minor release
|
||||
for each stable release series. This means that in the case of a security fix
|
||||
6.1.x will receive the fix, but we will not release a new version of 6.0.x.
|
||||
|
||||
The latest stable release unilaterally receives all fixes from `main`,
|
||||
and the version prior to that receives the vast majority of those fixes
|
||||
as time and bandwidth warrants. The oldest supported release line will receive
|
||||
only security fixes directly.
|
||||
|
||||
All supported release lines will accept external pull requests to backport
|
||||
fixes previously merged to `main`, though this may be on a case-by-case
|
||||
basis for some older supported lines. All contested decisions around release
|
||||
line backports will be resolved by the [Releases Working Group](https://github.com/electron/governance/tree/main/wg-releases) as an agenda item at their weekly meeting the week the backport PR is raised.
|
||||
|
||||
When an API is changed or removed in a way that breaks existing functionality, the
|
||||
previous functionality will be supported for a minimum of two major versions when
|
||||
possible before being removed. For example, if a function takes three arguments,
|
||||
and that number is reduced to two in major version 10, the three-argument version would
|
||||
continue to work until, at minimum, major version 12. Past the minimum two-version
|
||||
threshold, we will attempt to support backwards compatibility beyond two versions
|
||||
until the maintainers feel the maintenance burden is too high to continue doing so.
|
||||
|
||||
### Currently supported versions
|
||||
|
||||
* 18.x.y
|
||||
* 17.x.y
|
||||
* 16.x.y
|
||||
* 15.x.y
|
||||
|
||||
### End-of-life
|
||||
|
||||
When a release branch reaches the end of its support cycle, the series
|
||||
will be deprecated in NPM and a final end-of-support release will be
|
||||
made. This release will add a warning to inform that an unsupported
|
||||
version of Electron is in use.
|
||||
|
||||
These steps are to help app developers learn when a branch they're
|
||||
using becomes unsupported, but without being excessively intrusive
|
||||
to end users.
|
||||
|
||||
If an application has exceptional circumstances and needs to stay
|
||||
on an unsupported series of Electron, developers can silence the
|
||||
end-of-support warning by omitting the final release from the app's
|
||||
`package.json` `devDependencies`. For example, since the 1-6-x series
|
||||
ended with an end-of-support 1.6.18 release, developers could choose
|
||||
to stay in the 1-6-x series without warnings with `devDependency` of
|
||||
`"electron": 1.6.0 - 1.6.17`.
|
||||
|
||||
## Supported Platforms
|
||||
|
||||
Following platforms are supported by Electron:
|
||||
|
||||
### macOS
|
||||
|
||||
Only 64bit binaries are provided for macOS, and the minimum macOS version
|
||||
supported is macOS 10.11 (El Capitan).
|
||||
|
||||
Native support for Apple Silicon (`arm64`) devices was added in Electron 11.0.0.
|
||||
|
||||
### Windows
|
||||
|
||||
Windows 7 and later are supported, older operating systems are not supported
|
||||
(and do not work).
|
||||
|
||||
Both `ia32` (`x86`) and `x64` (`amd64`) binaries are provided for Windows.
|
||||
[Native support for Windows on Arm (`arm64`) devices was added in Electron 6.0.8.](windows-arm.md).
|
||||
Running apps packaged with previous versions is possible using the ia32 binary.
|
||||
|
||||
### Linux
|
||||
|
||||
The prebuilt binaries of Electron are built on Ubuntu 18.04.
|
||||
|
||||
Whether the prebuilt binary can run on a distribution depends on whether the
|
||||
distribution includes the libraries that Electron is linked to on the building
|
||||
platform, so only Ubuntu 18.04 is guaranteed to work, but following platforms
|
||||
are also verified to be able to run the prebuilt binaries of Electron:
|
||||
|
||||
* Ubuntu 14.04 and newer
|
||||
* Fedora 24 and newer
|
||||
* Debian 8 and newer
|
||||
* For information on supported releases, see the [Electron Releases](./electron-timelines.md) doc.
|
||||
* For community support on Electron, see the [Community page](https://www.electronjs.org/community).
|
||||
* For platform support info, see the [README](https://github.com/electron/electron/blob/main/README.md).
|
||||
|
||||
143
docs/tutorial/tutorial-1-prerequisites.md
Normal file
@@ -0,0 +1,143 @@
|
||||
---
|
||||
title: 'Prerequisites'
|
||||
description: 'This guide will step you through the process of creating a barebones Hello World app in Electron, similar to electron/electron-quick-start.'
|
||||
slug: tutorial-prerequisites
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
:::info Follow along the tutorial
|
||||
|
||||
This is **part 1** of the Electron tutorial.
|
||||
|
||||
1. **[Prerequisites][prerequisites]**
|
||||
1. [Building your First App][building your first app]
|
||||
1. [Using Preload Scripts][preload]
|
||||
1. [Adding Features][features]
|
||||
1. [Packaging Your Application][packaging]
|
||||
1. [Publishing and Updating][updates]
|
||||
|
||||
:::
|
||||
|
||||
Electron is a framework for building desktop applications using JavaScript,
|
||||
HTML, and CSS. By embedding [Chromium][chromium] and [Node.js][node] into a
|
||||
single binary file, Electron allows you to create cross-platform apps that
|
||||
work on Windows, macOS, and Linux with a single JavaScript codebase.
|
||||
|
||||
This tutorial will guide you through the process of developing a desktop
|
||||
application with Electron and distributing it to end users.
|
||||
|
||||
## Assumptions
|
||||
|
||||
Electron is a native wrapper layer for web apps and is run in a Node.js environment.
|
||||
Therefore, this tutorial assumes you are generally familiar with Node and
|
||||
front-end web development basics. If you need to do some background reading before
|
||||
continuing, we recommend the following resources:
|
||||
|
||||
- [Getting started with the Web (MDN Web Docs)][mdn-guide]
|
||||
- [Introduction to Node.js][node-guide]
|
||||
|
||||
## Required tools
|
||||
|
||||
### Code editor
|
||||
|
||||
You will need a text editor to write your code. We recommend using [Visual Studio Code],
|
||||
although you can choose whichever one you prefer.
|
||||
|
||||
### Command line
|
||||
|
||||
Throughout the tutorial, we will ask you to use various command-line interfaces (CLIs). You can
|
||||
type these commands into your system's default terminal:
|
||||
|
||||
- Windows: Command Prompt or PowerShell
|
||||
- macOS: Terminal
|
||||
- Linux: varies depending on distribution (e.g. GNOME Terminal, Konsole)
|
||||
|
||||
Most code editors also come with an integrated terminal, which you can also use.
|
||||
|
||||
### Git and GitHub
|
||||
|
||||
Git is a commonly-used version control system for source code, and GitHub is a collaborative
|
||||
development platform built on top of it. Although neither is strictly necessary to building
|
||||
an Electron application, we will use GitHub releases to set up automatic updates later
|
||||
on in the tutorial. Therefore, we'll require you to:
|
||||
|
||||
- [Create a GitHub account](https://github.com/join)
|
||||
- [Install Git](https://github.com/git-guides/install-git)
|
||||
|
||||
If you're unfamiliar with how Git works, we recommend reading GitHub's [Git guides]. You can also
|
||||
use the [GitHub Desktop] app if you prefer using a visual interface over the command line.
|
||||
|
||||
We recommend that you create a local Git repository and publish it to GitHub before starting
|
||||
the tutorial, and commit your code after every step.
|
||||
|
||||
:::info Installing Git via GitHub Desktop
|
||||
|
||||
GitHub Desktop will install the latest version of Git on your system if you don't already have
|
||||
it installed.
|
||||
|
||||
:::
|
||||
|
||||
### Node.js and npm
|
||||
|
||||
To begin developing an Electron app, you need to install the [Node.js][node-download]
|
||||
runtime and its bundled npm package manager onto your system. We recommend that you
|
||||
use the latest long-term support (LTS) version.
|
||||
|
||||
:::tip
|
||||
|
||||
Please install Node.js using pre-built installers for your platform.
|
||||
You may encounter incompatibility issues with different development tools otherwise.
|
||||
If you are using macOS, we recommend using a package manager like [Homebrew] or
|
||||
[nvm] to avoid any directory permission issues.
|
||||
|
||||
:::
|
||||
|
||||
To check that Node.js was installed correctly, you can use the `-v` flag when
|
||||
running the `node` and `npm` commands. These should print out the installed
|
||||
versions.
|
||||
|
||||
```sh
|
||||
$ node -v
|
||||
v16.14.2
|
||||
$ npm -v
|
||||
8.7.0
|
||||
```
|
||||
|
||||
:::caution
|
||||
|
||||
Although you need Node.js installed locally to scaffold an Electron project,
|
||||
Electron **does not use your system's Node.js installation to run its code**. Instead, it
|
||||
comes bundled with its own Node.js runtime. This means that your end users do not
|
||||
need to install Node.js themselves as a prerequisite to running your app.
|
||||
|
||||
To check which version of Node.js is running in your app, you can access the global
|
||||
[`process.versions`] variable in the main process or preload script. You can also reference
|
||||
the list of versions in the [electron/releases] repository.
|
||||
|
||||
:::
|
||||
|
||||
<!-- Links -->
|
||||
|
||||
[chromium]: https://www.chromium.org/
|
||||
[electron/releases]: https://github.com/electron/releases/blob/master/readme.md#releases
|
||||
[homebrew]: https://brew.sh/
|
||||
[mdn-guide]: https://developer.mozilla.org/en-US/docs/Learn/
|
||||
[node]: https://nodejs.org/
|
||||
[node-guide]: https://nodejs.dev/learn
|
||||
[node-download]: https://nodejs.org/en/download/
|
||||
[nvm]: https://github.com/nvm-sh/nvm
|
||||
[process-model]: ./process-model.md
|
||||
[`process.versions`]: https://nodejs.org/api/process.html#processversions
|
||||
[github]: https://github.com/
|
||||
[git guides]: https://github.com/git-guides/
|
||||
[github desktop]: https://desktop.github.com/
|
||||
[visual studio code]: https://code.visualstudio.com/
|
||||
|
||||
<!-- Tutorial links -->
|
||||
|
||||
[prerequisites]: tutorial-1-prerequisites.md
|
||||
[building your first app]: tutorial-2-first-app.md
|
||||
[preload]: tutorial-3-preload.md
|
||||
[features]: tutorial-4-adding-features.md
|
||||
[packaging]: tutorial-5-packaging.md
|
||||
[updates]: tutorial-6-publishing-updating.md
|
||||
480
docs/tutorial/tutorial-2-first-app.md
Normal file
@@ -0,0 +1,480 @@
|
||||
---
|
||||
title: 'Building your First App'
|
||||
description: 'This guide will step you through the process of creating a barebones Hello World app in Electron, similar to electron/electron-quick-start.'
|
||||
slug: tutorial-first-app
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
:::info Follow along the tutorial
|
||||
|
||||
This is **part 2** of the Electron tutorial.
|
||||
|
||||
1. [Prerequisites][prerequisites]
|
||||
1. **[Building your First App][building your first app]**
|
||||
1. [Using Preload Scripts][preload]
|
||||
1. [Adding Features][features]
|
||||
1. [Packaging Your Application][packaging]
|
||||
1. [Publishing and Updating][updates]
|
||||
|
||||
:::
|
||||
|
||||
## Learning goals
|
||||
|
||||
In this part of the tutorial, you will learn how to set up your Electron project
|
||||
and write a minimal starter application. By the end of this section,
|
||||
you should be able to run a working Electron app in development mode from
|
||||
your terminal.
|
||||
|
||||
## Setting up your project
|
||||
|
||||
:::caution Avoid WSL
|
||||
|
||||
If you are on a Windows machine, please do not use [Windows Subsystem for Linux][wsl] (WSL)
|
||||
when following this tutorial as you will run into issues when trying to execute the
|
||||
application.
|
||||
|
||||
<!--https://www.electronforge.io/guides/developing-with-wsl-->
|
||||
|
||||
:::
|
||||
|
||||
### Initializing your npm project
|
||||
|
||||
Electron apps are scaffolded using npm, with the package.json file
|
||||
as an entry point. Start by creating a folder and initializing an npm package
|
||||
within it with `npm init`.
|
||||
|
||||
```sh npm2yarn
|
||||
mkdir my-electron-app && cd my-electron-app
|
||||
npm init
|
||||
```
|
||||
|
||||
This command will prompt you to configure some fields in your package.json.
|
||||
There are a few rules to follow for the purposes of this tutorial:
|
||||
|
||||
- _entry point_ should be `main.js` (you will be creating that file soon).
|
||||
- _author_, _license_, and _description_ can be any value, but will be necessary for
|
||||
[packaging][packaging] later on.
|
||||
|
||||
Then, install Electron into your app's **devDependencies**, which is the list of external
|
||||
development-only package dependencies not required in production.
|
||||
|
||||
:::info Why is Electron a devDependency?
|
||||
|
||||
This may seem counter-intuitive since your production code is running Electron APIs.
|
||||
However, packaged apps will come bundled with the Electron binary, eliminating the need to specify
|
||||
it as a production dependency.
|
||||
|
||||
:::
|
||||
|
||||
```sh npm2yarn
|
||||
npm install electron --save-dev
|
||||
```
|
||||
|
||||
Your package.json file should look something like this after initializing your package
|
||||
and installing Electron. You should also now have a `node_modules` folder containing
|
||||
the Electron executable, as well as a `package-lock.json` lockfile that specifies
|
||||
the exact dependency versions to install.
|
||||
|
||||
```json title='package.json'
|
||||
{
|
||||
"name": "my-electron-app",
|
||||
"version": "1.0.0",
|
||||
"description": "Hello World!",
|
||||
"main": "main.js",
|
||||
"author": "Jane Doe",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"electron": "19.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
:::info Advanced Electron installation steps
|
||||
|
||||
If installing Electron directly fails, please refer to our [Advanced Installation][installation]
|
||||
documentation for instructions on download mirrors, proxies, and troubleshooting steps.
|
||||
|
||||
:::
|
||||
|
||||
### Adding a .gitignore
|
||||
|
||||
The [`.gitignore`][gitignore] file specifies which files and directories to avoid tracking
|
||||
with Git. You should place a copy of [GitHub's Node.js gitignore template][gitignore-template]
|
||||
into your project's root folder to avoid committing your project's `node_modules` folder.
|
||||
|
||||
## Running an Electron app
|
||||
|
||||
:::tip Further reading
|
||||
|
||||
Read [Electron's process model][process-model] documentation to better
|
||||
understand how Electron's multiple processes work together.
|
||||
|
||||
:::
|
||||
|
||||
The [`main`][package-json-main] script you defined in package.json is the entry point of any
|
||||
Electron application. This script controls the **main process**, which runs in a Node.js
|
||||
environment and is responsible for controlling your app's lifecycle, displaying native
|
||||
interfaces, performing privileged operations, and managing renderer processes
|
||||
(more on that later).
|
||||
|
||||
Before creating your first Electron app, you will first use a trivial script to ensure your
|
||||
main process entry point is configured correctly. Create a `main.js` file in the root folder
|
||||
of your project with a single line of code:
|
||||
|
||||
```js title='main.js'
|
||||
console.log(`Hello from Electron 👋`)
|
||||
```
|
||||
|
||||
Because Electron's main process is a Node.js runtime, you can execute arbitrary Node.js code
|
||||
with the `electron` command (you can even use it as a [REPL]). To execute this script,
|
||||
add `electron .` to the `start` command in the [`scripts`][package-scripts]
|
||||
field of your package.json. This command will tell the Electron executable to look for the main
|
||||
script in the current directory and run it in dev mode.
|
||||
|
||||
```json {8-10} title='package.json'
|
||||
{
|
||||
"name": "my-electron-app",
|
||||
"version": "1.0.0",
|
||||
"description": "Hello World!",
|
||||
"main": "main.js",
|
||||
"author": "Jane Doe",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"start": "electron ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron": "^19.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```sh npm2yarn
|
||||
npm run start
|
||||
```
|
||||
|
||||
Your terminal should print out `Hello from Electron 👋`. Congratulations,
|
||||
you have executed your first line of code in Electron! Next, you will learn
|
||||
how to create user interfaces with HTML and load that into a native window.
|
||||
|
||||
## Loading a web page into a BrowserWindow
|
||||
|
||||
In Electron, each window displays a web page that can be loaded either from a local HTML
|
||||
file or a remote web address. For this example, you will be loading in a local file. Start
|
||||
by creating a barebones web page in an `index.html` file in the root folder of your project:
|
||||
|
||||
```html title='index.html'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="default-src 'self'; script-src 'self'"
|
||||
/>
|
||||
<meta
|
||||
http-equiv="X-Content-Security-Policy"
|
||||
content="default-src 'self'; script-src 'self'"
|
||||
/>
|
||||
<title>Hello from Electron renderer!</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello from Electron renderer!</h1>
|
||||
<p>👋</p>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Now that you have a web page, you can load it into an Electron [BrowserWindow][browser-window].
|
||||
Replace the contents your `main.js` file with the following code. We will explain each
|
||||
highlighted block separately.
|
||||
|
||||
```js {1,3-10,12-14} title='main.js' showLineNumbers
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
```
|
||||
|
||||
### Importing modules
|
||||
|
||||
```js title='main.js (Line 1)'
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
```
|
||||
|
||||
In the first line, we are importing two Electron modules
|
||||
with CommonJS module syntax:
|
||||
|
||||
- [app][app], which controls your application's event lifecycle.
|
||||
- [BrowserWindow][browser-window], which creates and manages app windows.
|
||||
|
||||
:::info Capitalization conventions
|
||||
|
||||
You might have noticed the capitalization difference between the **a**pp
|
||||
and **B**rowser**W**indow modules. Electron follows typical JavaScript conventions here,
|
||||
where PascalCase modules are instantiable class constructors (e.g. BrowserWindow, Tray,
|
||||
Notification) whereas camelCase modules are not instantiable (e.g. app, ipcRenderer, webContents).
|
||||
|
||||
:::
|
||||
|
||||
:::warning ES Modules in Electron
|
||||
|
||||
[ECMAScript modules](https://nodejs.org/api/esm.html) (i.e. using `import` to load a module)
|
||||
are currently not directly supported in Electron. You can find more information about the
|
||||
state of ESM in Electron in [electron/electron#21457](https://github.com/electron/electron/issues/21457).
|
||||
|
||||
:::
|
||||
|
||||
### Writing a reusable function to instantiate windows
|
||||
|
||||
The `createWindow()` function loads your web page into a new BrowserWindow instance:
|
||||
|
||||
```js title='main.js (Lines 3-10)'
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
```
|
||||
|
||||
### Calling your function when the app is ready
|
||||
|
||||
```js title='main.js (Lines 12-14)'
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
```
|
||||
|
||||
Many of Electron's core modules are Node.js [event emitters] that adhere to Node's asynchronous
|
||||
event-driven architecture. The app module is one of these emitters.
|
||||
|
||||
In Electron, BrowserWindows can only be created after the app module's [`ready`][app-ready] event
|
||||
is fired. You can wait for this event by using the [`app.whenReady()`][app-when-ready] API and
|
||||
calling `createWindow()` once its promise is fulfilled.
|
||||
|
||||
:::info
|
||||
|
||||
You typically listen to Node.js events by using an emitter's `.on` function.
|
||||
|
||||
```diff
|
||||
+ app.on('ready').then(() => {
|
||||
- app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
```
|
||||
|
||||
However, Electron exposes `app.whenReady()` as a helper specifically for the `ready` event to
|
||||
avoid subtle pitfalls with directly listening to that event in particular.
|
||||
See [electron/electron#21972](https://github.com/electron/electron/pull/21972) for details.
|
||||
|
||||
:::
|
||||
|
||||
At this point, running your Electron application's `start` command should successfully
|
||||
open a window that displays your web page!
|
||||
|
||||
Each web page your app displays in a window will run in a separate process called a
|
||||
**renderer** process (or simply _renderer_ for short). Renderer processes have access
|
||||
to the same JavaScript APIs and tooling you use for typical front-end web
|
||||
development, such as using [webpack] to bundle and minify your code or [React][react]
|
||||
to build your user interfaces.
|
||||
|
||||
## Managing your app's window lifecycle
|
||||
|
||||
Application windows behave differently on each operating system. Rather than
|
||||
enforce these conventions by default, Electron gives you the choice to implement
|
||||
them in your app code if you wish to follow them. You can implement basic window
|
||||
conventions by listening for events emitted by the app and BrowserWindow modules.
|
||||
|
||||
:::tip Process-specific control flow
|
||||
|
||||
Checking against Node's [`process.platform`][node-platform] variable can help you
|
||||
to run code conditionally on certain platforms. Note that there are only three
|
||||
possible platforms that Electron can run in: `win32` (Windows), `linux` (Linux),
|
||||
and `darwin` (macOS).
|
||||
|
||||
:::
|
||||
|
||||
### Quit the app when all windows are closed (Windows & Linux)
|
||||
|
||||
On Windows and Linux, closing all windows will generally quit an application entirely.
|
||||
To implement this pattern in your Electron app, listen for the app module's
|
||||
[`window-all-closed`][window-all-closed] event, and call [`app.quit()`][app-quit]
|
||||
to exit your app if the user is not on macOS.
|
||||
|
||||
```js
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') app.quit()
|
||||
})
|
||||
```
|
||||
|
||||
### Open a window if none are open (macOS)
|
||||
|
||||
In contrast, macOS apps generally continue running even without any windows open.
|
||||
Activating the app when no windows are available should open a new one.
|
||||
|
||||
To implement this feature, listen for the app module's [`activate`][activate]
|
||||
event, and call your existing `createWindow()` method if no BrowserWindows are open.
|
||||
|
||||
Because windows cannot be created before the `ready` event, you should only listen for
|
||||
`activate` events after your app is initialized. Do this by only listening for activate
|
||||
events inside your existing `whenReady()` callback.
|
||||
|
||||
```js
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## Final starter code
|
||||
|
||||
```fiddle docs/fiddles/tutorial-first-app
|
||||
|
||||
```
|
||||
|
||||
## Optional: Debugging from VS Code
|
||||
|
||||
If you want to debug your application using VS Code, you have need attach VS Code to
|
||||
both the main and renderer processes. Here is a sample configuration for you to
|
||||
run. Create a launch.json configuration in a new `.vscode` folder in your project:
|
||||
|
||||
```json title='.vscode/launch.json'
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"compounds": [
|
||||
{
|
||||
"name": "Main + renderer",
|
||||
"configurations": ["Main", "Renderer"],
|
||||
"stopAll": true
|
||||
}
|
||||
],
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Renderer",
|
||||
"port": 9222,
|
||||
"request": "attach",
|
||||
"type": "pwa-chrome",
|
||||
"webRoot": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "Main",
|
||||
"type": "pwa-node",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
|
||||
"windows": {
|
||||
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
|
||||
},
|
||||
"args": [".", "--remote-debugging-port=9222"],
|
||||
"outputCapture": "std",
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The "Main + renderer" option will appear when you select "Run and Debug"
|
||||
from the sidebar, allowing you to set breakpoints and inspect all the variables among
|
||||
other things in both the main and renderer processes.
|
||||
|
||||
What we have done in the `launch.json` file is to create 3 configurations:
|
||||
|
||||
- `Main` is used to start the main process and also expose port 9222 for remote debugging
|
||||
(`--remote-debugging-port=9222`). This is the port that we will use to attach the debugger
|
||||
for the `Renderer`. Because the main process is a Node.js process, the type is set to
|
||||
`pwa-node` (`pwa-` is the prefix that tells VS Code to use the latest JavaScript debugger).
|
||||
- `Renderer` is used to debug the renderer process. Because the main process is the one
|
||||
that creates the process, we have to "attach" to it (`"request": "attach"`) instead of
|
||||
creating a new one.
|
||||
The renderer process is a web one, so the debugger we have to use is `pwa-chrome`.
|
||||
- `Main + renderer` is a [compound task] that executes the previous ones simultaneously.
|
||||
|
||||
:::caution
|
||||
|
||||
Because we are attaching to a process in `Renderer`, it is possible that the first lines of
|
||||
your code will be skipped as the debugger will not have had enough time to connect before they are
|
||||
being executed.
|
||||
You can work around this by refreshing the page or setting a timeout before executing the code
|
||||
in development mode.
|
||||
|
||||
:::
|
||||
|
||||
:::info Further reading
|
||||
|
||||
If you want to dig deeper in the debugging area, the following guides provide more information:
|
||||
|
||||
- [Application Debugging]
|
||||
- [DevTools Extensions][devtools extension]
|
||||
|
||||
:::
|
||||
|
||||
## Summary
|
||||
|
||||
Electron applications are set up using npm packages. The Electron executable should be installed
|
||||
in your project's `devDependencies` and can be run in development mode using a script in your
|
||||
package.json file.
|
||||
|
||||
The executable runs the JavaScript entry point found in the `main` property of your package.json.
|
||||
This file controls Electron's **main process**, which runs an instance of Node.js and is
|
||||
responsible for your app's lifecycle, displaying native interfaces, performing privileged operations,
|
||||
and managing renderer processes.
|
||||
|
||||
**Renderer processes** (or renderers for short) are responsible for display graphical content. You can
|
||||
load a web page into a renderer by pointing it to either a web address or a local HTML file.
|
||||
Renderers behave very similarly to regular web pages and have access to the same web APIs.
|
||||
|
||||
In the next section of the tutorial, we will be learning how to augment the renderer process with
|
||||
privileged APIs and how to communicate between processes.
|
||||
|
||||
<!-- Links -->
|
||||
|
||||
[activate]: ../api/app.md#event-activate-macos
|
||||
[advanced-installation]: installation.md
|
||||
[app]: ../api/app.md
|
||||
[app-quit]: ../api/app.md#appquit
|
||||
[app-ready]: ../api/app.md#event-ready
|
||||
[app-when-ready]: ../api/app.md#appwhenready
|
||||
[application debugging]: ./application-debugging.md
|
||||
[browser-window]: ../api/browser-window.md
|
||||
[commonjs]: https://nodejs.org/docs/../api/modules.html#modules_modules_commonjs_modules
|
||||
[compound task]: https://code.visualstudio.com/Docs/editor/tasks#_compound-tasks
|
||||
[devtools extension]: ./devtools-extension.md
|
||||
[event emitters]: https://nodejs.org/api/events.html#events
|
||||
[gitignore]: https://git-scm.com/docs/gitignore
|
||||
[gitignore-template]: https://github.com/github/gitignore/blob/main/Node.gitignore
|
||||
[installation]: ./installation.md
|
||||
[node-platform]: https://nodejs.org/api/process.html#process_process_platform
|
||||
[package-json-main]: https://docs.npmjs.com/cli/v7/configuring-npm/package-json#main
|
||||
[package-scripts]: https://docs.npmjs.com/cli/v7/using-npm/scripts
|
||||
[process-model]: process-model.md
|
||||
[react]: https://reactjs.org
|
||||
[repl]: ./repl.md
|
||||
[sandbox]: ./sandbox.md
|
||||
[webpack]: https://webpack.js.org
|
||||
[window-all-closed]: ../api/app.md#event-window-all-closed
|
||||
[wsl]: https://docs.microsoft.com/en-us/windows/wsl/about#what-is-wsl-2
|
||||
|
||||
<!-- Tutorial links -->
|
||||
|
||||
[prerequisites]: tutorial-1-prerequisites.md
|
||||
[building your first app]: tutorial-2-first-app.md
|
||||
[preload]: tutorial-3-preload.md
|
||||
[features]: tutorial-4-adding-features.md
|
||||
[packaging]: tutorial-5-packaging.md
|
||||
[updates]: tutorial-6-publishing-updating.md
|
||||
271
docs/tutorial/tutorial-3-preload.md
Normal file
@@ -0,0 +1,271 @@
|
||||
---
|
||||
title: 'Using Preload Scripts'
|
||||
description: 'This guide will step you through the process of creating a barebones Hello World app in Electron, similar to electron/electron-quick-start.'
|
||||
slug: tutorial-preload
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
:::info Follow along the tutorial
|
||||
|
||||
This is **part 3** of the Electron tutorial.
|
||||
|
||||
1. [Prerequisites][prerequisites]
|
||||
1. [Building your First App][building your first app]
|
||||
1. **[Using Preload Scripts][preload]**
|
||||
1. [Adding Features][features]
|
||||
1. [Packaging Your Application][packaging]
|
||||
1. [Publishing and Updating][updates]
|
||||
|
||||
:::
|
||||
|
||||
## Learning goals
|
||||
|
||||
In this part of the tutorial, you will learn what a preload script is and how to use one
|
||||
to securely expose privileged APIs into the renderer process. You will also learn how to
|
||||
communicate between main and renderer processes with Electron's inter-process
|
||||
communication (IPC) modules.
|
||||
|
||||
## What is a preload script?
|
||||
|
||||
Electron's main process is a Node.js environment that has full operating system access.
|
||||
On top of [Electron modules][modules], you can also access [Node.js built-ins][node-api],
|
||||
as well as any packages installed via npm. On the other hand, renderer processes run web
|
||||
pages and do not run Node.js by default for security reasons.
|
||||
|
||||
To bridge Electron's different process types together, we will need to use a special script
|
||||
called a **preload**.
|
||||
|
||||
## Augmenting the renderer with a preload script
|
||||
|
||||
A BrowserWindow's preload script runs in a context that has access to both the HTML DOM
|
||||
and a Node.js environment. Preload scripts are injected before a web page loads in the renderer,
|
||||
similar to a Chrome extension's [content scripts][content-script]. To add features to your renderer
|
||||
that require privileged access, you can define [global] objects through the
|
||||
[contextBridge][contextbridge] API.
|
||||
|
||||
To demonstrate this concept, you will create a preload script that exposes your app's
|
||||
versions of Chrome, Node, and Electron into the renderer.
|
||||
|
||||
Add a new `preload.js` script that exposes selected properties of Electron's `process.versions`
|
||||
object to the renderer process in a `versions` global variable.
|
||||
|
||||
```js title="preload.js"
|
||||
const { contextBridge } = require('electron')
|
||||
|
||||
contextBridge.exposeInMainWorld('versions', {
|
||||
node: () => process.versions.node,
|
||||
chrome: () => process.versions.chrome,
|
||||
electron: () => process.versions.electron,
|
||||
// we can also expose variables, not just functions
|
||||
})
|
||||
```
|
||||
|
||||
To attach this script to your renderer process, pass its path to the
|
||||
`webPreferences.preload` option in the BrowserWindow constructor:
|
||||
|
||||
```js {8-10} title="main.js"
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js'),
|
||||
},
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
There are two Node.js concepts that are used here:
|
||||
|
||||
- The [`__dirname`][dirname] string points to the path of the currently executing script
|
||||
(in this case, your project's root folder).
|
||||
- The [`path.join`][path-join] API joins multiple path segments together, creating a
|
||||
combined path string that works across all platforms.
|
||||
|
||||
:::
|
||||
|
||||
At this point, the renderer has access to the `versions` global, so let's display that
|
||||
information in the window. This variable can be accessed via `window.versions` or simply
|
||||
`versions`. Create a `renderer.js` script that uses the [`document.getElementById`]
|
||||
DOM API to replace the displayed text for the HTML element with `info` as its `id` property.
|
||||
|
||||
```js title="renderer.js"
|
||||
const information = document.getElementById('info')
|
||||
information.innerText = `This app is using Chrome (v${versions.chrome()}), Node.js (v${versions.node()}), and Electron (v${versions.electron()})`
|
||||
```
|
||||
|
||||
Then, modify your `index.html` by adding a new element with `info` as its `id` property,
|
||||
and attach your `renderer.js` script:
|
||||
|
||||
```html {18,20} title="index.html"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="default-src 'self'; script-src 'self'"
|
||||
/>
|
||||
<meta
|
||||
http-equiv="X-Content-Security-Policy"
|
||||
content="default-src 'self'; script-src 'self'"
|
||||
/>
|
||||
<title>Hello from Electron renderer!</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello from Electron renderer!</h1>
|
||||
<p>👋</p>
|
||||
<p id="info"></p>
|
||||
</body>
|
||||
<script src="./renderer.js"></script>
|
||||
</html>
|
||||
```
|
||||
|
||||
After following the above steps, your app should look something like this:
|
||||
|
||||

|
||||
|
||||
And the code should look like this:
|
||||
|
||||
```fiddle docs/fiddles/tutorial-preload
|
||||
|
||||
```
|
||||
|
||||
## Communicating between processes
|
||||
|
||||
As we have mentioned above, Electron's main and renderer process have distinct responsibilities
|
||||
and are not interchangeable. This means it is not possible to access the Node.js APIs directly
|
||||
from the renderer process, nor the HTML Document Object Model (DOM) from the main process.
|
||||
|
||||
The solution for this problem is to use Electron's `ipcMain` and `ipcRenderer` modules for
|
||||
inter-process communication (IPC). To send a message from your web page to the main process,
|
||||
you can set up a main process handler with `ipcMain.handle` and
|
||||
then expose a function that calls `ipcRenderer.invoke` to trigger the handler in your preload script.
|
||||
|
||||
To illustrate, we will add a global function to the renderer called `ping()`
|
||||
that will return a string from the main process.
|
||||
|
||||
First, set up the `invoke` call in your preload script:
|
||||
|
||||
```js {1,7} title="preload.js"
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
|
||||
contextBridge.exposeInMainWorld('versions', {
|
||||
node: () => process.versions.node,
|
||||
chrome: () => process.versions.chrome,
|
||||
electron: () => process.versions.electron,
|
||||
ping: () => ipcRenderer.invoke('ping'),
|
||||
// we can also expose variables, not just functions
|
||||
})
|
||||
```
|
||||
|
||||
:::caution IPC security
|
||||
|
||||
Notice how we wrap the `ipcRenderer.invoke('ping')` call in a helper function rather
|
||||
than expose the `ipcRenderer` module directly via context bridge. You **never** want to
|
||||
directly expose the entire `ipcRenderer` module via preload. This would give your renderer
|
||||
the ability to send arbitrary IPC messages to the main process, which becomes a powerful
|
||||
attack vector for malicious code.
|
||||
|
||||
:::
|
||||
|
||||
Then, set up your `handle` listener in the main process. We do this _before_
|
||||
loading the HTML file so that the handler is guaranteed to be ready before
|
||||
you send out the `invoke` call from the renderer.
|
||||
|
||||
```js {1,11} title="main.js"
|
||||
const { ipcMain } = require('electron')
|
||||
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js'),
|
||||
},
|
||||
})
|
||||
ipcMain.handle('ping', () => 'pong')
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
```
|
||||
|
||||
Once you have the sender and receiver set up, you can now send messages from the renderer
|
||||
to the main process through the `'ping'` channel you just defined.
|
||||
|
||||
```js title='renderer.js'
|
||||
const func = async () => {
|
||||
const response = await window.versions.ping()
|
||||
console.log(response) // prints out 'pong'
|
||||
}
|
||||
|
||||
func()
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
For more in-depth explanations on using the `ipcRenderer` and `ipcMain` modules,
|
||||
check out the full [Inter-Process Communication][ipc] guide.
|
||||
|
||||
:::
|
||||
|
||||
## Summary
|
||||
|
||||
A preload script contains code that runs before your web page is loaded into the browser
|
||||
window. It has access to both DOM APIs and Node.js environment, and is often used to
|
||||
expose privileged APIs to the renderer via the `contextBridge` API.
|
||||
|
||||
Because the main and renderer processes have very different responsibilities, Electron
|
||||
apps often use the preload script to set up inter-process communication (IPC) interfaces
|
||||
to pass arbitrary messages between the two kinds of processes.
|
||||
|
||||
In the next part of the tutorial, we will be showing you resources on adding more
|
||||
functionality to your app, then teaching you distributing your app to users.
|
||||
|
||||
<!-- Links -->
|
||||
|
||||
[advanced-installation]: ./installation.md
|
||||
[application debugging]: ./application-debugging.md
|
||||
[app]: ../api/app.md
|
||||
[app-ready]: ../api/app.md#event-ready
|
||||
[app-when-ready]: ../api/app.md#appwhenready
|
||||
[browser-window]: ../api/browser-window.md
|
||||
[commonjs]: https://nodejs.org/docs/latest/api/modules.html#modules_modules_commonjs_modules
|
||||
[compound task]: https://code.visualstudio.com/Docs/editor/tasks#_compound-tasks
|
||||
[content-script]: https://developer.chrome.com/docs/extensions/mv3/content_scripts/
|
||||
[contextbridge]: ../api/context-bridge.md
|
||||
[context-isolation]: ./context-isolation.md
|
||||
[`document.getelementbyid`]: https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById
|
||||
[devtools-extension]: ./devtools-extension.md
|
||||
[dirname]: https://nodejs.org/api/modules.html#modules_dirname
|
||||
[global]: https://developer.mozilla.org/en-US/docs/Glossary/Global_object
|
||||
[ipc]: ./ipc.md
|
||||
[mdn-csp]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
|
||||
[modules]: ../api/app.md
|
||||
[node-api]: https://nodejs.org/dist/latest/docs/api/
|
||||
[package-json-main]: https://docs.npmjs.com/cli/v7/configuring-npm/package-json#main
|
||||
[package-scripts]: https://docs.npmjs.com/cli/v7/using-npm/scripts
|
||||
[path-join]: https://nodejs.org/api/path.html#path_path_join_paths
|
||||
[process-model]: ./process-model.md
|
||||
[react]: https://reactjs.org
|
||||
[sandbox]: ./sandbox.md
|
||||
[webpack]: https://webpack.js.org
|
||||
|
||||
<!-- Tutorial links -->
|
||||
|
||||
[prerequisites]: tutorial-1-prerequisites.md
|
||||
[building your first app]: tutorial-2-first-app.md
|
||||
[preload]: tutorial-3-preload.md
|
||||
[features]: tutorial-4-adding-features.md
|
||||
[packaging]: tutorial-5-packaging.md
|
||||
[updates]: tutorial-6-publishing-updating.md
|
||||
77
docs/tutorial/tutorial-4-adding-features.md
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
title: 'Adding Features'
|
||||
description: 'In this step of the tutorial, we will share some resources you should read to add features to your application'
|
||||
slug: tutorial-adding-features
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
:::info Follow along the tutorial
|
||||
|
||||
This is **part 4** of the Electron tutorial.
|
||||
|
||||
1. [Prerequisites][prerequisites]
|
||||
1. [Building your First App][building your first app]
|
||||
1. [Using Preload Scripts][preload]
|
||||
1. **[Adding Features][features]**
|
||||
1. [Packaging Your Application][packaging]
|
||||
1. [Publishing and Updating][updates]
|
||||
|
||||
:::
|
||||
|
||||
## Adding application complexity
|
||||
|
||||
If you have been following along, you should have a functional Electron application
|
||||
with a static user interface. From this starting point, you can generally progress
|
||||
in developing your app in two broad directions:
|
||||
|
||||
1. Adding complexity to your renderer process' web app code
|
||||
1. Deeper integrations with the operating system and Node.js
|
||||
|
||||
It is important to understand the distinction between these two broad concepts. For the
|
||||
first point, Electron-specific resources are not necessary. Building a pretty to-do
|
||||
list in Electron is just pointing your Electron BrowserWindow to a pretty
|
||||
to-do list web app. Ultimately, you are building your renderer's UI using the same tools
|
||||
(HTML, CSS, JavaScript) that you would on the web. Therefore, Electron's docs will
|
||||
not go in-depth on how to use standard web tools.
|
||||
|
||||
On the other hand, Electron also provides a rich set of tools that allow
|
||||
you to integrate with the desktop environment, from creating tray icons to adding
|
||||
global shortcuts to displaying native menus. It also gives you all the power of a
|
||||
Node.js environment in the main process. This set of capabilities separates
|
||||
Electron applications from running a website in a browser tab, and are the
|
||||
focus of Electron's documentation.
|
||||
|
||||
## How-to examples
|
||||
|
||||
Electron's documentation has many tutorials to help you with more advanced topics
|
||||
and deeper operating system integrations. To get started, check out the
|
||||
[How-To Examples][how-to] doc.
|
||||
|
||||
:::note Let us know if something is missing!
|
||||
|
||||
If you can't find what you are looking for, please let us know on [GitHub] or in
|
||||
our [Discord server][discord]!
|
||||
|
||||
:::
|
||||
|
||||
## What's next?
|
||||
|
||||
For the rest of the tutorial, we will be shifting away from application code
|
||||
and giving you a look at how you can get your app from your developer machine
|
||||
into end users' hands.
|
||||
|
||||
<!-- Link labels -->
|
||||
|
||||
[discord]: https://discord.gg/electronjs
|
||||
[github]: https://github.com/electron/electronjs.org-new/issues/new
|
||||
[how to]: ./examples.md
|
||||
[node-platform]: https://nodejs.org/api/process.html#process_process_platform
|
||||
|
||||
<!-- Tutorial links -->
|
||||
|
||||
[prerequisites]: tutorial-1-prerequisites.md
|
||||
[building your first app]: tutorial-2-first-app.md
|
||||
[preload]: tutorial-3-preload.md
|
||||
[features]: tutorial-4-adding-features.md
|
||||
[packaging]: tutorial-5-packaging.md
|
||||
[updates]: tutorial-6-publishing-updating.md
|
||||