mirror of
https://github.com/taigrr/wails.git
synced 2026-04-03 05:38:56 -07:00
Compare commits
164 Commits
v2.0.0-bet
...
linux-dial
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b296fbbb99 | ||
|
|
26c4f112e3 | ||
|
|
f338dff171 | ||
|
|
3c6ed12637 | ||
|
|
e2f3a11a33 | ||
|
|
0571deb290 | ||
|
|
451b357e40 | ||
|
|
84b67a8f53 | ||
|
|
448cf731bb | ||
|
|
9cb480f0f0 | ||
|
|
6825a631f5 | ||
|
|
39f91a030f | ||
|
|
202e4d5be8 | ||
|
|
045e58778a | ||
|
|
e375d60c67 | ||
|
|
fcb5499d3a | ||
|
|
dd5a54a8e0 | ||
|
|
9f24a46b8a | ||
|
|
d7eaab97dd | ||
|
|
a03d1e5ac5 | ||
|
|
d5d4d88481 | ||
|
|
1c823b09c4 | ||
|
|
e5732bcee1 | ||
|
|
c0f283335a | ||
|
|
64cdf64751 | ||
|
|
609bfc35c0 | ||
|
|
121d11db55 | ||
|
|
5c357f012d | ||
|
|
56285f8637 | ||
|
|
b61158d329 | ||
|
|
0233197073 | ||
|
|
d883397d75 | ||
|
|
5bd82c4637 | ||
|
|
e942867635 | ||
|
|
29749ed7cb | ||
|
|
0288f33556 | ||
|
|
ddeac08991 | ||
|
|
30e12d681c | ||
|
|
f9fce9f2a7 | ||
|
|
9c5bb8c6eb | ||
|
|
f2ab409284 | ||
|
|
7c190810fd | ||
|
|
2b2cd21674 | ||
|
|
f025234c85 | ||
|
|
44035637f7 | ||
|
|
008a5c70b9 | ||
|
|
24eaef1604 | ||
|
|
62adcab722 | ||
|
|
e12b630dfb | ||
|
|
81b3ecb056 | ||
|
|
b4d14644ee | ||
|
|
69fd584c32 | ||
|
|
3444ec50a7 | ||
|
|
02d4c65e01 | ||
|
|
efdcfe9985 | ||
|
|
5884b7a87c | ||
|
|
7229446ce7 | ||
|
|
c355d63768 | ||
|
|
eb0030adeb | ||
|
|
fe224d9ecd | ||
|
|
a98d55db58 | ||
|
|
f034163da5 | ||
|
|
d8fe011509 | ||
|
|
e7bb3b3e83 | ||
|
|
3201206d4f | ||
|
|
69c14d2a5d | ||
|
|
778cbe04d9 | ||
|
|
131a8f421d | ||
|
|
6fcd4b7bd4 | ||
|
|
f3b2f6ab76 | ||
|
|
b556e860c4 | ||
|
|
eb01a005dc | ||
|
|
6dcee51940 | ||
|
|
4c7a53b72b | ||
|
|
73c9fba731 | ||
|
|
0726ae9e83 | ||
|
|
9ba4ca10ca | ||
|
|
38caa645e5 | ||
|
|
41507e966a | ||
|
|
3092f04bcf | ||
|
|
ffc0765a2f | ||
|
|
ac803aa426 | ||
|
|
92b63d9fad | ||
|
|
fda3323386 | ||
|
|
b7a4aba5f3 | ||
|
|
7848a028e3 | ||
|
|
d827aafe89 | ||
|
|
db8094cd68 | ||
|
|
59d29dc12f | ||
|
|
7aad934dae | ||
|
|
0b1e33748a | ||
|
|
97be694d2a | ||
|
|
576e574399 | ||
|
|
6d9a195830 | ||
|
|
8107a8bd1e | ||
|
|
47d783291d | ||
|
|
0295f8dee2 | ||
|
|
d915f73c6c | ||
|
|
187bf3085c | ||
|
|
a353a653d1 | ||
|
|
155f1fde49 | ||
|
|
ec1a535acb | ||
|
|
fb5bcdc364 | ||
|
|
e6f42247e7 | ||
|
|
4bc0b30231 | ||
|
|
1cd2645b87 | ||
|
|
7904d0aadc | ||
|
|
06fa6850a1 | ||
|
|
485f5831ac | ||
|
|
587bcd8e21 | ||
|
|
d43b7b1882 | ||
|
|
ca147143ad | ||
|
|
3371967dad | ||
|
|
b09825ab0f | ||
|
|
5edf45468c | ||
|
|
507e8d5222 | ||
|
|
b9283009df | ||
|
|
60ddaf449d | ||
|
|
5bad81e182 | ||
|
|
2e15f22621 | ||
|
|
6a3a822640 | ||
|
|
e5057e1627 | ||
|
|
0a8f720586 | ||
|
|
5dbfb447b1 | ||
|
|
1f21dfbcfd | ||
|
|
53481830a9 | ||
|
|
7eb8e6456e | ||
|
|
5f0352404b | ||
|
|
b036b8c547 | ||
|
|
39ca977b18 | ||
|
|
abc078fb1b | ||
|
|
166490845c | ||
|
|
c2399e3620 | ||
|
|
a2890b6d0d | ||
|
|
a1dee989c7 | ||
|
|
6ff1dac925 | ||
|
|
0b011929bf | ||
|
|
be3d1ff9e1 | ||
|
|
9c73b7285f | ||
|
|
810793aba7 | ||
|
|
ef8d7d2fd7 | ||
|
|
ae341be638 | ||
|
|
dcef8679d2 | ||
|
|
0bb09a53ea | ||
|
|
deb1156916 | ||
|
|
1d87a81f63 | ||
|
|
8ef8b2528b | ||
|
|
f05109232e | ||
|
|
cf1001bffc | ||
|
|
7bf2218c36 | ||
|
|
48c9879bc4 | ||
|
|
2fe5e5ed01 | ||
|
|
38fd09bd9a | ||
|
|
4c5a81782b | ||
|
|
ace3122e07 | ||
|
|
f5c35487d9 | ||
|
|
06df0e1ee4 | ||
|
|
865d118651 | ||
|
|
6ea6bfeed0 | ||
|
|
48527eb90a | ||
|
|
33d8f98da9 | ||
|
|
658a30d16a | ||
|
|
0189d1cb55 | ||
|
|
8df94fa02b |
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -8,7 +8,7 @@ assignees: ''
|
||||
---
|
||||
|
||||
#####################################################
|
||||
**If you have a technical issue, please do not open a bug this way!**
|
||||
**V1 users: If you have a technical issue, please do not open a bug this way!**
|
||||
Please use the `wails issue` command!
|
||||
If you do not do this then the issue may be closed automatically.
|
||||
|
||||
@@ -33,7 +33,7 @@ A clear and concise description of what you expected to happen.
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**System Details**
|
||||
Please provide your platform, GO version and variables, etc
|
||||
V2 users: Please add the output of `wails doctor`.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
81
README.md
81
README.md
@@ -1,17 +1,35 @@
|
||||
<p align="center" style="text-align: center">
|
||||
<img src="logo.png" width="55%"><br/>
|
||||
<img src="logo.png" width="55%"><br/>
|
||||
</p>
|
||||
<p align="center">
|
||||
Build desktop applications using Go & Web Technologies.<br/><br/>
|
||||
<a href="https://github.com/wailsapp/wails/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg"></a>
|
||||
<a href="https://goreportcard.com/report/github.com/wailsapp/wails"><img src="https://goreportcard.com/badge/github.com/wailsapp/wails"/></a>
|
||||
<a href="http://godoc.org/github.com/wailsapp/wails"><img src="https://img.shields.io/badge/godoc-reference-blue.svg"/></a>
|
||||
<a href="https://www.codefactor.io/repository/github/wailsapp/wails"><img src="https://www.codefactor.io/repository/github/wailsapp/wails/badge" alt="CodeFactor" /></a>
|
||||
<a href="https://github.com/wailsapp/wails/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="CodeFactor" /></a>
|
||||
<a href="https://app.fossa.io/projects/git%2Bgithub.com%2Fwailsapp%2Fwails?ref=badge_shield" alt="FOSSA Status"><img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwailsapp%2Fwails.svg?type=shield"/></a>
|
||||
<a href="https://houndci.com"><img src="https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg"/></a>
|
||||
<a href="https://github.com/avelino/awesome-go" rel="nofollow"><img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome"></a>
|
||||
<a href="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" rel="nofollow"><img src="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" alt="Release Pipelines"></a>
|
||||
Build desktop applications using Go & Web Technologies.<br/><br/>
|
||||
<a href="https://github.com/wailsapp/wails/blob/master/LICENSE">
|
||||
<img src="https://img.shields.io/badge/License-MIT-blue.svg">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/wailsapp/wails">
|
||||
<img src="https://goreportcard.com/badge/github.com/wailsapp/wails"/>
|
||||
</a>
|
||||
<a href="http://godoc.org/github.com/wailsapp/wails">
|
||||
<img src="https://img.shields.io/badge/godoc-reference-blue.svg"/>
|
||||
</a>
|
||||
<a href="https://www.codefactor.io/repository/github/wailsapp/wails">
|
||||
<img src="https://www.codefactor.io/repository/github/wailsapp/wails/badge" alt="CodeFactor" />
|
||||
</a>
|
||||
<a href="https://github.com/wailsapp/wails/issues">
|
||||
<img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="CodeFactor" />
|
||||
</a>
|
||||
<a href="https://app.fossa.io/projects/git%2Bgithub.com%2Fwailsapp%2Fwails?ref=badge_shield" alt="FOSSA Status">
|
||||
<img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwailsapp%2Fwails.svg?type=shield"/>
|
||||
</a>
|
||||
<a href="https://houndci.com">
|
||||
<img src="https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg"/>
|
||||
</a>
|
||||
<a href="https://github.com/avelino/awesome-go" rel="nofollow">
|
||||
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome"/>
|
||||
</a>
|
||||
<a href="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" rel="nofollow">
|
||||
<img src="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" alt="Release Pipelines"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<span id="nav-1"></span>
|
||||
@@ -88,6 +106,13 @@ Click [here](https://wails.io) if you are interested in trying out v2 Beta for W
|
||||
|
||||
This project is supported by these kind people / companies:
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.easywebadv.it/" style="width:150px;">
|
||||
<img src="website/static/img/easyweb.png" width="150"/>
|
||||
</a>
|
||||
</p>
|
||||
<br/>
|
||||
<br/>
|
||||
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
|
||||
<img src="sponsors/silver%20sponsor.png" width="100"/>
|
||||
</a>
|
||||
@@ -114,7 +139,7 @@ This project is supported by these kind people / companies:
|
||||
<img src="https://github.com/matryer.png" width="100"/>
|
||||
</a>
|
||||
<a href="https://www.jetbrains.com?from=Wails" style="width:100px">
|
||||
<img src="/img/jetbrains-grayscale.png" width="100"/>
|
||||
<img src="/assets/images/jetbrains-grayscale.png" width="100"/>
|
||||
</a>
|
||||
<a href="https://github.com/tc-hib" style="width:55px">
|
||||
<img src="https://github.com/tc-hib.png?size=55" width="55"/>
|
||||
@@ -158,15 +183,27 @@ This project is supported by these kind people / companies:
|
||||
<a href="https://github.com/ilgityildirim" style="width:50px">
|
||||
<img src="https://github.com/ilgityildirim.png?size=50" width="50"/>
|
||||
</a>
|
||||
<a href="https://github.com/ondoki" style="width:65px">
|
||||
<img src="https://github.com/ondoki.png?size=65" width="65"/>
|
||||
</a>
|
||||
<a href="https://github.com/questrail" style="width:50px">
|
||||
<img src="https://github.com/questrail.png?size=50" width="50"/>
|
||||
</a>
|
||||
<a href="https://github.com/DonTomato" style="width:45px">
|
||||
<img src="https://github.com/DonTomato.png?size=45" width="45"/>
|
||||
</a>
|
||||
<a href="https://github.com/taigrr" style="width:45px">
|
||||
<img src="https://github.com/taigrr.png?size=45" width="45"/>
|
||||
</a>
|
||||
<a href="https://github.com/charlie-dee" style="width:55px">
|
||||
<img src="https://github.com/charlie-dee.png?size=55" width="55"/>
|
||||
</a>
|
||||
<a href="https://github.com/EdenNetworkItalia" style="width:65px">
|
||||
<img src="https://github.com/EdenNetworkItalia.png?size=65" width="65"/>
|
||||
</a>
|
||||
<a href="https://github.com/michaelolson1996" style="width:55px">
|
||||
<img src="https://github.com/michaelolson1996.png?size=55" width="55"/>
|
||||
</a>
|
||||
<a href="https://github.com/GargantuaX" style="width:45px">
|
||||
<img src="https://github.com/GargantuaX.png?size=45" width="45"/>
|
||||
</a>
|
||||
|
||||
<span id="nav-6"></span>
|
||||
|
||||
@@ -330,11 +367,11 @@ It is recommended at this stage to read the comprehensive documentation at [http
|
||||
<a href="https://github.com/SophieAu"><img src="https://github.com/SophieAu.png?size=40" width="40"/></a>
|
||||
<a href="https://github.com/alexmat"><img src="https://github.com/alexmat.png?size=40" width="40"/></a>
|
||||
<a href="https://github.com/RH12503"><img src="https://github.com/RH12503.png?size=40" width="40"/></a>
|
||||
<a href="https://github.com/hi019"><img src="https://github.com/hi019.png?size=40" width="40"/></a></a>
|
||||
<a href="https://github.com/Igogrek"><img src="https://github.com/Igogrek.png?size=40" width="40"/></a></a>
|
||||
<a href="https://github.com/aschey"><img src="https://github.com/aschey.png?size=40" width="40"/></a></a>
|
||||
<a href="https://github.com/akhudek"><img src="https://github.com/akhudek.png?size=40" width="40"/></a></a>
|
||||
<a href="https://github.com/s12chung"><img src="https://github.com/s12chung.png?size=40" width="40"/></a></a>
|
||||
<a href="https://github.com/hi019"><img src="https://github.com/hi019.png?size=40" width="40"/></a>
|
||||
<a href="https://github.com/Igogrek"><img src="https://github.com/Igogrek.png?size=40" width="40"/></a>
|
||||
<a href="https://github.com/aschey"><img src="https://github.com/aschey.png?size=40" width="40"/></a>
|
||||
<a href="https://github.com/akhudek"><img src="https://github.com/akhudek.png?size=40" width="40"/></a>
|
||||
<a href="https://github.com/s12chung"><img src="https://github.com/s12chung.png?size=40" width="40"/></a>
|
||||
|
||||
<span id="nav-10"></span>
|
||||
|
||||
@@ -370,7 +407,7 @@ This project was mainly coded to the following albums:
|
||||
## Special Thanks
|
||||
|
||||
<p align="center" style="text-align: center">
|
||||
<a href="https://pace.dev"><img src="pace.jpeg"/></a><br/>
|
||||
<a href="https://pace.dev"><img src="/assets/images/pace.jpeg"/></a><br/>
|
||||
A <i>huge</i> thanks to <a href="https://pace.dev">Pace</a> for sponsoring the project and helping the efforts to get Wails ported to Apple Silicon!<br/><br/>
|
||||
If you are looking for a Project Management tool that's powerful but quick and easy to use, check them out!<br/><br/>
|
||||
</p>
|
||||
@@ -378,5 +415,5 @@ This project was mainly coded to the following albums:
|
||||
<p align="center" style="text-align: center">
|
||||
A special thank you to JetBrains for donating licenses to us!<br/><br/>
|
||||
Please click the logo to let them know your appreciation!<br/><br/>
|
||||
<a href="https://www.jetbrains.com?from=Wails"><img src="jetbrains-grayscale.png" width="30%"></a>
|
||||
<a href="https://www.jetbrains.com?from=Wails"><img src="/assets/images/jetbrains-grayscale.png" width="30%"></a>
|
||||
</p>
|
||||
|
||||
@@ -2,16 +2,34 @@
|
||||
<img src="logo.png" width="55%"><br/>
|
||||
</p>
|
||||
<p align="center">
|
||||
使用 Go 和 Web 技术构建桌面应用程序。<br/><br/>
|
||||
<a href="https://github.com/wailsapp/wails/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg"></a>
|
||||
<a href="https://goreportcard.com/report/github.com/wailsapp/wails"><img src="https://goreportcard.com/badge/github.com/wailsapp/wails"/></a>
|
||||
<a href="http://godoc.org/github.com/wailsapp/wails"><img src="https://img.shields.io/badge/godoc-reference-blue.svg"/></a>
|
||||
<a href="https://www.codefactor.io/repository/github/wailsapp/wails"><img src="https://www.codefactor.io/repository/github/wailsapp/wails/badge" alt="CodeFactor" /></a>
|
||||
<a href="https://github.com/wailsapp/wails/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="CodeFactor" /></a>
|
||||
<a href="https://app.fossa.io/projects/git%2Bgithub.com%2Fwailsapp%2Fwails?ref=badge_shield" alt="FOSSA Status"><img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwailsapp%2Fwails.svg?type=shield"/></a>
|
||||
<a href="https://houndci.com"><img src="https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg"/></a>
|
||||
<a href="https://github.com/avelino/awesome-go" rel="nofollow"><img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome"></a>
|
||||
<a href="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" rel="nofollow"><img src="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" alt="Release Pipelines"></a>
|
||||
使用 Go 和 Web 技术构建桌面应用程序。<br/><br/>
|
||||
<a href="https://github.com/wailsapp/wails/blob/master/LICENSE">
|
||||
<img src="https://img.shields.io/badge/License-MIT-blue.svg">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/wailsapp/wails">
|
||||
<img src="https://goreportcard.com/badge/github.com/wailsapp/wails"/>
|
||||
</a>
|
||||
<a href="http://godoc.org/github.com/wailsapp/wails">
|
||||
<img src="https://img.shields.io/badge/godoc-reference-blue.svg"/>
|
||||
</a>
|
||||
<a href="https://www.codefactor.io/repository/github/wailsapp/wails">
|
||||
<img src="https://www.codefactor.io/repository/github/wailsapp/wails/badge" alt="CodeFactor" />
|
||||
</a>
|
||||
<a href="https://github.com/wailsapp/wails/issues">
|
||||
<img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="CodeFactor" />
|
||||
</a>
|
||||
<a href="https://app.fossa.io/projects/git%2Bgithub.com%2Fwailsapp%2Fwails?ref=badge_shield" alt="FOSSA Status">
|
||||
<img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwailsapp%2Fwails.svg?type=shield"/>
|
||||
</a>
|
||||
<a href="https://houndci.com">
|
||||
<img src="https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg"/>
|
||||
</a>
|
||||
<a href="https://github.com/avelino/awesome-go" rel="nofollow">
|
||||
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome"/>
|
||||
</a>
|
||||
<a href="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" rel="nofollow">
|
||||
<img src="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" alt="Release Pipelines"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<span id="nav-1"></span>
|
||||
@@ -91,6 +109,13 @@
|
||||
|
||||
这个项目由以下这些人或者公司支持:
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.easywebadv.it/" style="width:100px;">
|
||||
<img src="website/static/img/easyweb.png" width="120"/>
|
||||
</a>
|
||||
</p>
|
||||
<br/>
|
||||
<br/>
|
||||
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
|
||||
<img src="sponsors/silver%20sponsor.png" width="100"/>
|
||||
</a>
|
||||
@@ -117,7 +142,7 @@
|
||||
<img src="https://github.com/matryer.png" width="100"/>
|
||||
</a>
|
||||
<a href="https://www.jetbrains.com?from=Wails" style="width:100px">
|
||||
<img src="/img/jetbrains-grayscale.png" width="100"/>
|
||||
<img src="/assets/images/jetbrains-grayscale.png" width="100"/>
|
||||
</a>
|
||||
<a href="https://github.com/tc-hib" style="width:55px">
|
||||
<img src="https://github.com/tc-hib.png?size=55" width="55"/>
|
||||
@@ -161,15 +186,27 @@
|
||||
<a href="https://github.com/ilgityildirim" style="width:50px">
|
||||
<img src="https://github.com/ilgityildirim.png?size=50" width="50"/>
|
||||
</a>
|
||||
<a href="https://github.com/ondoki" style="width:65px">
|
||||
<img src="https://github.com/ondoki.png?size=65" width="65"/>
|
||||
</a>
|
||||
<a href="https://github.com/questrail" style="width:50px">
|
||||
<img src="https://github.com/questrail.png?size=50" width="50"/>
|
||||
</a>
|
||||
<a href="https://github.com/DonTomato" style="width:45px">
|
||||
<img src="https://github.com/DonTomato.png?size=45" width="45"/>
|
||||
</a>
|
||||
<a href="https://github.com/taigrr" style="width:45px">
|
||||
<img src="https://github.com/taigrr.png?size=45" width="45"/>
|
||||
</a>
|
||||
<a href="https://github.com/charlie-dee" style="width:55px">
|
||||
<img src="https://github.com/charlie-dee.png?size=55" width="55"/>
|
||||
</a>
|
||||
<a href="https://github.com/EdenNetworkItalia" style="width:65px">
|
||||
<img src="https://github.com/EdenNetworkItalia.png?size=65" width="65"/>
|
||||
</a>
|
||||
<a href="https://github.com/michaelolson1996" style="width:55px">
|
||||
<img src="https://github.com/michaelolson1996.png?size=55" width="55"/>
|
||||
</a>
|
||||
<a href="https://github.com/GargantuaX" style="width:45px">
|
||||
<img src="https://github.com/GargantuaX.png?size=45" width="45"/>
|
||||
</a>
|
||||
|
||||
<span id="nav-6"></span>
|
||||
|
||||
@@ -326,11 +363,11 @@ go get -u github.com/wailsapp/wails/cmd/wails
|
||||
<a href="https://github.com/SophieAu"><img src="https://github.com/SophieAu.png?size=40" width="40"/></a>
|
||||
<a href="https://github.com/alexmat"><img src="https://github.com/alexmat.png?size=40" width="40"/></a>
|
||||
<a href="https://github.com/RH12503"><img src="https://github.com/RH12503.png?size=40" width="40"/></a>
|
||||
<a href="https://github.com/hi019"><img src="https://github.com/hi019.png?size=40" width="40"/></a></a>
|
||||
<a href="https://github.com/Igogrek"><img src="https://github.com/Igogrek.png?size=40" width="40"/></a></a>
|
||||
<a href="https://github.com/aschey"><img src="https://github.com/aschey.png?size=40" width="40"/></a></a>
|
||||
<a href="https://github.com/akhudek"><img src="https://github.com/akhudek.png?size=40" width="40"/></a></a>
|
||||
<a href="https://github.com/s12chung"><img src="https://github.com/s12chung.png?size=40" width="40"/></a></a>
|
||||
<a href="https://github.com/hi019"><img src="https://github.com/hi019.png?size=40" width="40"/></a>
|
||||
<a href="https://github.com/Igogrek"><img src="https://github.com/Igogrek.png?size=40" width="40"/></a>
|
||||
<a href="https://github.com/aschey"><img src="https://github.com/aschey.png?size=40" width="40"/></a>
|
||||
<a href="https://github.com/akhudek"><img src="https://github.com/akhudek.png?size=40" width="40"/></a>
|
||||
<a href="https://github.com/s12chung"><img src="https://github.com/s12chung.png?size=40" width="40"/></a>
|
||||
|
||||
<span id="nav-10"></span>
|
||||
|
||||
@@ -363,7 +400,7 @@ go get -u github.com/wailsapp/wails/cmd/wails
|
||||
## 特别感谢
|
||||
|
||||
<p align="center" style="text-align: center">
|
||||
<a href="https://pace.dev"><img src="pace.jpeg"/></a><br/>
|
||||
<a href="https://pace.dev"><img src="/assets/images/pace.jpeg"/></a><br/>
|
||||
<i>非常</i> 感谢<a href="https://pace.dev">Pace</a>对项目的赞助,并帮助将 Wails 移植到 Apple Silicon !<br/><br/>
|
||||
如果您正在寻找一个强大并且快速和易于使用的项目管理工具,可以看看他们!<br/><br/>
|
||||
</p>
|
||||
@@ -371,5 +408,5 @@ go get -u github.com/wailsapp/wails/cmd/wails
|
||||
<p align="center" style="text-align: center">
|
||||
特别感谢 JetBrains 向我们捐赠许可!<br/><br/>
|
||||
请点击 logo 让他们知道你的感激之情!<br/><br/>
|
||||
<a href="https://www.jetbrains.com?from=Wails"><img src="jetbrains-grayscale.png" width="30%"></a>
|
||||
<a href="https://www.jetbrains.com?from=Wails"><img src="/assets/images/jetbrains-grayscale.png" width="30%"></a>
|
||||
</p>
|
||||
|
||||
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
21
cmd/fs.go
21
cmd/fs.go
@@ -6,7 +6,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
@@ -50,7 +49,7 @@ func (fs *FSHelper) FileExists(path string) bool {
|
||||
|
||||
// FindFile returns the first occurrence of match inside path.
|
||||
func (fs *FSHelper) FindFile(path, match string) (string, error) {
|
||||
files, err := ioutil.ReadDir(path)
|
||||
files, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -69,7 +68,7 @@ func (fs *FSHelper) FindFile(path, match string) (string, error) {
|
||||
func (fs *FSHelper) CreateFile(filename string, data []byte) error {
|
||||
// Ensure directory exists
|
||||
fs.MkDirs(filepath.Dir(filename))
|
||||
return ioutil.WriteFile(filename, data, 0644)
|
||||
return os.WriteFile(filename, data, 0644)
|
||||
}
|
||||
|
||||
// MkDirs creates the given nested directories.
|
||||
@@ -149,21 +148,11 @@ func (fs *FSHelper) LocalDir(dir string) (*Dir, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
// LoadRelativeFile loads the given file relative to the caller's directory
|
||||
func (fs *FSHelper) LoadRelativeFile(relativePath string) ([]byte, error) {
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
fullPath, err := filepath.Abs(filepath.Join(path.Dir(filename), relativePath))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ioutil.ReadFile(fullPath)
|
||||
}
|
||||
|
||||
// GetSubdirs will return a list of FQPs to subdirectories in the given directory
|
||||
func (d *Dir) GetSubdirs() (map[string]string, error) {
|
||||
|
||||
// Read in the directory information
|
||||
fileInfo, err := ioutil.ReadDir(d.fullPath)
|
||||
fileInfo, err := os.ReadDir(d.fullPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -215,7 +204,7 @@ func (fs *FSHelper) SaveAsJSON(data interface{}, filename string) error {
|
||||
e.SetIndent("", " ")
|
||||
e.Encode(data)
|
||||
|
||||
err := ioutil.WriteFile(filename, buf.Bytes(), 0755)
|
||||
err := os.WriteFile(filename, buf.Bytes(), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -231,7 +220,7 @@ func (fs *FSHelper) LoadAsString(filename string) (string, error) {
|
||||
|
||||
// LoadAsBytes returns the contents of the file as a byte slice
|
||||
func (fs *FSHelper) LoadAsBytes(filename string) ([]byte, error) {
|
||||
return ioutil.ReadFile(filename)
|
||||
return os.ReadFile(filename)
|
||||
}
|
||||
|
||||
// FileMD5 returns the md5sum of the given file
|
||||
|
||||
@@ -3,7 +3,7 @@ package cmd
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"sort"
|
||||
)
|
||||
@@ -28,7 +28,7 @@ func (g *GitHubHelper) GetVersionTags() ([]*SemanticVersion, error) {
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"runtime"
|
||||
@@ -75,7 +74,6 @@ const (
|
||||
NixOS
|
||||
// Artix linux distribution
|
||||
ArtixLinux
|
||||
|
||||
)
|
||||
|
||||
// DistroInfo contains all the information relating to a linux distribution
|
||||
@@ -96,7 +94,7 @@ func GetLinuxDistroInfo() *DistroInfo {
|
||||
}
|
||||
_, err := os.Stat("/etc/os-release")
|
||||
if !os.IsNotExist(err) {
|
||||
osRelease, _ := ioutil.ReadFile("/etc/os-release")
|
||||
osRelease, _ := os.ReadFile("/etc/os-release")
|
||||
result = parseOsRelease(string(osRelease))
|
||||
}
|
||||
return result
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"log"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
//go:embed linuxdb.yaml
|
||||
var LinuxDBYaml []byte
|
||||
|
||||
// LinuxDB is the database for linux distribution data.
|
||||
type LinuxDB struct {
|
||||
Distributions map[string]*Distribution `yaml:"distributions"`
|
||||
@@ -78,14 +82,10 @@ func (l *LinuxDB) GetDistro(distro string) *Distribution {
|
||||
// NewLinuxDB creates a new LinuxDB instance from the bundled
|
||||
// linuxdb.yaml file.
|
||||
func NewLinuxDB() *LinuxDB {
|
||||
data, err := fs.LoadRelativeFile("./linuxdb.yaml")
|
||||
if err != nil {
|
||||
log.Fatal("Could not load linuxdb.yaml")
|
||||
}
|
||||
result := LinuxDB{
|
||||
Distributions: make(map[string]*Distribution),
|
||||
}
|
||||
err = result.ImportData(data)
|
||||
err := result.ImportData(LinuxDBYaml)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/png"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -244,7 +243,7 @@ func (b *PackageHelper) packageOSX(po *ProjectOptions) error {
|
||||
// No - create a new plist from our defaults
|
||||
tmpl := template.New("infoPlist")
|
||||
plistFile := filepath.Join(b.getPackageFileBaseDir(), "info.plist")
|
||||
infoPlist, err := ioutil.ReadFile(plistFile)
|
||||
infoPlist, err := os.ReadFile(plistFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -258,13 +257,13 @@ func (b *PackageHelper) packageOSX(po *ProjectOptions) error {
|
||||
}
|
||||
|
||||
// Save to the package
|
||||
err = ioutil.WriteFile(plistFilename, tpl.Bytes(), 0644)
|
||||
err = os.WriteFile(plistFilename, tpl.Bytes(), 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Also write to project directory for customisation
|
||||
err = ioutil.WriteFile(customPlist, tpl.Bytes(), 0644)
|
||||
err = os.WriteFile(customPlist, tpl.Bytes(), 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -314,10 +313,12 @@ func (b *PackageHelper) PackageWindows(po *ProjectOptions, cleanUp bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate icon from PNG
|
||||
err = generateWindowsIcon(icon, basename+".ico")
|
||||
if err != nil {
|
||||
return err
|
||||
// Generate icon from PNG if it doesn't exist
|
||||
if !fs.FileExists(basename + ".ico") {
|
||||
err = generateWindowsIcon(icon, basename+".ico")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Copy manifest
|
||||
@@ -334,12 +335,12 @@ func (b *PackageHelper) PackageWindows(po *ProjectOptions, cleanUp bool) error {
|
||||
tgtRCFile := filepath.Join(outputDir, basename+".rc")
|
||||
if !b.fs.FileExists(tgtRCFile) {
|
||||
srcRCfile := filepath.Join(b.getPackageFileBaseDir(), "wails.rc")
|
||||
rcfilebytes, err := ioutil.ReadFile(srcRCfile)
|
||||
rcfilebytes, err := os.ReadFile(srcRCfile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rcfiledata := strings.Replace(string(rcfilebytes), "$NAME$", basename, -1)
|
||||
err = ioutil.WriteFile(tgtRCFile, []byte(rcfiledata), 0755)
|
||||
err = os.WriteFile(tgtRCFile, []byte(rcfiledata), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -387,11 +388,11 @@ func (b *PackageHelper) copyIcon() (string, error) {
|
||||
|
||||
// Install default icon
|
||||
iconfile := filepath.Join(b.getPackageFileBaseDir(), "icon.png")
|
||||
iconData, err := ioutil.ReadFile(iconfile)
|
||||
iconData, err := os.ReadFile(iconfile)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = ioutil.WriteFile(srcIcon, iconData, 0644)
|
||||
err = os.WriteFile(srcIcon, iconData, 0644)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package cmd
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@@ -310,14 +309,14 @@ func (po *ProjectOptions) WriteProjectConfig() error {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(targetFile, filedata, 0600)
|
||||
return os.WriteFile(targetFile, filedata, 0600)
|
||||
}
|
||||
|
||||
// LoadConfig loads the project configuration file from the
|
||||
// given directory
|
||||
func (po *ProjectOptions) LoadConfig(projectDir string) error {
|
||||
targetFile := filepath.Join(projectDir, "project.json")
|
||||
rawBytes, err := ioutil.ReadFile(targetFile)
|
||||
rawBytes, err := os.ReadFile(targetFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package cmd
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -124,7 +123,7 @@ func (s *SystemHelper) setup() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(s.wailsSystemConfig, configData, 0755)
|
||||
err = os.WriteFile(s.wailsSystemConfig, configData, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -207,11 +206,11 @@ func (sc *SystemConfig) Save(filename string) error {
|
||||
}
|
||||
|
||||
// Write it out to the config file
|
||||
return ioutil.WriteFile(filename, theJSON, 0644)
|
||||
return os.WriteFile(filename, theJSON, 0644)
|
||||
}
|
||||
|
||||
func (sc *SystemConfig) load(filename string) error {
|
||||
configData, err := ioutil.ReadFile(filename)
|
||||
configData, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -125,7 +125,7 @@ func (t *TemplateHelper) LoadMetadata(dir string) (*TemplateMetadata, error) {
|
||||
if !t.fs.FileExists(templateFile) {
|
||||
return nil, nil
|
||||
}
|
||||
rawJSON, err := ioutil.ReadFile(templateFile)
|
||||
rawJSON, err := os.ReadFile(templateFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package cmd
|
||||
|
||||
// Version - Wails version
|
||||
const Version = "v1.16.8"
|
||||
const Version = "v1.16.9"
|
||||
|
||||
@@ -3,7 +3,6 @@ package main
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -305,7 +304,7 @@ func updateWailsVersion(currentVersion, latestVersion *semver.Version) error {
|
||||
new := fmt.Sprintf("%s v%s", wailsModule, latestVersion)
|
||||
|
||||
goMod = strings.Replace(goMod, old, new, -1)
|
||||
err := ioutil.WriteFile(goModFile, []byte(goMod), 0600)
|
||||
err := os.WriteFile(goModFile, []byte(goMod), 0600)
|
||||
if err != nil {
|
||||
checkSpinner.Error()
|
||||
return err
|
||||
@@ -343,7 +342,7 @@ func patchMainJS() error {
|
||||
newStartLine := `Wails.Init`
|
||||
mainJSContents = strings.Replace(mainJSContents, oldStartLine, newStartLine, -1)
|
||||
|
||||
err := ioutil.WriteFile(mainJSFile, []byte(mainJSContents), 0600)
|
||||
err := os.WriteFile(mainJSFile, []byte(mainJSContents), 0600)
|
||||
if err != nil {
|
||||
checkSpinner.Error()
|
||||
return err
|
||||
|
||||
@@ -2,7 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -112,7 +112,7 @@ To help you in this process, we will ask for some information, add Go/Wails deta
|
||||
os.Exit(1)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
template, _ := ioutil.ReadAll(resp.Body)
|
||||
template, _ := io.ReadAll(resp.Body)
|
||||
body := string(template)
|
||||
body = "**Description**\n" + (strings.Split(body, "**Description**")[1])
|
||||
fullURL := "https://github.com/wailsapp/wails/issues/new?"
|
||||
|
||||
2
go.mod
2
go.mod
@@ -8,7 +8,6 @@ require (
|
||||
github.com/gorilla/websocket v1.4.1
|
||||
github.com/jackmordaunt/icns v1.0.0
|
||||
github.com/kennygrant/sanitize v1.2.4
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
||||
github.com/leaanthony/slicer v1.4.0
|
||||
github.com/leaanthony/spinner v0.5.3
|
||||
github.com/mattn/go-colorable v0.1.1 // indirect
|
||||
@@ -17,7 +16,6 @@ require (
|
||||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4
|
||||
github.com/pkg/errors v0.8.1 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/stretchr/objx v0.1.1 // indirect
|
||||
github.com/stretchr/testify v1.3.0 // indirect
|
||||
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba
|
||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8
|
||||
|
||||
9
go.sum
9
go.sum
@@ -21,9 +21,6 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o=
|
||||
github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/leaanthony/slicer v1.4.0 h1:Q9u4w+UBU4WHjXnEDdz+eRLMKF/rnyosRBiqULnc1J8=
|
||||
@@ -52,12 +49,9 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
@@ -73,15 +67,12 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c h1:UIcGWL6/wpCfyGuJnRFJRurA+yj8RrW7Q6x2YMCXt6c=
|
||||
golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 h1:2B5p2L5IfGiD7+b9BOoRMC6DgObAVZV+Fsp050NqXik=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
|
||||
@@ -2,7 +2,6 @@ package binding
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
@@ -144,7 +143,7 @@ export {};`
|
||||
|
||||
dir := filepath.Dir(typescriptDefinitionFilename)
|
||||
os.MkdirAll(dir, 0755)
|
||||
return ioutil.WriteFile(typescriptDefinitionFilename, []byte(output.String()), 0755)
|
||||
return os.WriteFile(typescriptDefinitionFilename, []byte(output.String()), 0755)
|
||||
}
|
||||
|
||||
// bind the given struct method
|
||||
|
||||
@@ -55,20 +55,20 @@ func (e *Manager) addEventListener(eventName string, callback func(...interface{
|
||||
return fmt.Errorf("nil callback bassed to addEventListener")
|
||||
}
|
||||
|
||||
// Check event has been registered before
|
||||
if e.listeners[eventName] == nil {
|
||||
e.listeners[eventName] = []*eventListener{}
|
||||
}
|
||||
|
||||
// Create the callback
|
||||
listener := &eventListener{
|
||||
callback: callback,
|
||||
counter: counter,
|
||||
}
|
||||
e.mu.Lock()
|
||||
// Check event has been registered before
|
||||
if e.listeners[eventName] == nil {
|
||||
e.listeners[eventName] = []*eventListener{}
|
||||
}
|
||||
|
||||
// Register listener
|
||||
e.listeners[eventName] = append(e.listeners[eventName], listener)
|
||||
|
||||
e.mu.Unlock()
|
||||
// All good mate
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@ The build command processes the Wails project and generates an application binar
|
||||
| -ldflags "custom ld flags" | Use given ldflags | |
|
||||
| -o path/to/binary | Compile to given path/filename | |
|
||||
| -k | Keep generated assets | |
|
||||
| -package | Create a platform specific package | |
|
||||
| -production | Compile in production mode: -ldflags="-w -s" + "-h windows" on Windows | |
|
||||
| -tags | Build tags to pass to Go compiler (quoted and space separated) | |
|
||||
| -upx | Compress final binary with UPX (if installed) | |
|
||||
| -upxflags "custom flags" | Flags to pass to upx | |
|
||||
@@ -36,13 +34,13 @@ The build process is as follows:
|
||||
- The frontend is then built. This command is read from the project file `wails.json` under the key `frontend:install` and executed in the `frontend` directory. If this is not defined, it is ignored.
|
||||
- The project directory is checked to see if the `build` directory exists. If not, it is created and default project assets are copied to it.
|
||||
- An asset bundle is then created by reading the `html` key from `wails.json` and loading the referenced file. This is then parsed, looking for local Javascript and CSS references. Those files are in turn loaded into memory, converted to C data and saved into the asset bundle located at `build/assets.h`, which also includes the original HTML.
|
||||
- The application icon is then processed: if there is no `build/appicon.png`, a default icon is copied. On Windows, an `app.ico` file is generated from this png. On Mac, `icons.icns` is generated.
|
||||
- If there are icons in the `build/tray` directory, these are processed, converted to C data and saved as `build/trayicons.h`, ready for the compilation step.
|
||||
- If there are icons in the `build/dialog` directory, these are processed, converted to C data and saved as `build/userdialogicons.h`, ready for the compilation step.
|
||||
- If the `-package` flag is given for a Windows target, the Windows assets in the `build/windows` directory are processed: manifest + icons compiled to a `.syso` file (deleted after compilation).
|
||||
- If we are building a universal binary for Mac, the application is compiled for both `arm64` and `amd64`. The `lipo` tool is then executed to create the universal binary.
|
||||
- The application icon is then processed: if there is no `build/appicon.png`, a default icon is copied. On Windows,
|
||||
an `app.ico` file is generated from this png. On Mac, `icons.icns` is generated.
|
||||
- The platform assets in the `build/<platform>` directory are processed: manifest + icons compiled to a `.syso` file (
|
||||
deleted after compilation), `info.plist` copied to `.app` on Mac.
|
||||
- If we are building a universal binary for Mac, the application is compiled for both `arm64` and `amd64`. The `lipo`
|
||||
tool is then executed to create the universal binary.
|
||||
- If we are not building a universal binary for Mac, the application is built using `go build`, using build tags to indicate type of application and build mode (debug/production).
|
||||
- If the `-upx` flag was provided, `upx` is invoked to compress the binary. Custom flags may be provided using the `-upxflags` flag.
|
||||
- If the `package` flag is given for a non Windows target, the application is bundled for the platform. On Mac, this creates a `.app` with the processed icons, the `Info.plist` in `build/darwin` and the compiled binary.
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package build
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v2/internal/colour"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -38,6 +39,9 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
compilerCommand := "go"
|
||||
command.StringFlag("compiler", "Use a different go compiler to build, eg go1.15beta1", &compilerCommand)
|
||||
|
||||
skipModTidy := false
|
||||
command.BoolFlag("m", "Skip mod tidy before compile", &skipModTidy)
|
||||
|
||||
compress := false
|
||||
command.BoolFlag("upx", "Compress final binary with UPX (if installed)", &compress)
|
||||
|
||||
@@ -76,6 +80,12 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
forceBuild := false
|
||||
command.BoolFlag("f", "Force build application", &forceBuild)
|
||||
|
||||
updateGoMod := false
|
||||
command.BoolFlag("u", "Updates go.mod to use the same Wails version as the CLI", &updateGoMod)
|
||||
|
||||
debug := false
|
||||
command.BoolFlag("debug", "Retains debug data in the compiled application", &debug)
|
||||
|
||||
command.Action(func() error {
|
||||
|
||||
quiet := verbosity == 0
|
||||
@@ -104,6 +114,7 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
//"linux/arm-7",
|
||||
"windows",
|
||||
"windows/amd64",
|
||||
"windows/arm64",
|
||||
})
|
||||
if !validPlatformArch.Contains(platform) {
|
||||
return fmt.Errorf("platform %s is not supported. Platforms supported: %s", platform, validPlatformArch.Join(","))
|
||||
@@ -156,16 +167,24 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
}
|
||||
}
|
||||
|
||||
mode := build.Production
|
||||
modeString := "Production"
|
||||
if debug {
|
||||
mode = build.Debug
|
||||
modeString = "Debug"
|
||||
}
|
||||
|
||||
// Create BuildOptions
|
||||
buildOptions := &build.Options{
|
||||
Logger: logger,
|
||||
OutputType: outputType,
|
||||
OutputFile: outputFilename,
|
||||
CleanBuildDirectory: cleanBuildDirectory,
|
||||
Mode: build.Production,
|
||||
Mode: mode,
|
||||
Pack: !noPackage,
|
||||
LDFlags: ldflags,
|
||||
Compiler: compilerCommand,
|
||||
SkipModTidy: skipModTidy,
|
||||
Verbosity: verbosity,
|
||||
ForceBuild: forceBuild,
|
||||
IgnoreFrontend: skipFrontend,
|
||||
@@ -197,6 +216,7 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
fmt.Fprintf(w, "Platform: \t%s\n", buildOptions.Platform)
|
||||
fmt.Fprintf(w, "Arch: \t%s\n", buildOptions.Arch)
|
||||
fmt.Fprintf(w, "Compiler: \t%s\n", compilerPath)
|
||||
fmt.Fprintf(w, "Build Mode: \t%s\n", modeString)
|
||||
fmt.Fprintf(w, "Skip Frontend: \t%t\n", skipFrontend)
|
||||
fmt.Fprintf(w, "Compress: \t%t\n", buildOptions.Compress)
|
||||
fmt.Fprintf(w, "Package: \t%t\n", buildOptions.Pack)
|
||||
@@ -209,7 +229,7 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
fmt.Fprintf(w, "\n")
|
||||
w.Flush()
|
||||
|
||||
err = checkGoModVersion(logger)
|
||||
err = checkGoModVersion(logger, updateGoMod)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -238,7 +258,7 @@ func doBuild(buildOptions *build.Options) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkGoModVersion(logger *clilogger.CLILogger) error {
|
||||
func checkGoModVersion(logger *clilogger.CLILogger, updateGoMod bool) error {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -260,6 +280,36 @@ func checkGoModVersion(logger *clilogger.CLILogger) error {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Println("Warning: go.mod is using Wails '%s' but the CLI is '%s'. Consider updating it.\n", gomodversion.String(), internal.Version)
|
||||
if updateGoMod {
|
||||
return syncGoModVersion(cwd)
|
||||
}
|
||||
|
||||
logger.Println("Warning: go.mod is using Wails '%s' but the CLI is '%s'. Consider updating your project's `go.mod` file.\n", gomodversion.String(), internal.Version)
|
||||
return nil
|
||||
}
|
||||
|
||||
func LogGreen(message string, args ...interface{}) {
|
||||
text := fmt.Sprintf(message, args...)
|
||||
println(colour.Green(text))
|
||||
}
|
||||
|
||||
func syncGoModVersion(cwd string) error {
|
||||
gomodFilename := filepath.Join(cwd, "go.mod")
|
||||
gomodData, err := os.ReadFile(gomodFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
outOfSync, err := gomod.GoModOutOfSync(gomodData, internal.Version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !outOfSync {
|
||||
return nil
|
||||
}
|
||||
LogGreen("Updating go.mod to use Wails '%s'", internal.Version)
|
||||
newGoData, err := gomod.UpdateGoModVersion(gomodData, internal.Version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(gomodFilename, newGoData, 0755)
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ type devFlags struct {
|
||||
compilerCommand string
|
||||
assetDir string
|
||||
extensions string
|
||||
reloadDirs string
|
||||
openBrowser bool
|
||||
noReload bool
|
||||
wailsjsdir string
|
||||
@@ -83,8 +84,9 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
flags := defaultDevFlags()
|
||||
command.StringFlag("ldflags", "optional ldflags", &flags.ldflags)
|
||||
command.StringFlag("compiler", "Use a different go compiler to build, eg go1.15beta1", &flags.compilerCommand)
|
||||
command.StringFlag("assetdir", "Serve assets from the given directory", &flags.assetDir)
|
||||
command.StringFlag("assetdir", "Serve assets from the given directory instead of using the provided asset FS", &flags.assetDir)
|
||||
command.StringFlag("e", "Extensions to trigger rebuilds (comma separated) eg go", &flags.extensions)
|
||||
command.StringFlag("reloaddirs", "Additional directories to trigger reloads (comma separated)", &flags.reloadDirs)
|
||||
command.BoolFlag("browser", "Open application in browser", &flags.openBrowser)
|
||||
command.BoolFlag("noreload", "Disable reload on asset change", &flags.noReload)
|
||||
command.StringFlag("wailsjsdir", "Directory to generate the Wails JS modules", &flags.wailsjsdir)
|
||||
@@ -301,21 +303,29 @@ func loadAndMergeProjectConfig(cwd string, flags *devFlags) (*project.Project, e
|
||||
|
||||
var shouldSaveConfig bool
|
||||
|
||||
if projectConfig.AssetDirectory == "" && flags.assetDir == "" {
|
||||
return nil, fmt.Errorf("No asset directory provided. Please use -assetdir to indicate which directory contains your built assets.")
|
||||
}
|
||||
|
||||
if flags.assetDir == "" && projectConfig.AssetDirectory != "" {
|
||||
flags.assetDir = projectConfig.AssetDirectory
|
||||
}
|
||||
|
||||
if flags.assetDir != projectConfig.AssetDirectory {
|
||||
projectConfig.AssetDirectory = filepath.ToSlash(flags.assetDir)
|
||||
shouldSaveConfig = true
|
||||
}
|
||||
|
||||
flags.assetDir, err = filepath.Abs(flags.assetDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if flags.assetDir != "" {
|
||||
flags.assetDir, err = filepath.Abs(flags.assetDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if flags.reloadDirs == "" && projectConfig.ReloadDirectories != "" {
|
||||
flags.reloadDirs = projectConfig.ReloadDirectories
|
||||
}
|
||||
|
||||
if flags.reloadDirs != projectConfig.ReloadDirectories {
|
||||
projectConfig.ReloadDirectories = filepath.ToSlash(flags.reloadDirs)
|
||||
shouldSaveConfig = true
|
||||
}
|
||||
|
||||
if flags.devServerURL == defaultDevServerURL && projectConfig.DevServerURL != defaultDevServerURL && projectConfig.DevServerURL != "" {
|
||||
@@ -503,11 +513,26 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
|
||||
newBinaryProcess *process.Process
|
||||
)
|
||||
var extensionsThatTriggerARebuild = sliceToMap(strings.Split(flags.extensions, ","))
|
||||
var dirsThatTriggerAReload []string
|
||||
for _, dir := range strings.Split(flags.reloadDirs, ",") {
|
||||
if dir == "" {
|
||||
continue
|
||||
}
|
||||
path, err := filepath.Abs(dir)
|
||||
if err != nil {
|
||||
LogRed("Unable to expand reloadDir '%s': %s", dir, err)
|
||||
continue
|
||||
}
|
||||
dirsThatTriggerAReload = append(dirsThatTriggerAReload, path)
|
||||
}
|
||||
|
||||
quit := false
|
||||
interval := time.Duration(flags.debounceMS) * time.Millisecond
|
||||
timer := time.NewTimer(interval)
|
||||
rebuild := false
|
||||
reload := false
|
||||
assetDir := ""
|
||||
changedPaths := map[string]struct{}{}
|
||||
for quit == false {
|
||||
//reload := false
|
||||
select {
|
||||
@@ -519,12 +544,13 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
|
||||
// Check for file writes
|
||||
if item.Op&fsnotify.Write == fsnotify.Write {
|
||||
// Ignore directories
|
||||
if fs.DirExists(item.Name) {
|
||||
itemName := item.Name
|
||||
if fs.DirExists(itemName) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Iterate all file patterns
|
||||
ext := filepath.Ext(item.Name)
|
||||
ext := filepath.Ext(itemName)
|
||||
if ext != "" {
|
||||
ext = ext[1:]
|
||||
if _, exists := extensionsThatTriggerARebuild[ext]; exists {
|
||||
@@ -534,9 +560,17 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(item.Name, flags.assetDir) {
|
||||
reload = true
|
||||
for _, reloadDir := range dirsThatTriggerAReload {
|
||||
if strings.HasPrefix(itemName, reloadDir) {
|
||||
reload = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !reload {
|
||||
changedPaths[filepath.Dir(itemName)] = struct{}{}
|
||||
}
|
||||
|
||||
timer.Reset(interval)
|
||||
}
|
||||
// Check for new directories
|
||||
@@ -568,6 +602,35 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
|
||||
debugBinaryProcess = newBinaryProcess
|
||||
}
|
||||
}
|
||||
if len(changedPaths) != 0 {
|
||||
if assetDir == "" {
|
||||
resp, err := http.Get("http://localhost:34115/wails/assetdir")
|
||||
if err != nil {
|
||||
LogRed("Error during retrieving assetdir: %s", err.Error())
|
||||
} else {
|
||||
content, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
LogRed("Error reading assetdir from devserver: %s", err.Error())
|
||||
} else {
|
||||
assetDir = string(content)
|
||||
}
|
||||
resp.Body.Close()
|
||||
}
|
||||
}
|
||||
|
||||
if assetDir != "" {
|
||||
for path := range changedPaths {
|
||||
if strings.HasPrefix(path, assetDir) {
|
||||
reload = true
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if len(dirsThatTriggerAReload) == 0 {
|
||||
LogRed("Reloading couldn't be triggered: Please specify -assetdir or -reloaddirs")
|
||||
}
|
||||
|
||||
changedPaths = map[string]struct{}{}
|
||||
}
|
||||
if reload {
|
||||
reload = false
|
||||
_, err = http.Get("http://localhost:34115/wails/reload")
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/wailsapp/wails/v2/cmd/wails/internal/commands/generate/template"
|
||||
"io"
|
||||
|
||||
"github.com/leaanthony/clir"
|
||||
)
|
||||
@@ -17,6 +16,7 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
template.AddSubCommand(app, command, w)
|
||||
|
||||
return nil
|
||||
|
||||
@@ -10,7 +10,6 @@ The next steps to complete the template are:
|
||||
- It is really important to ensure `helpurl` is valid as this is where users of the template will be directed for help.
|
||||
2. Update `README.md`.
|
||||
3. Edit `wails.json` and ensure all fields are correct, especially:
|
||||
- `assetdir` - path to your assets
|
||||
- `wailsjsdir` - path to generate wailsjs modules
|
||||
- `frontend:install` - The command to install your frontend dependencies
|
||||
- `frontend:build` - The command to build your frontend
|
||||
|
||||
@@ -4,13 +4,12 @@
|
||||
|
||||
About your template
|
||||
|
||||
## Building
|
||||
|
||||
To build this project in debug mode, use `wails build`. For production, use `wails build -production`.
|
||||
To generate a platform native package, add the `-package` flag.
|
||||
|
||||
## Live Development
|
||||
|
||||
To run in live development mode, run `wails dev` in the project directory. In another terminal, go into the `frontend`
|
||||
directory and run `npm run dev`. The frontend dev server will run on http://localhost:34115. Connect to this
|
||||
in your browser and connect to your application.
|
||||
To run in live development mode, run `wails dev` in the project directory. In another terminal, go into the `frontend`
|
||||
directory and run `npm run dev`. The frontend dev server will run on http://localhost:34115. Connect to this in your
|
||||
browser and connect to your application.
|
||||
|
||||
## Building
|
||||
|
||||
To build a redistributable, production mode package, use `wails build`.
|
||||
|
||||
@@ -22,7 +22,6 @@ github.com/leaanthony/go-common-file-dialog v1.0.3 // indirect
|
||||
github.com/leaanthony/go-webview2 v0.0.0-20210914103035-f00aa774a934 // indirect
|
||||
github.com/leaanthony/slicer v1.5.0 // indirect
|
||||
github.com/leaanthony/typescriptify-golang-structs v0.1.7 // indirect
|
||||
github.com/leaanthony/webview2runtime v1.1.0 // indirect
|
||||
github.com/leaanthony/winc v0.0.0-20210921073452-54963136bf18 // indirect
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
|
||||
@@ -90,8 +90,6 @@ github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0H
|
||||
github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
|
||||
github.com/leaanthony/typescriptify-golang-structs v0.1.7 h1:yoznzWzyxkO/iWdlpq+aPcuJ5Y/hpjq/lmgMFmpjwl0=
|
||||
github.com/leaanthony/typescriptify-golang-structs v0.1.7/go.mod h1:cWtOkiVhMF77e6phAXUcfNwYmMwCJ67Sij24lfvi9Js=
|
||||
github.com/leaanthony/webview2runtime v1.1.0 h1:N0pv55ift8XtqozIp4PNOtRCJ/Qdd/qzx80lUpalS4c=
|
||||
github.com/leaanthony/webview2runtime v1.1.0/go.mod h1:hH9GnWCve3DYzNaPOcPbhHQ7fodXR1QJNsnwixid4Tk=
|
||||
github.com/leaanthony/winc v0.0.0-20210921073452-54963136bf18 h1:5iOd93PZbpH4Iir8QkC4coFD+zEQEZSIRcjwjTFZkr0=
|
||||
github.com/leaanthony/winc v0.0.0-20210921073452-54963136bf18/go.mod h1:KEbMsKoznsebyGHwLk5LqkFOxL5uXSRdvpP4+avmAMs=
|
||||
github.com/leaanthony/winicon v1.0.0/go.mod h1:en5xhijl92aphrJdmRPlh4NI1L6wq3gEm0LpXAPghjU=
|
||||
|
||||
@@ -33,10 +33,10 @@ func main() {
|
||||
HideWindowOnClose: false,
|
||||
RGBA: &options.RGBA{255, 255, 255, 255},
|
||||
Assets: assets,
|
||||
LogLevel: logger.DEBUG,
|
||||
OnStartup: app.startup,
|
||||
OnDomReady: app.domReady,
|
||||
OnShutdown: app.shutdown,
|
||||
LogLevel: logger.DEBUG,
|
||||
OnStartup: app.startup,
|
||||
OnDomReady: app.domReady,
|
||||
OnShutdown: app.shutdown,
|
||||
Bind: []interface{}{
|
||||
app,
|
||||
},
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
{
|
||||
"name": "{{.ProjectName}}",
|
||||
"author": "",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"postinstall": "npm run setup && cd frontend && npm install",
|
||||
"install": "go install github.com/wailsapp/wails/v2/cmd/wails@latest",
|
||||
"build": "wails build --clean",
|
||||
"build:macos": "npm run build -- --platform darwin/universal",
|
||||
"build:macos-arm": "npm run build -- --platform darwin/arm64",
|
||||
"build:macos-intel": "npm run build -- --platform darwin",
|
||||
"build:windows": "npm run build -- --platform windows/amd64",
|
||||
"setup": "go install github.com/wailsapp/wails/v2/cmd/wails@latest"
|
||||
}
|
||||
"build:windows": "npm run build -- --platform windows/amd64"
|
||||
},
|
||||
"workspaces": [
|
||||
"frontend"
|
||||
]
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"name": "{{.ProjectName}}",
|
||||
"outputfilename": "{{.BinaryName}}",
|
||||
"assetdir": "frontend/dist",
|
||||
"frontend:install": "npm install",
|
||||
"frontend:build": "npm run build",
|
||||
"author": {
|
||||
|
||||
@@ -158,18 +158,17 @@ func processPackageJSON(frontendDir string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(packageJSON)
|
||||
json, err := os.ReadFile(packageJSON)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
json := string(data)
|
||||
|
||||
// We will ignore these errors - it's not critical
|
||||
println("Updating package.json data...")
|
||||
json, _ = sjson.Set(json, "name", "{{.ProjectName}}")
|
||||
json, _ = sjson.Set(json, "author", "{{.AuthorName}}")
|
||||
json, _ = sjson.SetBytes(json, "name", "{{.ProjectName}}")
|
||||
json, _ = sjson.SetBytes(json, "author", "{{.AuthorName}}")
|
||||
|
||||
err = os.WriteFile(packageJSON, []byte(json), 0644)
|
||||
err = os.WriteFile(packageJSON, json, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
<working_directory value="$PROJECT_DIR$"/>
|
||||
<go_parameters value="-gcflags "all=-N -l" -tags dev -o {{.PathToDesktopBinary}}"/>
|
||||
<useCustomBuildTags value="true"/>
|
||||
<parameters value="-assetdir {{.AssetDir}}"/>
|
||||
<envs>
|
||||
<env name="CGO_ENABLED" value=""{{.CGOEnabled}}""/>
|
||||
</envs>
|
||||
|
||||
@@ -9,11 +9,7 @@
|
||||
"program": "${workspaceFolder}/{{.PathToDesktopBinary}}",
|
||||
"preLaunchTask": "build",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"env": {},
|
||||
"args": [
|
||||
"-assetdir",
|
||||
"{{.AssetDir}}"
|
||||
]
|
||||
"env": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -4,15 +4,14 @@ import (
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/go-git/go-git/v5"
|
||||
gofs "io/fs"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/leaanthony/debme"
|
||||
@@ -43,7 +42,6 @@ type Data struct {
|
||||
AuthorNameAndEmail string
|
||||
WailsDirectory string
|
||||
GoSDKPath string
|
||||
AssetDir string
|
||||
WindowsFlags string
|
||||
CGOEnabled string
|
||||
OutputFile string
|
||||
@@ -61,7 +59,6 @@ type Options struct {
|
||||
InitGit bool
|
||||
AuthorName string
|
||||
AuthorEmail string
|
||||
AssetDir string
|
||||
IDE string
|
||||
ProjectNameFilename string // The project name but as a valid filename
|
||||
WailsVersion string
|
||||
@@ -262,7 +259,6 @@ func Install(options *Options) (bool, *Template, error) {
|
||||
AuthorName: options.AuthorName,
|
||||
WailsVersion: options.WailsVersion,
|
||||
GoSDKPath: options.GoSDKPath,
|
||||
AssetDir: options.AssetDir,
|
||||
}
|
||||
|
||||
// Create a formatted name and email combo.
|
||||
@@ -295,7 +291,7 @@ func Install(options *Options) (bool, *Template, error) {
|
||||
// Clones the given uri and returns the temporary cloned directory
|
||||
func gitclone(options *Options) (string, error) {
|
||||
// Create temporary directory
|
||||
dirname, err := ioutil.TempDir("", "wails-template-*")
|
||||
dirname, err := os.MkdirTemp("", "wails-template-*")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -409,22 +405,6 @@ func installIDEFiles(o ideOptions) error {
|
||||
binaryName += ".exe"
|
||||
}
|
||||
|
||||
// Parse wails.json for assetdir
|
||||
wailsJSONBytes, err := os.ReadFile(filepath.Join(o.options.TargetDir, "wails.json"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var wailsJSON map[string]interface{}
|
||||
err = json.Unmarshal(wailsJSONBytes, &wailsJSON)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
assetDir := wailsJSON["assetdir"]
|
||||
if assetDir == "" {
|
||||
return fmt.Errorf("Unable to find 'assetdir' in 'wails.json' ")
|
||||
}
|
||||
|
||||
o.options.AssetDir = assetDir.(string)
|
||||
o.options.PathToDesktopBinary = filepath.ToSlash(filepath.Join("build", "bin", binaryName))
|
||||
|
||||
o.options.WindowsFlags = ""
|
||||
|
||||
@@ -22,7 +22,6 @@ github.com/leaanthony/go-common-file-dialog v1.0.3 // indirect
|
||||
github.com/leaanthony/go-webview2 v0.0.0-20210914103035-f00aa774a934 // indirect
|
||||
github.com/leaanthony/slicer v1.5.0 // indirect
|
||||
github.com/leaanthony/typescriptify-golang-structs v0.1.7 // indirect
|
||||
github.com/leaanthony/webview2runtime v1.1.0 // indirect
|
||||
github.com/leaanthony/winc v0.0.0-20210921073452-54963136bf18 // indirect
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
|
||||
@@ -91,8 +91,6 @@ github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0H
|
||||
github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
|
||||
github.com/leaanthony/typescriptify-golang-structs v0.1.7 h1:yoznzWzyxkO/iWdlpq+aPcuJ5Y/hpjq/lmgMFmpjwl0=
|
||||
github.com/leaanthony/typescriptify-golang-structs v0.1.7/go.mod h1:cWtOkiVhMF77e6phAXUcfNwYmMwCJ67Sij24lfvi9Js=
|
||||
github.com/leaanthony/webview2runtime v1.1.0 h1:N0pv55ift8XtqozIp4PNOtRCJ/Qdd/qzx80lUpalS4c=
|
||||
github.com/leaanthony/webview2runtime v1.1.0/go.mod h1:hH9GnWCve3DYzNaPOcPbhHQ7fodXR1QJNsnwixid4Tk=
|
||||
github.com/leaanthony/winc v0.0.0-20210921073452-54963136bf18 h1:5iOd93PZbpH4Iir8QkC4coFD+zEQEZSIRcjwjTFZkr0=
|
||||
github.com/leaanthony/winc v0.0.0-20210921073452-54963136bf18/go.mod h1:KEbMsKoznsebyGHwLk5LqkFOxL5uXSRdvpP4+avmAMs=
|
||||
github.com/leaanthony/winicon v1.0.0/go.mod h1:en5xhijl92aphrJdmRPlh4NI1L6wq3gEm0LpXAPghjU=
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"name": "{{.ProjectName}}",
|
||||
"outputfilename": "{{.BinaryName}}",
|
||||
"assetdir": "frontend/dist",
|
||||
"frontend:install": "npm install",
|
||||
"frontend:build": "npm run build",
|
||||
"wailsjsdir": "./frontend",
|
||||
|
||||
@@ -22,7 +22,6 @@ github.com/leaanthony/go-common-file-dialog v1.0.3 // indirect
|
||||
github.com/leaanthony/go-webview2 v0.0.0-20210914103035-f00aa774a934 // indirect
|
||||
github.com/leaanthony/slicer v1.5.0 // indirect
|
||||
github.com/leaanthony/typescriptify-golang-structs v0.1.7 // indirect
|
||||
github.com/leaanthony/webview2runtime v1.1.0 // indirect
|
||||
github.com/leaanthony/winc v0.0.0-20210921073452-54963136bf18 // indirect
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
|
||||
@@ -91,8 +91,6 @@ github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0H
|
||||
github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
|
||||
github.com/leaanthony/typescriptify-golang-structs v0.1.7 h1:yoznzWzyxkO/iWdlpq+aPcuJ5Y/hpjq/lmgMFmpjwl0=
|
||||
github.com/leaanthony/typescriptify-golang-structs v0.1.7/go.mod h1:cWtOkiVhMF77e6phAXUcfNwYmMwCJ67Sij24lfvi9Js=
|
||||
github.com/leaanthony/webview2runtime v1.1.0 h1:N0pv55ift8XtqozIp4PNOtRCJ/Qdd/qzx80lUpalS4c=
|
||||
github.com/leaanthony/webview2runtime v1.1.0/go.mod h1:hH9GnWCve3DYzNaPOcPbhHQ7fodXR1QJNsnwixid4Tk=
|
||||
github.com/leaanthony/winc v0.0.0-20210921073452-54963136bf18 h1:5iOd93PZbpH4Iir8QkC4coFD+zEQEZSIRcjwjTFZkr0=
|
||||
github.com/leaanthony/winc v0.0.0-20210921073452-54963136bf18/go.mod h1:KEbMsKoznsebyGHwLk5LqkFOxL5uXSRdvpP4+avmAMs=
|
||||
github.com/leaanthony/winicon v1.0.0/go.mod h1:en5xhijl92aphrJdmRPlh4NI1L6wq3gEm0LpXAPghjU=
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"name": "{{.ProjectName}}",
|
||||
"outputfilename": "{{.BinaryName}}",
|
||||
"assetdir": "frontend/src",
|
||||
"wailsjsdir": "./frontend",
|
||||
"author": {
|
||||
"name": "{{.AuthorName}}",
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
package internal
|
||||
|
||||
var Version = "v2.0.0-beta.21"
|
||||
var Version = "v2.0.0-beta.27"
|
||||
|
||||
12
v2/go.mod
12
v2/go.mod
@@ -22,13 +22,12 @@ require (
|
||||
github.com/leaanthony/debme v1.2.1
|
||||
github.com/leaanthony/go-ansi-parser v1.0.1
|
||||
github.com/leaanthony/go-common-file-dialog v1.0.3
|
||||
github.com/leaanthony/go-webview2 v0.0.0-20211022194343-1e4c8d4226f3
|
||||
github.com/leaanthony/go-webview2 v1.0.2
|
||||
github.com/leaanthony/gosod v1.0.3
|
||||
github.com/leaanthony/idgen v1.0.0
|
||||
github.com/leaanthony/slicer v1.5.0
|
||||
github.com/leaanthony/typescriptify-golang-structs v0.1.7
|
||||
github.com/leaanthony/webview2runtime v1.1.0
|
||||
github.com/leaanthony/winc v0.0.0-20210921073452-54963136bf18
|
||||
github.com/leaanthony/winc v0.0.0-20211202091710-9931d43181ff
|
||||
github.com/leaanthony/winicon v1.0.0
|
||||
github.com/matryer/is v1.4.0
|
||||
github.com/olekukonko/tablewriter v0.0.4
|
||||
@@ -40,24 +39,21 @@ require (
|
||||
github.com/tdewolff/test v1.0.6 // indirect
|
||||
github.com/tidwall/sjson v1.1.7
|
||||
github.com/wzshiming/ctc v1.2.3
|
||||
github.com/xyproto/xpm v1.2.1
|
||||
github.com/ztrue/tracerr v0.3.0
|
||||
golang.org/x/mod v0.4.1
|
||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed
|
||||
golang.org/x/sys v0.0.0-20211020174200-9d6173849985
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e
|
||||
golang.org/x/tools v0.1.0
|
||||
nhooyr.io/websocket v1.8.6
|
||||
)
|
||||
|
||||
require github.com/gotk3/gotk3 v0.6.1
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.4.16 // indirect
|
||||
github.com/andybalholm/brotli v1.0.2 // indirect
|
||||
github.com/emirpasic/gods v1.12.0 // indirect
|
||||
github.com/fasthttp/websocket v0.0.0-20200320073529-1554a54587ab // indirect
|
||||
github.com/go-git/gcfg v1.5.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.5 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/google/go-cmp v0.5.5 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
|
||||
|
||||
25
v2/go.sum
25
v2/go.sum
@@ -45,8 +45,8 @@ github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod
|
||||
github.com/go-git/go-git/v5 v5.3.0 h1:8WKMtJR2j8RntEXR/uvTKagfEt4GYlwQ7mntE4+0GWc=
|
||||
github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
|
||||
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
@@ -82,8 +82,6 @@ github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gotk3/gotk3 v0.6.1 h1:GJ400a0ecEEWrzjBvzBzH+pB/esEMIGdB9zPSmBdoeo=
|
||||
github.com/gotk3/gotk3 v0.6.1/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/jackmordaunt/icns v1.0.0 h1:RYSxplerf/l/DUd09AHtITwckkv/mqjVv4DjYdPmAMQ=
|
||||
@@ -120,8 +118,8 @@ github.com/leaanthony/go-ansi-parser v1.0.1 h1:97v6c5kYppVsbScf4r/VZdXyQ21KQIfeQ
|
||||
github.com/leaanthony/go-ansi-parser v1.0.1/go.mod h1:7arTzgVI47srICYhvgUV4CGd063sGEeoSlych5yeSPM=
|
||||
github.com/leaanthony/go-common-file-dialog v1.0.3 h1:O0uGjKnWtdEADGrkg+TyAAbZylykMwwx/MNEXn9fp+Y=
|
||||
github.com/leaanthony/go-common-file-dialog v1.0.3/go.mod h1:TGhEc9eSJgRsupZ+iH1ZgAOnEo9zp05cRH2j08RPrF0=
|
||||
github.com/leaanthony/go-webview2 v0.0.0-20211022194343-1e4c8d4226f3 h1:qhgrg3MhFRAIvtaqoqI+SrT+0wDYpxDMp9e3cvcxMpI=
|
||||
github.com/leaanthony/go-webview2 v0.0.0-20211022194343-1e4c8d4226f3/go.mod h1:lS5ds4bruPk9d7lzdF/OH31Z0YCerI6MmHNFGsWoUnM=
|
||||
github.com/leaanthony/go-webview2 v1.0.2 h1:IjTbpAXUig33G3LUqf+8EClZutg2Z/C1cbxqhHKPxbU=
|
||||
github.com/leaanthony/go-webview2 v1.0.2/go.mod h1:iX54IaVk1FnDqMuHJ47VYLPQOcVqQiOe9SJACt9CAbU=
|
||||
github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aTQ=
|
||||
github.com/leaanthony/gosod v1.0.3/go.mod h1:BJ2J+oHsQIyIQpnLPjnqFGTMnOZXDbvWtRCSG7jGxs4=
|
||||
github.com/leaanthony/idgen v1.0.0 h1:IZreR+JGEzFV4yeVuBZA25gM0keUoFy+RDUldncQ+Jw=
|
||||
@@ -130,10 +128,8 @@ github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0H
|
||||
github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
|
||||
github.com/leaanthony/typescriptify-golang-structs v0.1.7 h1:yoznzWzyxkO/iWdlpq+aPcuJ5Y/hpjq/lmgMFmpjwl0=
|
||||
github.com/leaanthony/typescriptify-golang-structs v0.1.7/go.mod h1:cWtOkiVhMF77e6phAXUcfNwYmMwCJ67Sij24lfvi9Js=
|
||||
github.com/leaanthony/webview2runtime v1.1.0 h1:N0pv55ift8XtqozIp4PNOtRCJ/Qdd/qzx80lUpalS4c=
|
||||
github.com/leaanthony/webview2runtime v1.1.0/go.mod h1:hH9GnWCve3DYzNaPOcPbhHQ7fodXR1QJNsnwixid4Tk=
|
||||
github.com/leaanthony/winc v0.0.0-20210921073452-54963136bf18 h1:5iOd93PZbpH4Iir8QkC4coFD+zEQEZSIRcjwjTFZkr0=
|
||||
github.com/leaanthony/winc v0.0.0-20210921073452-54963136bf18/go.mod h1:KEbMsKoznsebyGHwLk5LqkFOxL5uXSRdvpP4+avmAMs=
|
||||
github.com/leaanthony/winc v0.0.0-20211202091710-9931d43181ff h1:FwGObElCr/T/xy8S9IKDjWsNcfJHGxgjRl/GIbcseoQ=
|
||||
github.com/leaanthony/winc v0.0.0-20211202091710-9931d43181ff/go.mod h1:KEbMsKoznsebyGHwLk5LqkFOxL5uXSRdvpP4+avmAMs=
|
||||
github.com/leaanthony/winicon v1.0.0 h1:ZNt5U5dY71oEoKZ97UVwJRT4e+5xo5o/ieKuHuk8NqQ=
|
||||
github.com/leaanthony/winicon v1.0.0/go.mod h1:en5xhijl92aphrJdmRPlh4NI1L6wq3gEm0LpXAPghjU=
|
||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||
@@ -215,8 +211,6 @@ github.com/wzshiming/winseq v0.0.0-20200112104235-db357dc107ae h1:tpXvBXC3hpQBDC
|
||||
github.com/wzshiming/winseq v0.0.0-20200112104235-db357dc107ae/go.mod h1:VTAq37rkGeV+WOybvZwjXiJOicICdpLCN8ifpISjK20=
|
||||
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
||||
github.com/xyproto/xpm v1.2.1 h1:trdvGjjWBsOOKzBBUPT6JvaIQM3acJEEYfbxN7M96wg=
|
||||
github.com/xyproto/xpm v1.2.1/go.mod h1:cMnesLsD0PBXLgjDfTDEaKr8XyTFsnP1QycSqRw7BiY=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/ztrue/tracerr v0.3.0 h1:lDi6EgEYhPYPnKcjsYzmWw4EkFEoA/gfe+I9Y5f+h6Y=
|
||||
github.com/ztrue/tracerr v0.3.0/go.mod h1:qEalzze4VN9O8tnhBXScfCrmoJo10o8TN5ciKjm6Mww=
|
||||
@@ -254,18 +248,17 @@ golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210218145245-beda7e5e158e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210611083646-a4fc73990273/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211020174200-9d6173849985 h1:LOlKVhfDyahgmqa97awczplwkjzNaELFg3zRIJ13RYo=
|
||||
golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package wails
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !desktop && !hybrid && !server && !dev
|
||||
// +build !desktop,!hybrid,!server,!dev
|
||||
|
||||
package app
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !server && !desktop && hybrid
|
||||
// +build !server,!desktop,hybrid
|
||||
|
||||
package app
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//+build !windows
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package app
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//+build windows
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package app
|
||||
|
||||
|
||||
@@ -103,6 +103,12 @@ func generateBindings(bindings *binding.Bindings) error {
|
||||
return err
|
||||
}
|
||||
|
||||
bindingsTypes := filepath.Join(targetDir, "bindings.d.ts")
|
||||
err = bindings.GenerateBackendTS(bindingsTypes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,10 @@ package appng
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"flag"
|
||||
"fmt"
|
||||
iofs "io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
@@ -91,12 +94,30 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if assetdir == "" {
|
||||
// If no assetdir has been defined, let's try to infer it from the project root and the asset FS.
|
||||
assetdir, err = tryInferAssetDirFromFS(appoptions.Assets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if assetdir != "" {
|
||||
// Let's override the assets to serve from on disk, if needed
|
||||
absdir, err := filepath.Abs(assetdir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
myLogger.Info("Serving assets from disk: %s", absdir)
|
||||
appoptions.Assets = os.DirFS(absdir)
|
||||
|
||||
ctx = context.WithValue(ctx, "assetdir", assetdir)
|
||||
}
|
||||
|
||||
if devServerURL != "" {
|
||||
ctx = context.WithValue(ctx, "devserverurl", devServerURL)
|
||||
}
|
||||
if assetdir != "" {
|
||||
ctx = context.WithValue(ctx, "assetdir", assetdir)
|
||||
}
|
||||
|
||||
if loglevel != "" {
|
||||
level, err := pkglogger.StringToLogLevel(loglevel)
|
||||
@@ -193,6 +214,42 @@ func generateBindings(bindings *binding.Bindings) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bindingsTypes := filepath.Join(targetDir, "bindings.d.ts")
|
||||
err = bindings.GenerateBackendTS(bindingsTypes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func tryInferAssetDirFromFS(assets iofs.FS) (string, error) {
|
||||
if _, isEmbedFs := assets.(embed.FS); !isEmbedFs {
|
||||
// We only infer the assetdir for embed.FS assets
|
||||
return "", nil
|
||||
}
|
||||
|
||||
path, err := fs.FindPathToFile(assets, "index.html")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
path, err = filepath.Abs(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(filepath.Join(path, "index.html")); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
err = fmt.Errorf(
|
||||
"inferred assetdir '%s' does not exist or does not contain an 'index.html' file, "+
|
||||
"please specify it with -assetdir or set it in wails.json",
|
||||
path)
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
return path, nil
|
||||
}
|
||||
|
||||
@@ -81,6 +81,9 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
appFrontend := desktop.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher)
|
||||
eventHandler.AddFrontend(appFrontend)
|
||||
|
||||
// Attach logger to context
|
||||
ctx = context.WithValue(ctx, "logger", myLogger)
|
||||
|
||||
result := &App{
|
||||
ctx: ctx,
|
||||
frontend: appFrontend,
|
||||
|
||||
@@ -15,9 +15,9 @@ func PreflightChecks(options *options.App, logger *logger.Logger) error {
|
||||
// Process the webview2 runtime situation. We can pass a strategy in via the `webview2` flag for `wails build`.
|
||||
// This will determine how wv2runtime.Process will handle a lack of valid runtime.
|
||||
installedVersion, err := wv2runtime.Process()
|
||||
if installedVersion != nil {
|
||||
logger.Debug("WebView2 Runtime installed: Name: '%s' Version:'%s' Location:'%s'. Minimum version required: %s.",
|
||||
installedVersion.Name, installedVersion.Version, installedVersion.Location, wv2runtime.MinimumRuntimeVersion)
|
||||
if installedVersion != "" {
|
||||
logger.Debug("WebView2 Runtime Version '%s' installed. Minimum version required: %s.",
|
||||
installedVersion, wv2runtime.MinimumRuntimeVersion)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//go:build !desktop
|
||||
// +build !desktop
|
||||
|
||||
package assetdb
|
||||
|
||||
import (
|
||||
|
||||
@@ -122,6 +122,83 @@ export default go;`)
|
||||
return os.WriteFile(targetfile, output.Bytes(), 0755)
|
||||
}
|
||||
|
||||
// GenerateBackendTS generates typescript bindings for
|
||||
// the bound methods.
|
||||
func (b *Bindings) GenerateBackendTS(targetfile string) error {
|
||||
|
||||
store := b.db.store
|
||||
var output bytes.Buffer
|
||||
|
||||
output.WriteString("interface go {\n")
|
||||
|
||||
var sortedPackageNames slicer.StringSlicer
|
||||
for packageName := range store {
|
||||
sortedPackageNames.Add(packageName)
|
||||
}
|
||||
sortedPackageNames.Sort()
|
||||
sortedPackageNames.Each(func(packageName string) {
|
||||
packages := store[packageName]
|
||||
output.WriteString(fmt.Sprintf(" \"%s\": {", packageName))
|
||||
output.WriteString("\n")
|
||||
var sortedStructNames slicer.StringSlicer
|
||||
for structName := range packages {
|
||||
sortedStructNames.Add(structName)
|
||||
}
|
||||
sortedStructNames.Sort()
|
||||
|
||||
sortedStructNames.Each(func(structName string) {
|
||||
structs := packages[structName]
|
||||
output.WriteString(fmt.Sprintf(" \"%s\": {", structName))
|
||||
output.WriteString("\n")
|
||||
|
||||
var sortedMethodNames slicer.StringSlicer
|
||||
for methodName := range structs {
|
||||
sortedMethodNames.Add(methodName)
|
||||
}
|
||||
sortedMethodNames.Sort()
|
||||
|
||||
sortedMethodNames.Each(func(methodName string) {
|
||||
methodDetails := structs[methodName]
|
||||
output.WriteString(fmt.Sprintf("\t\t%s(", methodName))
|
||||
|
||||
var args slicer.StringSlicer
|
||||
for count, input := range methodDetails.Inputs {
|
||||
arg := fmt.Sprintf("arg%d", count+1)
|
||||
args.Add(arg + ":" + goTypeToTypescriptType(input.TypeName))
|
||||
}
|
||||
output.WriteString(args.Join(",") + "):")
|
||||
returnType := "Promise"
|
||||
if methodDetails.OutputCount() > 0 {
|
||||
firstType := goTypeToTypescriptType(methodDetails.Outputs[0].TypeName)
|
||||
returnType += "<" + firstType
|
||||
if methodDetails.OutputCount() == 2 {
|
||||
secondType := goTypeToTypescriptType(methodDetails.Outputs[1].TypeName)
|
||||
returnType += "|" + secondType
|
||||
}
|
||||
returnType += ">"
|
||||
} else {
|
||||
returnType = "Promise<void>"
|
||||
}
|
||||
output.WriteString(returnType + "\n")
|
||||
})
|
||||
|
||||
output.WriteString(" },\n")
|
||||
})
|
||||
output.WriteString(" }\n\n")
|
||||
})
|
||||
output.WriteString("}\n")
|
||||
|
||||
globals := `
|
||||
declare global {
|
||||
interface Window {
|
||||
go: go;
|
||||
}
|
||||
}
|
||||
`
|
||||
output.WriteString(globals)
|
||||
return os.WriteFile(targetfile, output.Bytes(), 0755)
|
||||
}
|
||||
|
||||
func goTypeToJSDocType(input string) string {
|
||||
switch true {
|
||||
case input == "string":
|
||||
@@ -139,7 +216,7 @@ func goTypeToJSDocType(input string) string {
|
||||
return "string"
|
||||
case strings.HasPrefix(input, "[]"):
|
||||
arrayType := goTypeToJSDocType(input[2:])
|
||||
return "Array.<" + arrayType + ">"
|
||||
return "Array<" + arrayType + ">"
|
||||
default:
|
||||
if strings.ContainsRune(input, '.') {
|
||||
return strings.Split(input, ".")[1]
|
||||
@@ -147,3 +224,11 @@ func goTypeToJSDocType(input string) string {
|
||||
return "any"
|
||||
}
|
||||
}
|
||||
|
||||
func goTypeToTypescriptType(input string) string {
|
||||
if strings.HasPrefix(input, "[]") {
|
||||
arrayType := goTypeToJSDocType(input[2:])
|
||||
return "Array<" + arrayType + ">"
|
||||
}
|
||||
return goTypeToJSDocType(input)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package ffenestri
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ffenestri
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
//go:build wv2runtime.browser
|
||||
// +build wv2runtime.browser
|
||||
|
||||
package wv2runtime
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/leaanthony/webview2runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/webview2runtime"
|
||||
)
|
||||
|
||||
func doInstallationStrategy(installStatus installationStatus) error {
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
// +build !wv2runtime.error
|
||||
// +build !wv2runtime.browser
|
||||
// +build !wv2runtime.embed
|
||||
//go:build !wv2runtime.error && !wv2runtime.browser && !wv2runtime.embed
|
||||
// +build !wv2runtime.error,!wv2runtime.browser,!wv2runtime.embed
|
||||
|
||||
package wv2runtime
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/leaanthony/webview2runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/webview2runtime"
|
||||
)
|
||||
|
||||
func doInstallationStrategy(installStatus installationStatus) error {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
//go:build wv2runtime.embed
|
||||
// +build wv2runtime.embed
|
||||
|
||||
package wv2runtime
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/leaanthony/webview2runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/webview2runtime"
|
||||
)
|
||||
|
||||
func doInstallationStrategy(installStatus installationStatus) error {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
//go:build wv2runtime.error
|
||||
// +build wv2runtime.error
|
||||
|
||||
package wv2runtime
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/leaanthony/webview2runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/webview2runtime"
|
||||
)
|
||||
|
||||
func doInstallationStrategy(installStatus installationStatus) error {
|
||||
|
||||
@@ -2,7 +2,6 @@ package wv2runtime
|
||||
|
||||
import (
|
||||
"github.com/leaanthony/go-webview2/webviewloader"
|
||||
"github.com/leaanthony/webview2runtime"
|
||||
)
|
||||
|
||||
const MinimumRuntimeVersion string = "91.0.992.28"
|
||||
@@ -15,14 +14,17 @@ const (
|
||||
installed
|
||||
)
|
||||
|
||||
func Process() (*webview2runtime.Info, error) {
|
||||
func Process() (string, error) {
|
||||
installStatus := needsInstalling
|
||||
installedVersion := webview2runtime.GetInstalledVersion()
|
||||
if installedVersion != nil {
|
||||
installedVersion, err := webviewloader.GetInstalledVersion()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if installedVersion != "" {
|
||||
installStatus = installed
|
||||
compareResult, err := webviewloader.CompareBrowserVersions(installedVersion.Version, MinimumRuntimeVersion)
|
||||
compareResult, err := webviewloader.CompareBrowserVersions(installedVersion, MinimumRuntimeVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
updateRequired := compareResult == -1
|
||||
// Installed and does not require updating
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
//+build windows
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ffenestri
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/leaanthony/slicer"
|
||||
"github.com/wailsapp/wails/v2/internal/menumanager"
|
||||
"os"
|
||||
"sync"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/leaanthony/slicer"
|
||||
"github.com/wailsapp/wails/v2/internal/menumanager"
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------------------------
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//+build windows,debug
|
||||
//go:build windows && debug
|
||||
// +build windows,debug
|
||||
|
||||
package ffenestri
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows && !debug
|
||||
// +build windows,!debug
|
||||
|
||||
package ffenestri
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//+build windows
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ffenestri
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//+build windows
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ffenestri
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//+build windows
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ffenestri
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//+build windows
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ffenestri
|
||||
|
||||
|
||||
@@ -5,11 +5,13 @@ package assetserver
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/runtime"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"golang.org/x/net/html"
|
||||
"path/filepath"
|
||||
"context"
|
||||
"io/fs"
|
||||
"strings"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -19,35 +21,41 @@ It injects a websocket based IPC script into `index.html`.
|
||||
|
||||
*/
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
type BrowserAssetServer struct {
|
||||
runtimeJS []byte
|
||||
assetdir string
|
||||
appOptions *options.App
|
||||
assets fs.FS
|
||||
runtimeJS []byte
|
||||
logger *logger.Logger
|
||||
}
|
||||
|
||||
func NewBrowserAssetServer(assetdir string, bindingsJSON string, appOptions *options.App) (*BrowserAssetServer, error) {
|
||||
result := &BrowserAssetServer{
|
||||
assetdir: assetdir,
|
||||
appOptions: appOptions,
|
||||
func NewBrowserAssetServer(ctx context.Context, assets fs.FS, bindingsJSON string) (*BrowserAssetServer, error) {
|
||||
result := &BrowserAssetServer{}
|
||||
_logger := ctx.Value("logger")
|
||||
if _logger != nil {
|
||||
result.logger = _logger.(*logger.Logger)
|
||||
}
|
||||
|
||||
var err error
|
||||
result.assets, err = prepareAssetsForServing(assets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var buffer bytes.Buffer
|
||||
buffer.WriteString(`window.wailsbindings='` + bindingsJSON + `';` + "\n")
|
||||
buffer.Write(runtime.RuntimeDesktopJS)
|
||||
result.runtimeJS = buffer.Bytes()
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (a *BrowserAssetServer) loadFileFromDisk(filename string) ([]byte, error) {
|
||||
return os.ReadFile(filepath.Join(a.assetdir, filename))
|
||||
func (d *BrowserAssetServer) LogDebug(message string, args ...interface{}) {
|
||||
if d.logger != nil {
|
||||
d.logger.Debug("[BrowserAssetServer] "+message, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *BrowserAssetServer) processIndexHTML() ([]byte, error) {
|
||||
indexHTML, err := a.loadFileFromDisk("index.html")
|
||||
indexHTML, err := fs.ReadFile(a.assets, "index.html")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -97,15 +105,9 @@ func (a *BrowserAssetServer) Load(filename string) ([]byte, string, error) {
|
||||
case "/wails/ipc.js":
|
||||
content = runtime.WebsocketIPC
|
||||
default:
|
||||
content, err = a.loadFileFromDisk(filename)
|
||||
if strings.HasSuffix(filename, ".js") {
|
||||
var buffer bytes.Buffer
|
||||
buffer.WriteString("window.awaitIPC('" + filename + "', ()=>{")
|
||||
buffer.Write(content)
|
||||
buffer.WriteString(`
|
||||
});`)
|
||||
content = buffer.Bytes()
|
||||
}
|
||||
filename = strings.TrimPrefix(filename, "/")
|
||||
a.LogDebug("Loading file: %s", filename)
|
||||
content, err = fs.ReadFile(a.assets, filename)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
|
||||
25
v2/internal/frontend/assetserver/assetserver_common.go
Normal file
25
v2/internal/frontend/assetserver/assetserver_common.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package assetserver
|
||||
|
||||
import (
|
||||
iofs "io/fs"
|
||||
"path"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/fs"
|
||||
)
|
||||
|
||||
func prepareAssetsForServing(assets iofs.FS) (iofs.FS, error) {
|
||||
if _, err := assets.Open("."); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
subDir, err := fs.FindPathToFile(assets, "index.html")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
assets, err = iofs.Sub(assets, path.Clean(subDir))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return assets, nil
|
||||
}
|
||||
@@ -3,26 +3,21 @@ package assetserver
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"embed"
|
||||
"fmt"
|
||||
"github.com/leaanthony/debme"
|
||||
"github.com/leaanthony/slicer"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"io/fs"
|
||||
"log"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
)
|
||||
|
||||
type DesktopAssetServer struct {
|
||||
assets debme.Debme
|
||||
assets fs.FS
|
||||
runtimeJS []byte
|
||||
assetdir string
|
||||
logger *logger.Logger
|
||||
}
|
||||
|
||||
func NewDesktopAssetServer(ctx context.Context, assets embed.FS, bindingsJSON string) (*DesktopAssetServer, error) {
|
||||
func NewDesktopAssetServer(ctx context.Context, assets fs.FS, bindingsJSON string) (*DesktopAssetServer, error) {
|
||||
result := &DesktopAssetServer{}
|
||||
|
||||
_logger := ctx.Value("logger")
|
||||
@@ -30,22 +25,18 @@ func NewDesktopAssetServer(ctx context.Context, assets embed.FS, bindingsJSON st
|
||||
result.logger = _logger.(*logger.Logger)
|
||||
}
|
||||
|
||||
_assetdir := ctx.Value("assetdir")
|
||||
if _assetdir != nil {
|
||||
result.assetdir = _assetdir.(string)
|
||||
absdir, err := filepath.Abs(result.assetdir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.LogDebug("Loading assets from: %s", absdir)
|
||||
var err error
|
||||
result.assets, err = prepareAssetsForServing(assets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var buffer bytes.Buffer
|
||||
buffer.WriteString(`window.wailsbindings='` + bindingsJSON + `';` + "\n")
|
||||
buffer.Write(runtime.RuntimeDesktopJS)
|
||||
result.runtimeJS = buffer.Bytes()
|
||||
err := result.init(assets)
|
||||
return result, err
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (d *DesktopAssetServer) LogDebug(message string, args ...interface{}) {
|
||||
@@ -54,63 +45,8 @@ func (d *DesktopAssetServer) LogDebug(message string, args ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DesktopAssetServer) SetAssetDir(assetdir string) {
|
||||
d.assetdir = assetdir
|
||||
}
|
||||
|
||||
func PathToIndexHTML(assets embed.FS) (string, error) {
|
||||
stat, err := fs.Stat(assets, "index.html")
|
||||
if stat != nil {
|
||||
return ".", nil
|
||||
}
|
||||
var indexFiles slicer.StringSlicer
|
||||
err = fs.WalkDir(assets, ".", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.HasSuffix(path, "index.html") {
|
||||
indexFiles.Add(path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if indexFiles.Length() > 1 {
|
||||
return "", fmt.Errorf("multiple 'index.html' files found in assets")
|
||||
}
|
||||
|
||||
path, _ := filepath.Split(indexFiles.AsSlice()[0])
|
||||
return path, nil
|
||||
}
|
||||
|
||||
func processAssets(assets embed.FS) (debme.Debme, error) {
|
||||
|
||||
result, err := debme.FS(assets, ".")
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
// Find index.html
|
||||
path, err := PathToIndexHTML(assets)
|
||||
if err != nil {
|
||||
return debme.Debme{}, err
|
||||
}
|
||||
return debme.FS(assets, path)
|
||||
}
|
||||
|
||||
func (a *DesktopAssetServer) init(assets embed.FS) error {
|
||||
|
||||
var err error
|
||||
a.assets, err = processAssets(assets)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *DesktopAssetServer) processIndexHTML() ([]byte, error) {
|
||||
indexHTML, err := a.ReadFile("index.html")
|
||||
indexHTML, err := fs.ReadFile(a.assets, "index.html")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -146,7 +82,9 @@ func (a *DesktopAssetServer) Load(filename string) ([]byte, string, error) {
|
||||
case "/wails/ipc.js":
|
||||
content = runtime.DesktopIPC
|
||||
default:
|
||||
content, err = a.ReadFile(filename)
|
||||
filename = strings.TrimPrefix(filename, "/")
|
||||
a.LogDebug("Loading file: %s", filename)
|
||||
content, err = fs.ReadFile(a.assets, filename)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
//go:build dev
|
||||
|
||||
package assetserver
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func (a *DesktopAssetServer) ReadFile(filename string) ([]byte, error) {
|
||||
a.LogDebug("Loading file from disk: %s", filename)
|
||||
return os.ReadFile(filepath.Join(a.assetdir, filename))
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
//go:build production
|
||||
|
||||
package assetserver
|
||||
|
||||
func (a *DesktopAssetServer) ReadFile(filename string) ([]byte, error) {
|
||||
return a.assets.ReadFile(filename)
|
||||
}
|
||||
20
v2/internal/frontend/desktop/common/uri_translate.go
Normal file
20
v2/internal/frontend/desktop/common/uri_translate.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package common
|
||||
|
||||
import "net/url"
|
||||
|
||||
func TranslateUriToFile(uri string, expectedScheme string, expectedHost string) (file string, match bool, err error) {
|
||||
url, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
|
||||
if url.Scheme != expectedScheme || url.Host != expectedHost {
|
||||
return "", false, nil
|
||||
}
|
||||
|
||||
filePath := url.Path
|
||||
if filePath == "" {
|
||||
filePath = "/"
|
||||
}
|
||||
return filePath, true, nil
|
||||
}
|
||||
@@ -41,7 +41,7 @@ void Quit(void*);
|
||||
const char* GetSize(void *ctx);
|
||||
const char* GetPos(void *ctx);
|
||||
|
||||
void ProcessURLResponse(void *inctx, const char *url, const char *contentType, void* data, int datalength);
|
||||
void ProcessURLResponse(void *inctx, const char *url, int statusCode, const char *contentType, void* data, int datalength);
|
||||
|
||||
/* Dialogs */
|
||||
|
||||
|
||||
@@ -51,13 +51,15 @@ WailsContext* Create(const char* title, int width, int height, int frameless, in
|
||||
return result;
|
||||
}
|
||||
|
||||
void ProcessURLResponse(void *inctx, const char *url, const char *contentType, void* data, int datalength) {
|
||||
void ProcessURLResponse(void *inctx, const char *url, int statusCode, const char *contentType, void* data, int datalength) {
|
||||
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||
NSString *nsurl = safeInit(url);
|
||||
NSString *nsContentType = safeInit(contentType);
|
||||
NSData *nsdata = [NSData dataWithBytes:data length:datalength];
|
||||
|
||||
[ctx processURLResponse:nsurl :nsContentType :nsdata];
|
||||
[ctx processURLResponse:nsurl :statusCode :nsContentType :nsdata];
|
||||
|
||||
[nsdata release];
|
||||
}
|
||||
|
||||
void ExecJS(void* inctx, const char *script) {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
#if __has_include(<UniformTypeIdentifiers/UTType.h>)
|
||||
#define USE_NEW_FILTERS
|
||||
#import <UniformTypeIdentifiers/UTType.h>
|
||||
#endif
|
||||
|
||||
@@ -79,7 +80,7 @@
|
||||
- (void) SaveFileDialog :(NSString*)title :(NSString*)defaultFilename :(NSString*)defaultDirectory :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)showHiddenFiles :(NSString*)filters;
|
||||
|
||||
- (void) loadRequest:(NSString*)url;
|
||||
- (void) processURLResponse:(NSString *)url :(NSString *)contentType :(NSData*)data;
|
||||
- (void) processURLResponse:(NSString *)url :(int)statusCode :(NSString *)contentType :(NSData*)data;
|
||||
- (void) ExecJS:(NSString*)script;
|
||||
- (NSScreen*) getCurrentScreen;
|
||||
|
||||
|
||||
@@ -376,12 +376,14 @@
|
||||
[self.webview evaluateJavaScript:script completionHandler:nil];
|
||||
}
|
||||
|
||||
- (void) processURLResponse:(NSString *)url :(NSString *)contentType :(NSData *)data {
|
||||
- (void) processURLResponse:(NSString *)url :(int)statusCode :(NSString *)contentType :(NSData *)data {
|
||||
id<WKURLSchemeTask> urlSchemeTask = self.urlRequests[url];
|
||||
NSURL *nsurl = [NSURL URLWithString:url];
|
||||
NSMutableDictionary *headerFields = [NSMutableDictionary new];
|
||||
headerFields[@"content-type"] = contentType;
|
||||
NSHTTPURLResponse *response = [[NSHTTPURLResponse new] initWithURL:nsurl statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:headerFields];
|
||||
if ( ![contentType isEqualToString:@""] ) {
|
||||
headerFields[@"content-type"] = contentType;
|
||||
}
|
||||
NSHTTPURLResponse *response = [[NSHTTPURLResponse new] initWithURL:nsurl statusCode:statusCode HTTPVersion:@"HTTP/1.1" headerFields:headerFields];
|
||||
[urlSchemeTask didReceiveResponse:response];
|
||||
[urlSchemeTask didReceiveData:data];
|
||||
[urlSchemeTask didFinish];
|
||||
@@ -495,16 +497,20 @@
|
||||
filters = [filters stringByReplacingOccurrencesOfString:@"*." withString:@""];
|
||||
filters = [filters stringByReplacingOccurrencesOfString:@" " withString:@""];
|
||||
NSArray *filterList = [filters componentsSeparatedByString:@";"];
|
||||
if (@available(macOS 10.16, *)) {
|
||||
#ifdef USE_NEW_FILTERS
|
||||
NSMutableArray *contentTypes = [[NSMutableArray new] autorelease];
|
||||
for (NSString *filter in filterList) {
|
||||
UTType *t = [UTType typeWithFilenameExtension:filter];
|
||||
[contentTypes addObject:t];
|
||||
if (@available(macOS 11.0, *)) {
|
||||
UTType *t = [UTType typeWithFilenameExtension:filter];
|
||||
[contentTypes addObject:t];
|
||||
}
|
||||
}
|
||||
if (@available(macOS 11.0, *)) {
|
||||
[dialog setAllowedContentTypes:contentTypes];
|
||||
} else {
|
||||
[dialog setAllowedFileTypes:filterList];
|
||||
}
|
||||
#else
|
||||
[dialog setAllowedFileTypes:filterList];
|
||||
#endif
|
||||
} else {
|
||||
[dialog setAllowsOtherFileTypes:true];
|
||||
}
|
||||
@@ -534,6 +540,10 @@
|
||||
|
||||
// Setup callback handler
|
||||
[dialog beginSheetModalForWindow:self.mainWindow completionHandler:^(NSModalResponse returnCode) {
|
||||
if ( returnCode != NSModalResponseOK) {
|
||||
processOpenFileDialogResponse("[]");
|
||||
return;
|
||||
}
|
||||
NSMutableArray *arr = [NSMutableArray new];
|
||||
for (NSURL *url in [dialog URLs]) {
|
||||
[arr addObject:[url path]];
|
||||
@@ -552,7 +562,7 @@
|
||||
|
||||
|
||||
// Create the dialog
|
||||
NSSavePanel *dialog = [NSOpenPanel savePanel];
|
||||
NSSavePanel *dialog = [NSSavePanel savePanel];
|
||||
|
||||
// Valid but appears to do nothing.... :/
|
||||
if( title != nil ) {
|
||||
@@ -560,7 +570,7 @@
|
||||
}
|
||||
|
||||
// Filters - semicolon delimited list of file extensions
|
||||
if( filters != nil ) {
|
||||
if( filters != nil && [filters length] > 0) {
|
||||
filters = [filters stringByReplacingOccurrencesOfString:@"*." withString:@""];
|
||||
filters = [filters stringByReplacingOccurrencesOfString:@" " withString:@""];
|
||||
NSArray *filterList = [filters componentsSeparatedByString:@";"];
|
||||
@@ -586,10 +596,12 @@
|
||||
|
||||
// Setup callback handler
|
||||
[dialog beginSheetModalForWindow:self.mainWindow completionHandler:^(NSModalResponse returnCode) {
|
||||
NSURL *url = [dialog URL];
|
||||
if ( url != nil ) {
|
||||
processSaveFileDialogResponse([url.path UTF8String]);
|
||||
return;
|
||||
if ( returnCode == NSModalResponseOK ) {
|
||||
NSURL *url = [dialog URL];
|
||||
if ( url != nil ) {
|
||||
processSaveFileDialogResponse([url.path UTF8String]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
processSaveFileDialogResponse("");
|
||||
}];
|
||||
|
||||
@@ -43,14 +43,16 @@
|
||||
- (WailsMenu*) initWithNSTitle:(NSString *)title {
|
||||
if( title != nil ) {
|
||||
[super initWithTitle:title];
|
||||
} else {
|
||||
[self init];
|
||||
}
|
||||
[self setAutoenablesItems:NO];
|
||||
return [self init];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) appendSubmenu :(WailsMenu*)child {
|
||||
NSMenuItem *childMenuItem = [[NSMenuItem new] autorelease];
|
||||
[childMenuItem setTitle:[child title]];
|
||||
[childMenuItem setTitle:child.title];
|
||||
[self addItem:childMenuItem];
|
||||
[childMenuItem setSubmenu:child];
|
||||
}
|
||||
|
||||
@@ -12,16 +12,15 @@
|
||||
#import "WailsContext.h"
|
||||
|
||||
@implementation WindowDelegate
|
||||
|
||||
- (BOOL)windowShouldClose:(WailsWindow *)sender {
|
||||
[sender orderOut:nil];
|
||||
if( self.hideOnClose == false ) {
|
||||
processMessage("Q");
|
||||
if( self.hideOnClose ) {
|
||||
[NSApp hide:nil];
|
||||
return false;
|
||||
}
|
||||
return !self.hideOnClose;
|
||||
processMessage("Q");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
- (void)windowDidExitFullScreen:(NSNotification *)notification {
|
||||
[self.ctx.mainWindow applyWindowConstraints];
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ func (f *Frontend) openDialog(options *frontend.OpenDialogOptions, multiple bool
|
||||
|
||||
// OpenFileDialog prompts the user to select a file
|
||||
func (f *Frontend) OpenFileDialog(options frontend.OpenDialogOptions) (string, error) {
|
||||
results, err := f.openDialog(&options, false, options.AllowFiles, options.AllowDirectories)
|
||||
results, err := f.openDialog(&options, false, true, false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -97,7 +97,7 @@ func (f *Frontend) OpenFileDialog(options frontend.OpenDialogOptions) (string, e
|
||||
|
||||
// OpenMultipleFilesDialog prompts the user to select a file
|
||||
func (f *Frontend) OpenMultipleFilesDialog(options frontend.OpenDialogOptions) ([]string, error) {
|
||||
return f.openDialog(&options, true, options.AllowFiles, options.AllowDirectories)
|
||||
return f.openDialog(&options, true, true, false)
|
||||
}
|
||||
|
||||
// SaveFileDialog prompts the user to select a file
|
||||
|
||||
@@ -5,7 +5,7 @@ package darwin
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -x objective-c
|
||||
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit -framework UniformTypeIdentifiers
|
||||
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "Application.h"
|
||||
#import "WailsContext.h"
|
||||
@@ -16,15 +16,17 @@ import "C"
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/assetserver"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/common"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
@@ -204,6 +206,9 @@ func (f *Frontend) WindowSetRGBA(col *options.RGBA) {
|
||||
}
|
||||
|
||||
func (f *Frontend) Quit() {
|
||||
if f.frontendOptions.OnBeforeClose != nil && f.frontendOptions.OnBeforeClose(f.ctx) {
|
||||
return
|
||||
}
|
||||
f.mainWindow.Quit()
|
||||
}
|
||||
|
||||
@@ -239,23 +244,26 @@ func (f *Frontend) processMessage(message string) {
|
||||
// return
|
||||
//}
|
||||
|
||||
result, err := f.dispatcher.ProcessMessage(message, f)
|
||||
if err != nil {
|
||||
f.logger.Error(err.Error())
|
||||
f.Callback(result)
|
||||
return
|
||||
}
|
||||
if result == "" {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
result, err := f.dispatcher.ProcessMessage(message, f)
|
||||
if err != nil {
|
||||
f.logger.Error(err.Error())
|
||||
f.Callback(result)
|
||||
return
|
||||
}
|
||||
if result == "" {
|
||||
return
|
||||
}
|
||||
|
||||
switch result[0] {
|
||||
case 'c':
|
||||
// Callback from a method call
|
||||
f.Callback(result[1:])
|
||||
default:
|
||||
f.logger.Info("Unknown message returned from dispatcher: %+v", result)
|
||||
}
|
||||
}()
|
||||
|
||||
switch result[0] {
|
||||
case 'c':
|
||||
// Callback from a method call
|
||||
f.Callback(result[1:])
|
||||
default:
|
||||
f.logger.Info("Unknown message returned from dispatcher: %+v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Frontend) Callback(message string) {
|
||||
@@ -267,17 +275,34 @@ func (f *Frontend) ExecJS(js string) {
|
||||
}
|
||||
|
||||
func (f *Frontend) processRequest(r *request) {
|
||||
url := C.GoString(r.url)
|
||||
url = strings.TrimPrefix(url, "wails://wails")
|
||||
if !strings.HasPrefix(url, "/") {
|
||||
return
|
||||
uri := C.GoString(r.url)
|
||||
|
||||
var _contents []byte
|
||||
var _mimetype string
|
||||
|
||||
// Translate URI to file
|
||||
file, match, err := common.TranslateUriToFile(uri, "wails", "wails")
|
||||
if err == nil {
|
||||
if !match {
|
||||
// This should never happen on darwin, because we get only called for wails://
|
||||
panic("Unexpected host for request on wails:// scheme")
|
||||
}
|
||||
|
||||
// Load file from asset store
|
||||
_contents, _mimetype, err = f.assets.Load(file)
|
||||
}
|
||||
_contents, _mimetype, err := f.assets.Load(url)
|
||||
|
||||
statusCode := 200
|
||||
if err != nil {
|
||||
f.logger.Error(err.Error())
|
||||
//TODO: Handle errors
|
||||
return
|
||||
if os.IsNotExist(err) {
|
||||
statusCode = 404
|
||||
} else {
|
||||
err = fmt.Errorf("Error processing request %s: %w", uri, err)
|
||||
f.logger.Error(err.Error())
|
||||
statusCode = 500
|
||||
}
|
||||
}
|
||||
|
||||
var data unsafe.Pointer
|
||||
if _contents != nil {
|
||||
data = unsafe.Pointer(&_contents[0])
|
||||
@@ -285,7 +310,7 @@ func (f *Frontend) processRequest(r *request) {
|
||||
mimetype := C.CString(_mimetype)
|
||||
defer C.free(unsafe.Pointer(mimetype))
|
||||
|
||||
C.ProcessURLResponse(r.ctx, r.url, mimetype, data, C.int(len(_contents)))
|
||||
C.ProcessURLResponse(r.ctx, r.url, C.int(statusCode), mimetype, data, C.int(len(_contents)))
|
||||
}
|
||||
|
||||
//func (f *Frontend) processSystemEvent(message string) {
|
||||
|
||||
@@ -32,7 +32,8 @@ void processCallback(int callbackID) {
|
||||
void processURLRequest(void *ctx, const char* url) {
|
||||
NSLog(@"processURLRequest called");
|
||||
const char myByteArray[] = { 0x3c,0x68,0x31,0x3e,0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,0x72,0x6c,0x64,0x21,0x3c,0x2f,0x68,0x31,0x3e };
|
||||
ProcessURLResponse(ctx, url, "text/html", (void*)myByteArray, 21);
|
||||
// void *inctx, const char *url, int statusCode, const char *contentType, void* data, int datalength
|
||||
ProcessURLResponse(ctx, url, 200, "text/html", (void*)myByteArray, 21);
|
||||
}
|
||||
|
||||
unsigned char _Users_username_Pictures_SaltBae_png[] = {
|
||||
|
||||
32
v2/internal/frontend/desktop/linux/calloc.go
Normal file
32
v2/internal/frontend/desktop/linux/calloc.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package linux
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
// Calloc handles alloc/dealloc of C data
|
||||
type Calloc struct {
|
||||
pool []unsafe.Pointer
|
||||
}
|
||||
|
||||
// NewCalloc creates a new allocator
|
||||
func NewCalloc() Calloc {
|
||||
return Calloc{}
|
||||
}
|
||||
|
||||
// String creates a new C string and retains a reference to it
|
||||
func (c Calloc) String(in string) *C.char {
|
||||
result := C.CString(in)
|
||||
c.pool = append(c.pool, unsafe.Pointer(result))
|
||||
return result
|
||||
}
|
||||
|
||||
// Free frees all allocated C memory
|
||||
func (c Calloc) Free() {
|
||||
for _, str := range c.pool {
|
||||
C.free(str)
|
||||
}
|
||||
c.pool = []unsafe.Pointer{}
|
||||
}
|
||||
@@ -3,10 +3,24 @@
|
||||
|
||||
package linux
|
||||
|
||||
import "github.com/wailsapp/wails/v2/internal/frontend"
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
)
|
||||
import "C"
|
||||
|
||||
func (f *Frontend) OpenFileDialog(dialogOptions frontend.OpenDialogOptions) (string, error) {
|
||||
panic("implement me")
|
||||
var openFileResults = make(chan string)
|
||||
|
||||
func (f *Frontend) OpenFileDialog(dialogOptions frontend.OpenDialogOptions) (result string, err error) {
|
||||
|
||||
f.dispatch(func() {
|
||||
println("Before OpenFileDialog")
|
||||
f.mainWindow.OpenFileDialog(dialogOptions)
|
||||
println("After OpenFileDialog")
|
||||
})
|
||||
println("Waiting for result")
|
||||
result = <-openFileResults
|
||||
println("Got result")
|
||||
return
|
||||
}
|
||||
|
||||
func (f *Frontend) OpenMultipleFilesDialog(dialogOptions frontend.OpenDialogOptions) ([]string, error) {
|
||||
@@ -24,3 +38,8 @@ func (f *Frontend) SaveFileDialog(dialogOptions frontend.SaveDialogOptions) (str
|
||||
func (f *Frontend) MessageDialog(dialogOptions frontend.MessageDialogOptions) (string, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
//export processOpenFileResult
|
||||
func processOpenFileResult(result *C.char) {
|
||||
openFileResults <- C.GoString(result)
|
||||
}
|
||||
|
||||
@@ -3,20 +3,41 @@
|
||||
|
||||
package linux
|
||||
|
||||
/*
|
||||
#cgo linux pkg-config: gtk+-3.0 webkit2gtk-4.0
|
||||
|
||||
#include "gtk/gtk.h"
|
||||
#include "webkit2/webkit2.h"
|
||||
|
||||
extern void callDispatchedMethod(int id);
|
||||
|
||||
static inline void processDispatchID(gpointer id) {
|
||||
callDispatchedMethod(GPOINTER_TO_INT(id));
|
||||
}
|
||||
|
||||
static void gtkDispatch(int id) {
|
||||
gdk_threads_add_idle((GSourceFunc)processDispatchID, GINT_TO_POINTER(id));
|
||||
}
|
||||
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
"text/template"
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/assetserver"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/common"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
|
||||
"github.com/gotk3/gotk3/gtk"
|
||||
)
|
||||
|
||||
type Frontend struct {
|
||||
@@ -33,25 +54,25 @@ type Frontend struct {
|
||||
startURL string
|
||||
|
||||
// main window handle
|
||||
mainWindow *Window
|
||||
minWidth, minHeight, maxWidth, maxHeight int
|
||||
bindings *binding.Bindings
|
||||
dispatcher frontend.Dispatcher
|
||||
servingFromDisk bool
|
||||
mainWindow *Window
|
||||
// minWidth, minHeight, maxWidth, maxHeight int
|
||||
bindings *binding.Bindings
|
||||
dispatcher frontend.Dispatcher
|
||||
servingFromDisk bool
|
||||
}
|
||||
|
||||
func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher) *Frontend {
|
||||
|
||||
println("[NewFrontend] PID:", os.Getpid())
|
||||
// Set GDK_BACKEND=x11 to prevent warnings
|
||||
os.Setenv("GDK_BACKEND", "x11")
|
||||
|
||||
result := &Frontend{
|
||||
frontendOptions: appoptions,
|
||||
logger: myLogger,
|
||||
bindings: appBindings,
|
||||
dispatcher: dispatcher,
|
||||
ctx: ctx,
|
||||
minHeight: appoptions.MinHeight,
|
||||
minWidth: appoptions.MinWidth,
|
||||
maxHeight: appoptions.MaxHeight,
|
||||
maxWidth: appoptions.MaxWidth,
|
||||
startURL: "file://wails/",
|
||||
}
|
||||
|
||||
@@ -72,7 +93,7 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.
|
||||
// Check if we have been given a directory to serve assets from.
|
||||
// If so, this means we are in dev mode and are serving assets off disk.
|
||||
// We indicate this through the `servingFromDisk` flag to ensure requests
|
||||
// aren't cached by WebView2 in dev mode
|
||||
// aren't cached by webkit.
|
||||
|
||||
_assetdir := ctx.Value("assetdir")
|
||||
if _assetdir != nil {
|
||||
@@ -85,12 +106,26 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.
|
||||
}
|
||||
result.assets = assets
|
||||
|
||||
// Initialise GTK
|
||||
gtk.Init(nil)
|
||||
go result.startMessageProcessor()
|
||||
go result.startRequestProcessor()
|
||||
|
||||
C.gtk_init(nil, nil)
|
||||
|
||||
var _debug = ctx.Value("debug")
|
||||
if _debug != nil {
|
||||
result.debug = _debug.(bool)
|
||||
}
|
||||
result.mainWindow = NewWindow(appoptions, result.debug)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (f *Frontend) startMessageProcessor() {
|
||||
for message := range messageBuffer {
|
||||
f.processMessage(message)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Frontend) WindowReload() {
|
||||
f.ExecJS("runtime.WindowReload();")
|
||||
}
|
||||
@@ -99,41 +134,14 @@ func (f *Frontend) Run(ctx context.Context) error {
|
||||
|
||||
f.ctx = context.WithValue(ctx, "frontend", f)
|
||||
|
||||
mainWindow := NewWindow(f.frontendOptions)
|
||||
f.mainWindow = mainWindow
|
||||
|
||||
var _debug = ctx.Value("debug")
|
||||
if _debug != nil {
|
||||
f.debug = _debug.(bool)
|
||||
}
|
||||
|
||||
//f.WindowCenter()
|
||||
//f.setupChromium()
|
||||
//
|
||||
//gtkWindow.OnSize().Bind(func(arg *winc.Event) {
|
||||
// f.chromium.Resize()
|
||||
//})
|
||||
//
|
||||
//gtkWindow.OnClose().Bind(func(arg *winc.Event) {
|
||||
// if f.frontendOptions.HideWindowOnClose {
|
||||
// f.WindowHide()
|
||||
// } else {
|
||||
// f.Quit()
|
||||
// }
|
||||
//})
|
||||
|
||||
go func() {
|
||||
if f.frontendOptions.OnStartup != nil {
|
||||
f.frontendOptions.OnStartup(f.ctx)
|
||||
}
|
||||
}()
|
||||
|
||||
if f.frontendOptions.Fullscreen {
|
||||
mainWindow.Fullscreen()
|
||||
}
|
||||
f.mainWindow.Run()
|
||||
|
||||
mainWindow.Run()
|
||||
mainWindow.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -157,19 +165,15 @@ func (f *Frontend) WindowGetSize() (int, int) {
|
||||
}
|
||||
|
||||
func (f *Frontend) WindowSetTitle(title string) {
|
||||
f.mainWindow.SetText(title)
|
||||
f.mainWindow.SetTitle(title)
|
||||
}
|
||||
|
||||
func (f *Frontend) WindowFullscreen() {
|
||||
f.mainWindow.SetMaxSize(0, 0)
|
||||
f.mainWindow.SetMinSize(0, 0)
|
||||
f.mainWindow.Fullscreen()
|
||||
}
|
||||
|
||||
func (f *Frontend) WindowUnFullscreen() {
|
||||
f.mainWindow.UnFullscreen()
|
||||
f.mainWindow.SetMaxSize(f.maxWidth, f.maxHeight)
|
||||
f.mainWindow.SetMinSize(f.minWidth, f.minHeight)
|
||||
}
|
||||
|
||||
func (f *Frontend) WindowShow() {
|
||||
@@ -193,13 +197,9 @@ func (f *Frontend) WindowUnminimise() {
|
||||
}
|
||||
|
||||
func (f *Frontend) WindowSetMinSize(width int, height int) {
|
||||
f.minWidth = width
|
||||
f.minHeight = height
|
||||
f.mainWindow.SetMinSize(width, height)
|
||||
}
|
||||
func (f *Frontend) WindowSetMaxSize(width int, height int) {
|
||||
f.maxWidth = width
|
||||
f.maxHeight = height
|
||||
f.mainWindow.SetMaxSize(width, height)
|
||||
}
|
||||
|
||||
@@ -207,87 +207,15 @@ func (f *Frontend) WindowSetRGBA(col *options.RGBA) {
|
||||
if col == nil {
|
||||
return
|
||||
}
|
||||
//
|
||||
//f.gtkWindow.Dispatch(func() {
|
||||
// controller := f.chromium.GetController()
|
||||
// controller2 := controller.GetICoreWebView2Controller2()
|
||||
//
|
||||
// backgroundCol := edge.COREWEBVIEW2_COLOR{
|
||||
// A: col.A,
|
||||
// R: col.R,
|
||||
// G: col.G,
|
||||
// B: col.B,
|
||||
// }
|
||||
//
|
||||
// // Webview2 only has 0 and 255 as valid values.
|
||||
// if backgroundCol.A > 0 && backgroundCol.A < 255 {
|
||||
// backgroundCol.A = 255
|
||||
// }
|
||||
//
|
||||
// if f.frontendOptions.Windows != nil && f.frontendOptions.Windows.WebviewIsTransparent {
|
||||
// backgroundCol.A = 0
|
||||
// }
|
||||
//
|
||||
// err := controller2.PutDefaultBackgroundColor(backgroundCol)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
//})
|
||||
}
|
||||
|
||||
func (f *Frontend) Quit() {
|
||||
//winc.Exit()
|
||||
if f.frontendOptions.OnBeforeClose != nil && f.frontendOptions.OnBeforeClose(f.ctx) {
|
||||
return
|
||||
}
|
||||
f.mainWindow.Quit()
|
||||
}
|
||||
|
||||
//func (f *Frontend) setupChromium() {
|
||||
// chromium := edge.NewChromium()
|
||||
// f.chromium = chromium
|
||||
// chromium.MessageCallback = f.processMessage
|
||||
// chromium.WebResourceRequestedCallback = f.processRequest
|
||||
// chromium.NavigationCompletedCallback = f.navigationCompleted
|
||||
// chromium.AcceleratorKeyCallback = func(vkey uint) bool {
|
||||
// w32.PostMessage(f.gtkWindow.Handle(), w32.WM_KEYDOWN, uintptr(vkey), 0)
|
||||
// return false
|
||||
// }
|
||||
// chromium.Embed(f.gtkWindow.Handle())
|
||||
// chromium.Resize()
|
||||
// settings, err := chromium.GetSettings()
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// err = settings.PutAreDefaultContextMenusEnabled(f.debug)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// err = settings.PutAreDevToolsEnabled(f.debug)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// err = settings.PutIsZoomControlEnabled(false)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// err = settings.PutIsStatusBarEnabled(false)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// err = settings.PutAreBrowserAcceleratorKeysEnabled(false)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// err = settings.PutIsSwipeNavigationEnabled(false)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
//
|
||||
// // Set background colour
|
||||
// f.WindowSetRGBA(f.frontendOptions.RGBA)
|
||||
//
|
||||
// chromium.SetGlobalPermission(edge.CoreWebView2PermissionStateAllow)
|
||||
// chromium.AddWebResourceRequestedFilter("*", edge.COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL)
|
||||
// chromium.Navigate(f.startURL)
|
||||
//}
|
||||
|
||||
type EventNotify struct {
|
||||
Name string `json:"name"`
|
||||
Data []interface{} `json:"data"`
|
||||
@@ -306,96 +234,141 @@ func (f *Frontend) Notify(name string, data ...interface{}) {
|
||||
f.ExecJS(`window.wails.EventsNotify('` + template.JSEscapeString(string(payload)) + `');`)
|
||||
}
|
||||
|
||||
//func (f *Frontend) processRequest(req *edge.ICoreWebView2WebResourceRequest, args *edge.ICoreWebView2WebResourceRequestedEventArgs) {
|
||||
// //Get the request
|
||||
// uri, _ := req.GetUri()
|
||||
//
|
||||
// // Translate URI
|
||||
// uri = strings.TrimPrefix(uri, "file://wails")
|
||||
// if !strings.HasPrefix(uri, "/") {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// // Load file from asset store
|
||||
// content, mimeType, err := f.assets.Load(uri)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// env := f.chromium.Environment()
|
||||
// headers := "Content-Type: " + mimeType
|
||||
// if f.servingFromDisk {
|
||||
// headers += "\nPragma: no-cache"
|
||||
// }
|
||||
// response, err := env.CreateWebResourceResponse(content, 200, "OK", headers)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// // Send response back
|
||||
// err = args.PutResponse(response)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// return
|
||||
//}
|
||||
|
||||
func (f *Frontend) processMessage(message string) {
|
||||
if message == "drag" {
|
||||
if !f.mainWindow.IsFullScreen() {
|
||||
err := f.startDrag()
|
||||
if err != nil {
|
||||
f.logger.Error(err.Error())
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
result, err := f.dispatcher.ProcessMessage(message, f)
|
||||
if err != nil {
|
||||
f.logger.Error(err.Error())
|
||||
f.Callback(result)
|
||||
return
|
||||
}
|
||||
if result == "" {
|
||||
// if !f.mainWindow.IsFullScreen() {
|
||||
f.startDrag()
|
||||
// }
|
||||
return
|
||||
}
|
||||
|
||||
switch result[0] {
|
||||
case 'c':
|
||||
// Callback from a method call
|
||||
f.Callback(result[1:])
|
||||
default:
|
||||
f.logger.Info("Unknown message returned from dispatcher: %+v", result)
|
||||
}
|
||||
go func() {
|
||||
result, err := f.dispatcher.ProcessMessage(message, f)
|
||||
if err != nil {
|
||||
f.logger.Error(err.Error())
|
||||
f.Callback(result)
|
||||
return
|
||||
}
|
||||
if result == "" {
|
||||
return
|
||||
}
|
||||
|
||||
switch result[0] {
|
||||
case 'c':
|
||||
// Callback from a method call
|
||||
f.Callback(result[1:])
|
||||
default:
|
||||
f.logger.Info("Unknown message returned from dispatcher: %+v", result)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (f *Frontend) Callback(message string) {
|
||||
f.ExecJS(`window.wails.Callback(` + strconv.Quote(message) + `);`)
|
||||
}
|
||||
|
||||
func (f *Frontend) startDrag() error {
|
||||
//if !w32.ReleaseCapture() {
|
||||
// return fmt.Errorf("unable to release mouse capture")
|
||||
//}
|
||||
//w32.SendMessage(f.gtkWindow.Handle(), w32.WM_NCLBUTTONDOWN, w32.HTCAPTION, 0)
|
||||
return nil
|
||||
func (f *Frontend) startDrag() {
|
||||
f.dispatch(func() {
|
||||
f.mainWindow.StartDrag()
|
||||
})
|
||||
}
|
||||
|
||||
func (f *Frontend) ExecJS(js string) {
|
||||
//f.gtkWindow.Dispatch(func() {
|
||||
// f.chromium.Eval(js)
|
||||
//})
|
||||
f.dispatch(func() {
|
||||
f.mainWindow.ExecJS(js)
|
||||
})
|
||||
}
|
||||
|
||||
//func (f *Frontend) navigationCompleted(sender *edge.ICoreWebView2, args *edge.ICoreWebView2NavigationCompletedEventArgs) {
|
||||
// if f.frontendOptions.OnDomReady != nil {
|
||||
// go f.frontendOptions.OnDomReady(f.ctx)
|
||||
// }
|
||||
//
|
||||
// // If you want to start hidden, return
|
||||
// if f.frontendOptions.StartHidden {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// f.gtkWindow.Show()
|
||||
//
|
||||
//}
|
||||
func (f *Frontend) dispatch(fn func()) {
|
||||
dispatchCallbackLock.Lock()
|
||||
id := 0
|
||||
for fn := dispatchCallbacks[id]; fn != nil; id++ {
|
||||
}
|
||||
dispatchCallbacks[id] = fn
|
||||
dispatchCallbackLock.Unlock()
|
||||
C.gtkDispatch(C.int(id))
|
||||
}
|
||||
|
||||
var messageBuffer = make(chan string, 100)
|
||||
|
||||
//export processMessage
|
||||
func processMessage(message *C.char) {
|
||||
goMessage := C.GoString(message)
|
||||
messageBuffer <- goMessage
|
||||
}
|
||||
|
||||
// Map of functions passed to dispatch()
|
||||
var dispatchCallbacks = make(map[int]func())
|
||||
var dispatchCallbackLock sync.Mutex
|
||||
|
||||
//export callDispatchedMethod
|
||||
func callDispatchedMethod(cid C.int) {
|
||||
println("[callDispatchedMethod] PID:", os.Getpid())
|
||||
id := int(cid)
|
||||
fn := dispatchCallbacks[id]
|
||||
if fn != nil {
|
||||
fn()
|
||||
dispatchCallbackLock.Lock()
|
||||
delete(dispatchCallbacks, id)
|
||||
dispatchCallbackLock.Unlock()
|
||||
} else {
|
||||
println("Error: No dispatch method with id", id, cid)
|
||||
}
|
||||
}
|
||||
|
||||
var requestBuffer = make(chan unsafe.Pointer, 100)
|
||||
|
||||
func (f *Frontend) startRequestProcessor() {
|
||||
for request := range requestBuffer {
|
||||
f.processRequest(request)
|
||||
}
|
||||
}
|
||||
|
||||
//export processURLRequest
|
||||
func processURLRequest(request unsafe.Pointer) {
|
||||
requestBuffer <- request
|
||||
}
|
||||
|
||||
func (f *Frontend) processRequest(request unsafe.Pointer) {
|
||||
req := (*C.WebKitURISchemeRequest)(request)
|
||||
uri := C.webkit_uri_scheme_request_get_uri(req)
|
||||
goURI := C.GoString(uri)
|
||||
|
||||
file, match, err := common.TranslateUriToFile(goURI, "wails", "")
|
||||
if err != nil {
|
||||
// TODO Handle errors
|
||||
return
|
||||
} else if !match {
|
||||
// This should never happen on linux, because we get only called for wails://
|
||||
panic("Unexpected host for request on wails:// scheme")
|
||||
}
|
||||
|
||||
// Load file from asset store
|
||||
content, mimeType, err := f.assets.Load(file)
|
||||
|
||||
// TODO How to return 404/500 errors to webkit?
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
f.dispatch(func() {
|
||||
message := C.CString("not found")
|
||||
defer C.free(unsafe.Pointer(message))
|
||||
C.webkit_uri_scheme_request_finish_error(req, C.g_error_new_literal(C.G_FILE_ERROR_NOENT, C.int(404), message))
|
||||
})
|
||||
} else {
|
||||
err = fmt.Errorf("Error processing request %s: %w", uri, err)
|
||||
f.logger.Error(err.Error())
|
||||
message := C.CString("internal server error")
|
||||
defer C.free(unsafe.Pointer(message))
|
||||
C.webkit_uri_scheme_request_finish_error(req, C.g_error_new_literal(C.G_FILE_ERROR_NOENT, C.int(500), message))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
cContent := C.CString(string(content))
|
||||
defer C.free(unsafe.Pointer(cContent))
|
||||
cMimeType := C.CString(mimeType)
|
||||
defer C.free(unsafe.Pointer(cMimeType))
|
||||
cLen := C.long(len(content))
|
||||
stream := C.g_memory_input_stream_new_from_data(unsafe.Pointer(cContent), cLen, nil)
|
||||
C.webkit_uri_scheme_request_finish(req, stream, cLen, cMimeType)
|
||||
}
|
||||
|
||||
@@ -3,245 +3,450 @@
|
||||
|
||||
package linux
|
||||
|
||||
import (
|
||||
"github.com/gotk3/gotk3/gdk"
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/gotk3/gotk3/gtk"
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/linux"
|
||||
"log"
|
||||
"math"
|
||||
"sync"
|
||||
)
|
||||
/*
|
||||
#cgo linux pkg-config: gtk+-3.0 webkit2gtk-4.0 x11
|
||||
|
||||
type Window struct {
|
||||
frontendOptions *options.App
|
||||
applicationMenu *menu.Menu
|
||||
m sync.Mutex
|
||||
application *gtk.Application
|
||||
gtkWindow *gtk.ApplicationWindow
|
||||
#include "gtk/gtk.h"
|
||||
#include "webkit2/webkit2.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
//dispatchq []func()
|
||||
static GtkWidget* GTKWIDGET(void *pointer) {
|
||||
return GTK_WIDGET(pointer);
|
||||
}
|
||||
|
||||
func NewWindow(options *options.App) *Window {
|
||||
result := new(Window)
|
||||
result.frontendOptions = options
|
||||
static GtkWindow* GTKWINDOW(void *pointer) {
|
||||
return GTK_WINDOW(pointer);
|
||||
}
|
||||
|
||||
var linuxOptions linux.Options
|
||||
if options.Linux != nil {
|
||||
linuxOptions = *options.Linux
|
||||
static void SetMinSize(GtkWindow* window, int width, int height) {
|
||||
GdkGeometry size;
|
||||
size.min_height = height;
|
||||
size.min_width = width;
|
||||
gtk_window_set_geometry_hints(window, NULL, &size, GDK_HINT_MIN_SIZE);
|
||||
}
|
||||
|
||||
static void SetMaxSize(GtkWindow* window, int width, int height) {
|
||||
GdkGeometry size;
|
||||
if( width == 0 ) {
|
||||
width = INT_MAX;
|
||||
}
|
||||
appID := linuxOptions.AppID
|
||||
if appID == "" {
|
||||
appID = "io.wails"
|
||||
if( height == 0 ) {
|
||||
height = INT_MAX;
|
||||
}
|
||||
|
||||
println("AppID =", appID)
|
||||
size.max_height = height;
|
||||
size.max_width = width;
|
||||
gtk_window_set_geometry_hints(window, NULL, &size, GDK_HINT_MAX_SIZE);
|
||||
}
|
||||
|
||||
application, err := gtk.ApplicationNew(appID, glib.APPLICATION_FLAGS_NONE)
|
||||
if err != nil {
|
||||
log.Fatal("Could not create application:", err)
|
||||
GdkRectangle getCurrentMonitorGeometry(GtkWindow *window) {
|
||||
// Get the monitor that the window is currently on
|
||||
GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(window));
|
||||
GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(window));
|
||||
GdkMonitor *monitor = gdk_display_get_monitor_at_window (display, gdk_window);
|
||||
|
||||
// Get the geometry of the monitor
|
||||
GdkRectangle result;
|
||||
gdk_monitor_get_geometry (monitor,&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void SetPosition(GtkWindow *window, int x, int y) {
|
||||
GdkRectangle monitorDimensions = getCurrentMonitorGeometry(window);
|
||||
gtk_window_move(window, monitorDimensions.x + x, monitorDimensions.y + y);
|
||||
}
|
||||
|
||||
void Center(GtkWindow *window)
|
||||
{
|
||||
// Get the geometry of the monitor
|
||||
GdkRectangle m = getCurrentMonitorGeometry(window);
|
||||
|
||||
// Get the window width/height
|
||||
int windowWidth, windowHeight;
|
||||
gtk_window_get_size(window, &windowWidth, &windowHeight);
|
||||
|
||||
int newX = ((m.width - windowWidth) / 2) + m.x;
|
||||
int newY = ((m.height - windowHeight) / 2) + m.y;
|
||||
|
||||
// Place the window at the center of the monitor
|
||||
gtk_window_move(window, newX, newY);
|
||||
}
|
||||
|
||||
int IsFullscreen(GtkWidget *widget) {
|
||||
GdkWindow *gdkwindow = gtk_widget_get_window(widget);
|
||||
GdkWindowState state = gdk_window_get_state(GDK_WINDOW(gdkwindow));
|
||||
return state & GDK_WINDOW_STATE_FULLSCREEN == GDK_WINDOW_STATE_FULLSCREEN;
|
||||
}
|
||||
|
||||
extern void processMessage(char*);
|
||||
|
||||
static void sendMessageToBackend(WebKitUserContentManager *contentManager,
|
||||
WebKitJavascriptResult *result,
|
||||
void* data)
|
||||
{
|
||||
#if WEBKIT_MAJOR_VERSION >= 2 && WEBKIT_MINOR_VERSION >= 22
|
||||
JSCValue *value = webkit_javascript_result_get_js_value(result);
|
||||
char *message = jsc_value_to_string(value);
|
||||
#else
|
||||
JSGlobalContextRef context = webkit_javascript_result_get_global_context(result);
|
||||
JSValueRef value = webkit_javascript_result_get_value(result);
|
||||
JSStringRef js = JSValueToStringCopy(context, value, NULL);
|
||||
size_t messageSize = JSStringGetMaximumUTF8CStringSize(js);
|
||||
char *message = g_new(char, messageSize);
|
||||
JSStringGetUTF8CString(js, message, messageSize);
|
||||
JSStringRelease(js);
|
||||
#endif
|
||||
processMessage(message);
|
||||
g_free(message);
|
||||
}
|
||||
|
||||
ulong setupInvokeSignal(void* contentManager) {
|
||||
return g_signal_connect((WebKitUserContentManager*)contentManager, "script-message-received::external", G_CALLBACK(sendMessageToBackend), NULL);
|
||||
}
|
||||
|
||||
void initThreads() {
|
||||
printf("init threads\n");
|
||||
XInitThreads();
|
||||
}
|
||||
|
||||
// These are the x,y & time of the last mouse down event
|
||||
// It's used for window dragging
|
||||
float xroot = 0.0f;
|
||||
float yroot = 0.0f;
|
||||
int dragTime = -1;
|
||||
|
||||
gboolean buttonPress(GtkWidget *widget, GdkEventButton *event, void* dummy)
|
||||
{
|
||||
if( event == NULL ) {
|
||||
xroot = yroot = 0.0f;
|
||||
dragTime = -1;
|
||||
return FALSE;
|
||||
}
|
||||
if (event->type == GDK_BUTTON_PRESS && event->button == 1)
|
||||
{
|
||||
xroot = event->x_root;
|
||||
yroot = event->y_root;
|
||||
dragTime = event->time;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean buttonRelease(GtkWidget *widget, GdkEventButton *event, void* dummy)
|
||||
{
|
||||
if (event == NULL || (event->type == GDK_BUTTON_RELEASE && event->button == 1))
|
||||
{
|
||||
xroot = yroot = 0.0f;
|
||||
dragTime = -1;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void connectButtons(void* webview) {
|
||||
g_signal_connect(WEBKIT_WEB_VIEW(webview), "button-press-event", G_CALLBACK(buttonPress), NULL);
|
||||
g_signal_connect(WEBKIT_WEB_VIEW(webview), "button-release-event", G_CALLBACK(buttonRelease), NULL);
|
||||
}
|
||||
|
||||
extern void processURLRequest(WebKitURISchemeRequest *request);
|
||||
|
||||
// This is called when the close button on the window is pressed
|
||||
gboolean close_button_pressed(GtkWidget *widget, GdkEvent *event, void* data)
|
||||
{
|
||||
processMessage("Q");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GtkWidget* setupWebview(void* contentManager, GtkWindow* window, int hideWindowOnClose) {
|
||||
GtkWidget* webview = webkit_web_view_new_with_user_content_manager((WebKitUserContentManager*)contentManager);
|
||||
gtk_container_add(GTK_CONTAINER(window), webview);
|
||||
WebKitWebContext *context = webkit_web_context_get_default();
|
||||
webkit_web_context_register_uri_scheme(context, "wails", (WebKitURISchemeRequestCallback)processURLRequest, NULL, NULL);
|
||||
//g_signal_connect(G_OBJECT(webview), "load-changed", G_CALLBACK(webview_load_changed_cb), NULL);
|
||||
if (hideWindowOnClose) {
|
||||
g_signal_connect(GTK_WIDGET(window), "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
|
||||
} else {
|
||||
g_signal_connect(GTK_WIDGET(window), "delete-event", G_CALLBACK(close_button_pressed), NULL);
|
||||
}
|
||||
return webview;
|
||||
}
|
||||
|
||||
void devtoolsEnabled(void* webview, int enabled) {
|
||||
WebKitSettings *settings = webkit_web_view_get_settings(WEBKIT_WEB_VIEW(webview));
|
||||
gboolean genabled = enabled == 1 ? true : false;
|
||||
webkit_settings_set_enable_developer_extras(settings, genabled);
|
||||
}
|
||||
|
||||
void loadIndex(void* webview) {
|
||||
webkit_web_view_load_uri(WEBKIT_WEB_VIEW(webview), "wails:///");
|
||||
}
|
||||
|
||||
static void startDrag(void *webview, GtkWindow* mainwindow)
|
||||
{
|
||||
// Ignore non-toplevel widgets
|
||||
GtkWidget *window = gtk_widget_get_toplevel(GTK_WIDGET(webview));
|
||||
if (!GTK_IS_WINDOW(window)) return;
|
||||
|
||||
gtk_window_begin_move_drag(mainwindow, 1, xroot, yroot, dragTime);
|
||||
}
|
||||
|
||||
void extern processOpenFileResult(char*);
|
||||
|
||||
static void OpenDialog(GtkWindow* window, char *title) {
|
||||
printf("Here\n");
|
||||
GtkWidget *dlg = gtk_file_chooser_dialog_new(title, window, GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
"_Cancel", GTK_RESPONSE_CANCEL,
|
||||
"_Open", GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
printf("Here3\n");
|
||||
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dlg));
|
||||
printf("Here 4\n");
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
printf("Here 5\n");
|
||||
|
||||
gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg));
|
||||
processOpenFileResult(filename);
|
||||
g_free(filename);
|
||||
}
|
||||
gtk_widget_destroy(dlg);
|
||||
}
|
||||
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"os"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func gtkBool(input bool) C.gboolean {
|
||||
if input {
|
||||
return C.gboolean(1)
|
||||
}
|
||||
return C.gboolean(0)
|
||||
}
|
||||
|
||||
type Window struct {
|
||||
appoptions *options.App
|
||||
debug bool
|
||||
gtkWindow unsafe.Pointer
|
||||
contentManager unsafe.Pointer
|
||||
webview unsafe.Pointer
|
||||
}
|
||||
|
||||
func bool2Cint(value bool) C.int {
|
||||
if value {
|
||||
return C.int(1)
|
||||
}
|
||||
return C.int(0)
|
||||
}
|
||||
|
||||
func NewWindow(appoptions *options.App, debug bool) *Window {
|
||||
|
||||
result := &Window{
|
||||
appoptions: appoptions,
|
||||
debug: debug,
|
||||
}
|
||||
|
||||
result.application = application
|
||||
gtkWindow := C.gtk_window_new(C.GTK_WINDOW_TOPLEVEL)
|
||||
C.g_object_ref_sink(C.gpointer(gtkWindow))
|
||||
result.gtkWindow = unsafe.Pointer(gtkWindow)
|
||||
|
||||
application.Connect("activate", func() {
|
||||
result.contentManager = unsafe.Pointer(C.webkit_user_content_manager_new())
|
||||
external := C.CString("external")
|
||||
defer C.free(unsafe.Pointer(external))
|
||||
C.webkit_user_content_manager_register_script_message_handler(result.cWebKitUserContentManager(), external)
|
||||
C.setupInvokeSignal(result.contentManager)
|
||||
|
||||
window, err := gtk.ApplicationWindowNew(application)
|
||||
if err != nil {
|
||||
log.Fatal("Could not create application window:", err)
|
||||
}
|
||||
window.Connect("delete-event", func() {
|
||||
if options.HideWindowOnClose {
|
||||
result.gtkWindow.Hide()
|
||||
return
|
||||
}
|
||||
result.gtkWindow.Close()
|
||||
})
|
||||
result.gtkWindow = window
|
||||
window.SetTitle(options.Title)
|
||||
window.SetDecorated(!options.Frameless)
|
||||
window.SetDefaultSize(600, 300)
|
||||
window.SetResizable(!options.DisableResize)
|
||||
window.SetKeepAbove(options.AlwaysOnTop)
|
||||
window.SetPosition(gtk.WIN_POS_CENTER)
|
||||
if !options.StartHidden {
|
||||
window.ShowAll()
|
||||
}
|
||||
})
|
||||
webview := C.setupWebview(result.contentManager, result.asGTKWindow(), bool2Cint(appoptions.HideWindowOnClose))
|
||||
result.webview = unsafe.Pointer(webview)
|
||||
buttonPressedName := C.CString("button-press-event")
|
||||
defer C.free(unsafe.Pointer(buttonPressedName))
|
||||
C.connectButtons(unsafe.Pointer(webview))
|
||||
|
||||
//result.SetIsForm(true)
|
||||
//
|
||||
//var exStyle int
|
||||
//if options.Windows != nil {
|
||||
// exStyle = w32.WS_EX_CONTROLPARENT | w32.WS_EX_APPWINDOW
|
||||
// if options.Windows.WindowIsTranslucent {
|
||||
// exStyle |= w32.WS_EX_NOREDIRECTIONBITMAP
|
||||
// }
|
||||
//}
|
||||
//if options.AlwaysOnTop {
|
||||
// exStyle |= w32.WS_EX_TOPMOST
|
||||
//}
|
||||
//
|
||||
//var dwStyle = w32.WS_OVERLAPPEDWINDOW
|
||||
//if options.Frameless {
|
||||
// dwStyle = w32.WS_POPUP
|
||||
//}
|
||||
//
|
||||
//winc.RegClassOnlyOnce("wailsWindow")
|
||||
//result.SetHandle(winc.CreateWindow("wailsWindow", parent, uint(exStyle), uint(dwStyle)))
|
||||
//result.SetParent(parent)
|
||||
//
|
||||
//loadIcon := true
|
||||
//if options.Windows != nil && options.Windows.DisableWindowIcon == true {
|
||||
// loadIcon = false
|
||||
//}
|
||||
//if loadIcon {
|
||||
// if ico, err := winc.NewIconFromResource(winc.GetAppInstance(), uint16(winc.AppIconID)); err == nil {
|
||||
// result.SetIcon(0, ico)
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//result.SetSize(options.Width, options.Height)
|
||||
//result.SetText(options.Title)
|
||||
//if options.Frameless == false && !options.Fullscreen {
|
||||
// result.EnableMaxButton(!options.DisableResize)
|
||||
// result.EnableSizable(!options.DisableResize)
|
||||
// result.SetMinSize(options.MinWidth, options.MinHeight)
|
||||
// result.SetMaxSize(options.MaxWidth, options.MaxHeight)
|
||||
//}
|
||||
//
|
||||
//if options.Windows != nil {
|
||||
// if options.Windows.WindowIsTranslucent {
|
||||
// result.SetTranslucentBackground()
|
||||
// }
|
||||
//
|
||||
// if options.Windows.DisableWindowIcon {
|
||||
// result.DisableIcon()
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// Dlg forces display of focus rectangles, as soon as the user starts to type.
|
||||
//w32.SendMessage(result.Handle(), w32.WM_CHANGEUISTATE, w32.UIS_INITIALIZE, 0)
|
||||
//winc.RegMsgHandler(result)
|
||||
//
|
||||
//result.SetFont(winc.DefaultFont)
|
||||
//
|
||||
//if options.Menu != nil {
|
||||
// result.SetApplicationMenu(options.Menu)
|
||||
//}
|
||||
if debug {
|
||||
C.devtoolsEnabled(unsafe.Pointer(webview), C.int(1))
|
||||
}
|
||||
|
||||
// Setup window
|
||||
result.SetKeepAbove(appoptions.AlwaysOnTop)
|
||||
result.SetResizable(!appoptions.DisableResize)
|
||||
result.SetSize(appoptions.Width, appoptions.Height)
|
||||
result.SetDecorated(!appoptions.Frameless)
|
||||
result.SetTitle(appoptions.Title)
|
||||
result.SetMinSize(appoptions.MinWidth, appoptions.MinHeight)
|
||||
result.SetMaxSize(appoptions.MaxWidth, appoptions.MaxHeight)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (w *Window) Run() {
|
||||
w.application.Run(nil)
|
||||
func (w *Window) asGTKWidget() *C.GtkWidget {
|
||||
return C.GTKWIDGET(w.gtkWindow)
|
||||
}
|
||||
|
||||
func (w *Window) Dispatch(f func()) {
|
||||
glib.IdleAdd(f)
|
||||
func (w *Window) asGTKWindow() *C.GtkWindow {
|
||||
return C.GTKWINDOW(w.gtkWindow)
|
||||
}
|
||||
|
||||
func (w *Window) cWebKitUserContentManager() *C.WebKitUserContentManager {
|
||||
return (*C.WebKitUserContentManager)(w.contentManager)
|
||||
}
|
||||
|
||||
func (w *Window) Fullscreen() {
|
||||
w.gtkWindow.Fullscreen()
|
||||
C.gtk_window_fullscreen(w.asGTKWindow())
|
||||
}
|
||||
|
||||
func (w *Window) UnFullscreen() {
|
||||
w.gtkWindow.Unfullscreen()
|
||||
C.gtk_window_unfullscreen(w.asGTKWindow())
|
||||
}
|
||||
|
||||
func (w *Window) Destroy() {
|
||||
C.g_object_unref(C.gpointer(w.gtkWindow))
|
||||
C.gtk_widget_destroy(w.asGTKWidget())
|
||||
}
|
||||
|
||||
func (w *Window) Close() {
|
||||
w.application.Quit()
|
||||
C.gtk_window_close(w.asGTKWindow())
|
||||
}
|
||||
|
||||
func (w *Window) Center() {
|
||||
w.gtkWindow.SetPosition(gtk.WIN_POS_CENTER)
|
||||
C.Center(w.asGTKWindow())
|
||||
}
|
||||
|
||||
func (w *Window) SetPos(x int, y int) {
|
||||
display, err := w.gtkWindow.GetDisplay()
|
||||
if err != nil {
|
||||
w.gtkWindow.Move(x, y)
|
||||
return
|
||||
}
|
||||
window, err := w.gtkWindow.GetWindow()
|
||||
if err != nil {
|
||||
w.gtkWindow.Move(x, y)
|
||||
return
|
||||
}
|
||||
|
||||
monitor, err := display.GetMonitorAtWindow(window)
|
||||
if err != nil {
|
||||
w.gtkWindow.Move(x, y)
|
||||
return
|
||||
}
|
||||
|
||||
geom := monitor.GetGeometry()
|
||||
w.gtkWindow.Move(geom.GetX()+x, geom.GetY()+y)
|
||||
}
|
||||
|
||||
func (w *Window) Pos() (int, int) {
|
||||
return w.gtkWindow.GetPosition()
|
||||
}
|
||||
|
||||
func (w *Window) SetSize(width int, height int) {
|
||||
w.gtkWindow.SetDefaultSize(width, height)
|
||||
cX := C.int(x)
|
||||
cY := C.int(y)
|
||||
C.gtk_window_move(w.asGTKWindow(), cX, cY)
|
||||
}
|
||||
|
||||
func (w *Window) Size() (int, int) {
|
||||
return w.gtkWindow.GetSize()
|
||||
var width, height C.int
|
||||
C.gtk_window_get_size(w.asGTKWindow(), &width, &height)
|
||||
return int(width), int(height)
|
||||
}
|
||||
|
||||
func (w *Window) SetText(title string) {
|
||||
w.gtkWindow.SetTitle(title)
|
||||
func (w *Window) Pos() (int, int) {
|
||||
var width, height C.int
|
||||
C.gtk_window_get_position(w.asGTKWindow(), &width, &height)
|
||||
return int(width), int(height)
|
||||
}
|
||||
|
||||
func (w *Window) SetMaxSize(maxWidth int, maxHeight int) {
|
||||
var geom gdk.Geometry
|
||||
if maxWidth == 0 {
|
||||
maxWidth = math.MaxInt
|
||||
}
|
||||
if maxHeight == 0 {
|
||||
maxHeight = math.MaxInt
|
||||
}
|
||||
geom.SetMaxWidth(maxWidth)
|
||||
geom.SetMaxHeight(maxHeight)
|
||||
w.gtkWindow.SetGeometryHints(w.gtkWindow, geom, gdk.HINT_MAX_SIZE)
|
||||
C.SetMaxSize(w.asGTKWindow(), C.int(maxWidth), C.int(maxHeight))
|
||||
}
|
||||
|
||||
func (w *Window) SetMinSize(minWidth int, minHeight int) {
|
||||
var geom gdk.Geometry
|
||||
geom.SetMinWidth(minWidth)
|
||||
geom.SetMinHeight(minHeight)
|
||||
w.gtkWindow.SetGeometryHints(w.gtkWindow, geom, gdk.HINT_MIN_SIZE)
|
||||
C.SetMinSize(w.asGTKWindow(), C.int(minWidth), C.int(minHeight))
|
||||
}
|
||||
|
||||
func (w *Window) Show() {
|
||||
w.gtkWindow.ShowAll()
|
||||
C.gtk_widget_show(w.asGTKWidget())
|
||||
}
|
||||
|
||||
func (w *Window) Hide() {
|
||||
w.gtkWindow.Hide()
|
||||
C.gtk_widget_hide(w.asGTKWidget())
|
||||
}
|
||||
|
||||
func (w *Window) Maximise() {
|
||||
w.gtkWindow.Maximize()
|
||||
C.gtk_window_maximize(w.asGTKWindow())
|
||||
}
|
||||
|
||||
func (w *Window) UnMaximise() {
|
||||
w.gtkWindow.Unmaximize()
|
||||
C.gtk_window_unmaximize(w.asGTKWindow())
|
||||
}
|
||||
|
||||
func (w *Window) Minimise() {
|
||||
w.gtkWindow.Iconify()
|
||||
C.gtk_window_iconify(w.asGTKWindow())
|
||||
}
|
||||
|
||||
func (w *Window) UnMinimise() {
|
||||
w.gtkWindow.Present()
|
||||
C.gtk_window_present(w.asGTKWindow())
|
||||
}
|
||||
|
||||
func (w *Window) IsFullScreen() bool {
|
||||
result := C.IsFullscreen(w.asGTKWidget())
|
||||
if result == 1 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *Window) SetRGBA(r uint8, g uint8, b uint8, a uint8) {
|
||||
//C.SetRGBA(w.context, C.int(r), C.int(g), C.int(b), C.int(a))
|
||||
}
|
||||
|
||||
//func (w *Window) SetApplicationMenu(inMenu *menu.Menu) {
|
||||
// //mainMenu := NewNSMenu(w.context, "")
|
||||
// //processMenu(mainMenu, inMenu)
|
||||
// //C.SetAsApplicationMenu(w.context, mainMenu.nsmenu)
|
||||
//}
|
||||
|
||||
func (w *Window) UpdateApplicationMenu() {
|
||||
//C.UpdateApplicationMenu(w.context)
|
||||
}
|
||||
|
||||
func (w *Window) Run() {
|
||||
C.loadIndex(w.webview)
|
||||
C.gtk_widget_show_all(w.asGTKWidget())
|
||||
w.Center()
|
||||
switch w.appoptions.WindowStartState {
|
||||
case options.Fullscreen:
|
||||
w.Fullscreen()
|
||||
case options.Minimised:
|
||||
w.Minimise()
|
||||
case options.Maximised:
|
||||
w.Maximise()
|
||||
}
|
||||
|
||||
C.initThreads()
|
||||
C.gtk_main()
|
||||
w.Destroy()
|
||||
}
|
||||
|
||||
func (w *Window) SetKeepAbove(top bool) {
|
||||
C.gtk_window_set_keep_above(w.asGTKWindow(), gtkBool(top))
|
||||
}
|
||||
|
||||
func (w *Window) SetResizable(resizable bool) {
|
||||
C.gtk_window_set_resizable(w.asGTKWindow(), gtkBool(resizable))
|
||||
}
|
||||
|
||||
func (w *Window) SetSize(width int, height int) {
|
||||
C.gtk_window_resize(w.asGTKWindow(), C.gint(width), C.gint(height))
|
||||
}
|
||||
|
||||
func (w *Window) SetDecorated(frameless bool) {
|
||||
C.gtk_window_set_decorated(w.asGTKWindow(), gtkBool(frameless))
|
||||
}
|
||||
|
||||
func (w *Window) SetTitle(title string) {
|
||||
cTitle := C.CString(title)
|
||||
defer C.free(unsafe.Pointer(cTitle))
|
||||
C.gtk_window_set_title(w.asGTKWindow(), cTitle)
|
||||
}
|
||||
|
||||
func (w *Window) ExecJS(js string) {
|
||||
script := C.CString(js)
|
||||
defer C.free(unsafe.Pointer(script))
|
||||
C.webkit_web_view_run_javascript((*C.WebKitWebView)(w.webview), script, nil, nil, nil)
|
||||
}
|
||||
|
||||
func (w *Window) StartDrag() {
|
||||
C.startDrag(w.webview, w.asGTKWindow())
|
||||
}
|
||||
|
||||
func (w *Window) Quit() {
|
||||
C.gtk_main_quit()
|
||||
}
|
||||
|
||||
func (w *Window) OpenFileDialog(dialogOptions frontend.OpenDialogOptions) {
|
||||
println("OpenFileDialog PID:", os.Getpid())
|
||||
mem := NewCalloc()
|
||||
title := mem.String(dialogOptions.Title)
|
||||
C.OpenDialog(w.asGTKWindow(), title)
|
||||
mem.Free()
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -19,6 +20,7 @@ import (
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/assetserver"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/common"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
@@ -43,6 +45,8 @@ type Frontend struct {
|
||||
bindings *binding.Bindings
|
||||
dispatcher frontend.Dispatcher
|
||||
servingFromDisk bool
|
||||
|
||||
hasStarted bool
|
||||
}
|
||||
|
||||
func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher) *Frontend {
|
||||
@@ -229,7 +233,7 @@ func (f *Frontend) WindowSetRGBA(col *options.RGBA) {
|
||||
return
|
||||
}
|
||||
|
||||
f.mainWindow.Dispatch(func() {
|
||||
f.mainWindow.Invoke(func() {
|
||||
controller := f.chromium.GetController()
|
||||
controller2 := controller.GetICoreWebView2Controller2()
|
||||
|
||||
@@ -257,7 +261,12 @@ func (f *Frontend) WindowSetRGBA(col *options.RGBA) {
|
||||
}
|
||||
|
||||
func (f *Frontend) Quit() {
|
||||
winc.Exit()
|
||||
if f.frontendOptions.OnBeforeClose != nil && f.frontendOptions.OnBeforeClose(f.ctx) {
|
||||
return
|
||||
}
|
||||
// Exit must be called on the Main-Thread. It calls PostQuitMessage which sends the WM_QUIT message to the thread's
|
||||
// message queue and our message queue runs on the Main-Thread.
|
||||
f.mainWindow.Invoke(winc.Exit)
|
||||
}
|
||||
|
||||
func (f *Frontend) setupChromium() {
|
||||
@@ -331,33 +340,55 @@ func (f *Frontend) processRequest(req *edge.ICoreWebView2WebResourceRequest, arg
|
||||
//Get the request
|
||||
uri, _ := req.GetUri()
|
||||
|
||||
// Translate URI
|
||||
uri = strings.TrimPrefix(uri, "file://wails")
|
||||
if !strings.HasPrefix(uri, "/") {
|
||||
return
|
||||
var content []byte
|
||||
var mimeType string
|
||||
|
||||
// Translate URI to file
|
||||
file, match, err := common.TranslateUriToFile(uri, "file", "wails")
|
||||
if err == nil {
|
||||
if !match {
|
||||
// In this case we should let the WebView2 handle the request with it's default handler
|
||||
return
|
||||
}
|
||||
|
||||
// Load file from asset store
|
||||
content, mimeType, err = f.assets.Load(file)
|
||||
}
|
||||
|
||||
// Load file from asset store
|
||||
content, mimeType, err := f.assets.Load(uri)
|
||||
statusCode := 200
|
||||
reasonPhrase := "OK"
|
||||
if err != nil {
|
||||
return
|
||||
if os.IsNotExist(err) {
|
||||
statusCode = 404
|
||||
reasonPhrase = "Not Found"
|
||||
} else {
|
||||
err = fmt.Errorf("Error processing request %s: %w", uri, err)
|
||||
f.logger.Error(err.Error())
|
||||
statusCode = 500
|
||||
reasonPhrase = "Internal Server Error"
|
||||
}
|
||||
}
|
||||
|
||||
headers := []string{}
|
||||
if mimeType != "" {
|
||||
headers = append(headers, "Content-Type: "+mimeType)
|
||||
}
|
||||
if content != nil && f.servingFromDisk {
|
||||
headers = append(headers, "Pragma: no-cache")
|
||||
}
|
||||
|
||||
env := f.chromium.Environment()
|
||||
headers := "Content-Type: " + mimeType
|
||||
if f.servingFromDisk {
|
||||
headers += "\nPragma: no-cache"
|
||||
}
|
||||
response, err := env.CreateWebResourceResponse(content, 200, "OK", headers)
|
||||
response, err := env.CreateWebResourceResponse(content, statusCode, reasonPhrase, strings.Join(headers, "\n"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer response.Release()
|
||||
|
||||
// Send response back
|
||||
err = args.PutResponse(response)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var edgeMap = map[string]uintptr{
|
||||
@@ -396,27 +427,30 @@ func (f *Frontend) processMessage(message string) {
|
||||
}
|
||||
return
|
||||
}
|
||||
result, err := f.dispatcher.ProcessMessage(message, f)
|
||||
if err != nil {
|
||||
f.logger.Error(err.Error())
|
||||
f.Callback(result)
|
||||
return
|
||||
}
|
||||
if result == "" {
|
||||
return
|
||||
}
|
||||
|
||||
switch result[0] {
|
||||
case 'c':
|
||||
// Callback from a method call
|
||||
f.Callback(result[1:])
|
||||
default:
|
||||
f.logger.Info("Unknown message returned from dispatcher: %+v", result)
|
||||
}
|
||||
go func() {
|
||||
result, err := f.dispatcher.ProcessMessage(message, f)
|
||||
if err != nil {
|
||||
f.logger.Error(err.Error())
|
||||
f.Callback(result)
|
||||
return
|
||||
}
|
||||
if result == "" {
|
||||
return
|
||||
}
|
||||
|
||||
switch result[0] {
|
||||
case 'c':
|
||||
// Callback from a method call
|
||||
f.Callback(result[1:])
|
||||
default:
|
||||
f.logger.Info("Unknown message returned from dispatcher: %+v", result)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (f *Frontend) Callback(message string) {
|
||||
f.mainWindow.Dispatch(func() {
|
||||
f.mainWindow.Invoke(func() {
|
||||
f.chromium.Eval(`window.wails.Callback(` + strconv.Quote(message) + `);`)
|
||||
})
|
||||
}
|
||||
@@ -438,7 +472,7 @@ func (f *Frontend) startResize(border uintptr) error {
|
||||
}
|
||||
|
||||
func (f *Frontend) ExecJS(js string) {
|
||||
f.mainWindow.Dispatch(func() {
|
||||
f.mainWindow.Invoke(func() {
|
||||
f.chromium.Eval(js)
|
||||
})
|
||||
}
|
||||
@@ -452,6 +486,11 @@ func (f *Frontend) navigationCompleted(sender *edge.ICoreWebView2, args *edge.IC
|
||||
f.ExecJS("window.wails.flags.enableResize = true;")
|
||||
}
|
||||
|
||||
if f.hasStarted {
|
||||
return
|
||||
}
|
||||
f.hasStarted = true
|
||||
|
||||
// Hack to make it visible: https://github.com/MicrosoftEdge/WebView2Feedback/issues/1077#issuecomment-825375026
|
||||
err := f.chromium.Hide()
|
||||
if err != nil {
|
||||
|
||||
@@ -7,15 +7,12 @@ import (
|
||||
"github.com/leaanthony/winc/w32"
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Window struct {
|
||||
winc.Form
|
||||
frontendOptions *options.App
|
||||
applicationMenu *menu.Menu
|
||||
m sync.Mutex
|
||||
dispatchq []func()
|
||||
}
|
||||
|
||||
func NewWindow(parent winc.Controller, appoptions *options.App) *Window {
|
||||
@@ -37,6 +34,9 @@ func NewWindow(parent winc.Controller, appoptions *options.App) *Window {
|
||||
var dwStyle = w32.WS_OVERLAPPEDWINDOW
|
||||
if appoptions.Frameless {
|
||||
dwStyle = w32.WS_POPUP
|
||||
if winoptions := appoptions.Windows; winoptions != nil && winoptions.EnableFramelessBorder {
|
||||
dwStyle |= w32.WS_BORDER
|
||||
}
|
||||
}
|
||||
|
||||
winc.RegClassOnlyOnce("wailsWindow")
|
||||
@@ -86,32 +86,5 @@ func NewWindow(parent winc.Controller, appoptions *options.App) *Window {
|
||||
}
|
||||
|
||||
func (w *Window) Run() int {
|
||||
var m w32.MSG
|
||||
|
||||
for w32.GetMessage(&m, 0, 0, 0) != 0 {
|
||||
if m.Message == w32.WM_APP {
|
||||
// Credit: https://github.com/jchv/go-webview2
|
||||
w.m.Lock()
|
||||
q := append([]func(){}, w.dispatchq...)
|
||||
w.dispatchq = []func(){}
|
||||
w.m.Unlock()
|
||||
for _, v := range q {
|
||||
v()
|
||||
}
|
||||
}
|
||||
if !w.PreTranslateMessage(&m) {
|
||||
w32.TranslateMessage(&m)
|
||||
w32.DispatchMessage(&m)
|
||||
}
|
||||
}
|
||||
|
||||
w32.GdiplusShutdown()
|
||||
return int(m.WParam)
|
||||
}
|
||||
|
||||
func (w *Window) Dispatch(f func()) {
|
||||
w.m.Lock()
|
||||
w.dispatchq = append(w.dispatchq, f)
|
||||
w.m.Unlock()
|
||||
w32.PostMainThreadMessage(w32.WM_APP, 0, 0)
|
||||
return winc.RunMainLoop()
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"log"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -50,6 +49,11 @@ func (d *DevWebServer) WindowReload() {
|
||||
func (d *DevWebServer) Run(ctx context.Context) error {
|
||||
d.ctx = ctx
|
||||
|
||||
assetdir, _ := ctx.Value("assetdir").(string)
|
||||
d.server.Get("/wails/assetdir", func(fctx *fiber.Ctx) error {
|
||||
return fctx.SendString(assetdir)
|
||||
})
|
||||
|
||||
d.server.Get("/wails/reload", func(fctx *fiber.Ctx) error {
|
||||
d.WindowReload()
|
||||
d.desktopFrontend.WindowReload()
|
||||
@@ -100,25 +104,14 @@ func (d *DevWebServer) Run(ctx context.Context) error {
|
||||
_devServerURL := ctx.Value("devserverurl")
|
||||
if _devServerURL == "http://localhost:34115" {
|
||||
// Setup internal dev server
|
||||
_assetdir := ctx.Value("assetdir")
|
||||
if _assetdir == nil {
|
||||
return fmt.Errorf("no assetdir provided")
|
||||
bindingsJSON, err := d.appBindings.ToJSON()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if _assetdir != nil {
|
||||
assetdir := _assetdir.(string)
|
||||
bindingsJSON, err := d.appBindings.ToJSON()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
d.assetServer, err = assetserver.NewBrowserAssetServer(assetdir, bindingsJSON, d.appoptions)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
absdir, err := filepath.Abs(assetdir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.LogDebug("Serving assets from: %s", absdir)
|
||||
|
||||
d.assetServer, err = assetserver.NewBrowserAssetServer(ctx, d.appoptions.Assets, bindingsJSON)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
d.server.Get("*", d.loadAsset)
|
||||
|
||||
@@ -19,8 +19,6 @@ type OpenDialogOptions struct {
|
||||
DefaultFilename string
|
||||
Title string
|
||||
Filters []FileFilter
|
||||
AllowFiles bool
|
||||
AllowDirectories bool
|
||||
ShowHiddenFiles bool
|
||||
CanCreateDirectories bool
|
||||
ResolvesAliases bool
|
||||
|
||||
@@ -152,7 +152,7 @@ export function EventsEmit(eventName) {
|
||||
|
||||
export function EventsOff(eventName) {
|
||||
// Remove local listeners
|
||||
eventListeners.delete(eventName);
|
||||
delete eventListeners[eventName];
|
||||
|
||||
// Notify Go listeners
|
||||
window.WailsInvoke('EX' + eventName);
|
||||
|
||||
@@ -23,9 +23,9 @@ The electron alternative for Go
|
||||
return obj;
|
||||
};
|
||||
let windows = _deeptest(["chrome", "webview", "postMessage"]);
|
||||
let mac = _deeptest(["webkit", "messageHandlers", "external", "postMessage"]);
|
||||
let mac_linux = _deeptest(["webkit", "messageHandlers", "external", "postMessage"]);
|
||||
|
||||
if (!windows && !mac) {
|
||||
if (!windows && !mac_linux) {
|
||||
console.error("Unsupported Platform");
|
||||
return;
|
||||
}
|
||||
@@ -33,7 +33,7 @@ The electron alternative for Go
|
||||
if (windows) {
|
||||
window.WailsInvoke = (message) => window.chrome.webview.postMessage(message);
|
||||
}
|
||||
if (mac) {
|
||||
if (mac_linux) {
|
||||
window.WailsInvoke = (message) => window.webkit.messageHandlers.external.postMessage(message);
|
||||
}
|
||||
})();
|
||||
@@ -14,14 +14,17 @@ import Overlay from "./Overlay.svelte";
|
||||
import {hideOverlay, showOverlay} from "./store";
|
||||
|
||||
let components = {};
|
||||
window.ipcCallbacks = [];
|
||||
window.ipcCallbackNames = [];
|
||||
|
||||
window.awaitIPC = (name, callback) => {
|
||||
if (!window.ipcCallbacks) return callback;
|
||||
log("Queuing '" + name + "' for execution once ipc ready.");
|
||||
window.ipcCallbackNames.push(name);
|
||||
window.ipcCallbacks.push(callback);
|
||||
let wailsInvokeInternal = null;
|
||||
let messageQueue = [];
|
||||
|
||||
window.WailsInvoke = (message) => {
|
||||
if (!wailsInvokeInternal) {
|
||||
console.log("Queueing: " + message);
|
||||
messageQueue.push(message);
|
||||
return;
|
||||
}
|
||||
wailsInvokeInternal(message);
|
||||
};
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
@@ -47,15 +50,14 @@ window.onbeforeunload = function () {
|
||||
connect();
|
||||
|
||||
function setupIPCBridge() {
|
||||
window.WailsInvoke = (message) => {
|
||||
wailsInvokeInternal = (message) => {
|
||||
websocket.send(message);
|
||||
};
|
||||
for (let i = 0; i < window.ipcCallbacks.length; i++) {
|
||||
log("Executing JS: " + window.ipcCallbackNames[i]);
|
||||
window.ipcCallbacks[i]();
|
||||
for (let i = 0; i < messageQueue.length; i++) {
|
||||
console.log("sending queued message: " + messageQueue[i]);
|
||||
window.WailsInvoke(messageQueue[i]);
|
||||
}
|
||||
delete window.ipcCallbacks;
|
||||
delete window.ipcCallbackNames;
|
||||
messageQueue = [];
|
||||
}
|
||||
|
||||
// Handles incoming websocket connections
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.12.17",
|
||||
"esbuild-svelte": "^0.5.6",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"svelte": "^3.42.2",
|
||||
"esbuild-svelte": "^0.5.6"
|
||||
"svelte": "^3.42.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
(()=>{(function(){let o=function(e){for(var s=window[e.shift()];s&&e.length;)s=s[e.shift()];return s},t=o(["chrome","webview","postMessage"]),n=o(["webkit","messageHandlers","external","postMessage"]);if(!t&&!n){console.error("Unsupported Platform");return}t&&(window.WailsInvoke=e=>window.chrome.webview.postMessage(e)),n&&(window.WailsInvoke=e=>window.webkit.messageHandlers.external.postMessage(e))})();})();
|
||||
(()=>{(function(){let n=function(e){for(var s=window[e.shift()];s&&e.length;)s=s[e.shift()];return s},o=n(["chrome","webview","postMessage"]),t=n(["webkit","messageHandlers","external","postMessage"]);if(!o&&!t){console.error("Unsupported Platform");return}o&&(window.WailsInvoke=e=>window.chrome.webview.postMessage(e)),t&&(window.WailsInvoke=e=>window.webkit.messageHandlers.external.postMessage(e))})();})();
|
||||
|
||||
File diff suppressed because one or more lines are too long
762
v2/internal/frontend/runtime/package-lock.json
generated
762
v2/internal/frontend/runtime/package-lock.json
generated
@@ -1,8 +1,768 @@
|
||||
{
|
||||
"name": "runtime",
|
||||
"version": "2.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "2.0.0",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.12.17",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"svelte": "^3.42.2"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
|
||||
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1",
|
||||
"get-intrinsic": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
|
||||
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"nice-try": "^1.0.4",
|
||||
"path-key": "^2.0.1",
|
||||
"semver": "^5.5.0",
|
||||
"shebang-command": "^1.2.0",
|
||||
"which": "^1.2.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.8"
|
||||
}
|
||||
},
|
||||
"node_modules/define-properties": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
|
||||
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"object-keys": "^1.0.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/error-ex": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/es-abstract": {
|
||||
"version": "1.18.5",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz",
|
||||
"integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"es-to-primitive": "^1.2.1",
|
||||
"function-bind": "^1.1.1",
|
||||
"get-intrinsic": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
"has-symbols": "^1.0.2",
|
||||
"internal-slot": "^1.0.3",
|
||||
"is-callable": "^1.2.3",
|
||||
"is-negative-zero": "^2.0.1",
|
||||
"is-regex": "^1.1.3",
|
||||
"is-string": "^1.0.6",
|
||||
"object-inspect": "^1.11.0",
|
||||
"object-keys": "^1.1.1",
|
||||
"object.assign": "^4.1.2",
|
||||
"string.prototype.trimend": "^1.0.4",
|
||||
"string.prototype.trimstart": "^1.0.4",
|
||||
"unbox-primitive": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-to-primitive": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
|
||||
"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-callable": "^1.1.4",
|
||||
"is-date-object": "^1.0.1",
|
||||
"is-symbol": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.12.17",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.17.tgz",
|
||||
"integrity": "sha512-GshKJyVYUnlSXIZj/NheC2O0Kblh42CS7P1wJyTbbIHevTG4jYMS9NNw8EOd8dDWD0dzydYHS01MpZoUcQXB4g==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
|
||||
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
"has-symbols": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.6",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
|
||||
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/has-bigints": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
|
||||
"integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
|
||||
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/hosted-git-info": {
|
||||
"version": "2.8.9",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
||||
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/internal-slot": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
|
||||
"integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.1.0",
|
||||
"has": "^1.0.3",
|
||||
"side-channel": "^1.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/is-bigint": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz",
|
||||
"integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/is-boolean-object": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz",
|
||||
"integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-callable": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz",
|
||||
"integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.5.0.tgz",
|
||||
"integrity": "sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/is-date-object": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz",
|
||||
"integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-negative-zero": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
|
||||
"integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-number-object": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz",
|
||||
"integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-regex": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz",
|
||||
"integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"has-symbols": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-string": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz",
|
||||
"integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-symbol": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
|
||||
"integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json-parse-better-errors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
|
||||
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/load-json-file": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
|
||||
"integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"parse-json": "^4.0.0",
|
||||
"pify": "^3.0.0",
|
||||
"strip-bom": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/memorystream": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
|
||||
"integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/nice-try": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
|
||||
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/normalize-package-data": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
|
||||
"integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"hosted-git-info": "^2.1.4",
|
||||
"resolve": "^1.10.0",
|
||||
"semver": "2 || 3 || 4 || 5",
|
||||
"validate-npm-package-license": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-all": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
|
||||
"integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"chalk": "^2.4.1",
|
||||
"cross-spawn": "^6.0.5",
|
||||
"memorystream": "^0.3.1",
|
||||
"minimatch": "^3.0.4",
|
||||
"pidtree": "^0.3.0",
|
||||
"read-pkg": "^3.0.0",
|
||||
"shell-quote": "^1.6.1",
|
||||
"string.prototype.padend": "^3.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"npm-run-all": "bin/npm-run-all/index.js",
|
||||
"run-p": "bin/run-p/index.js",
|
||||
"run-s": "bin/run-s/index.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/object-inspect": {
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
|
||||
"integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/object-keys": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/object.assign": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
|
||||
"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.0",
|
||||
"define-properties": "^1.1.3",
|
||||
"has-symbols": "^1.0.1",
|
||||
"object-keys": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
|
||||
"integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"error-ex": "^1.3.1",
|
||||
"json-parse-better-errors": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/path-key": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
|
||||
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/path-type": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
|
||||
"integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"pify": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/pidtree": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz",
|
||||
"integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"pidtree": "bin/pidtree.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/pify": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
|
||||
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/read-pkg": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
|
||||
"integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"load-json-file": "^4.0.0",
|
||||
"normalize-package-data": "^2.3.2",
|
||||
"path-type": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.20.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
|
||||
"integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.2.0",
|
||||
"path-parse": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
|
||||
"integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"shebang-regex": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-regex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
|
||||
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/shell-quote": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz",
|
||||
"integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/side-channel": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
|
||||
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.0",
|
||||
"get-intrinsic": "^1.0.2",
|
||||
"object-inspect": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/spdx-correct": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
|
||||
"integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"spdx-expression-parse": "^3.0.0",
|
||||
"spdx-license-ids": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/spdx-exceptions": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
|
||||
"integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/spdx-expression-parse": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
|
||||
"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"spdx-exceptions": "^2.1.0",
|
||||
"spdx-license-ids": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/spdx-license-ids": {
|
||||
"version": "3.0.9",
|
||||
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz",
|
||||
"integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/string.prototype.padend": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.2.tgz",
|
||||
"integrity": "sha512-/AQFLdYvePENU3W5rgurfWSMU6n+Ww8n/3cUt7E+vPBB/D7YDG8x+qjoFs4M/alR2bW7Qg6xMjVwWUOvuQ0XpQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.3",
|
||||
"es-abstract": "^1.18.0-next.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/string.prototype.trimend": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
|
||||
"integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/string.prototype.trimstart": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
|
||||
"integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-bom": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
|
||||
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte": {
|
||||
"version": "3.42.5",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.42.5.tgz",
|
||||
"integrity": "sha512-+y9ivcwMojAb0e87W7vR/UP7go44zc/3gtEciIMb8CUoIkUx6UJmPloBvVuO9MDXoGkUZM5SHr5PbLze9fJQVw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/unbox-primitive": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
|
||||
"integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1",
|
||||
"has-bigints": "^1.0.1",
|
||||
"has-symbols": "^1.0.2",
|
||||
"which-boxed-primitive": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||
"integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"spdx-correct": "^3.0.0",
|
||||
"spdx-expression-parse": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"which": "bin/which"
|
||||
}
|
||||
},
|
||||
"node_modules/which-boxed-primitive": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
|
||||
"integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-bigint": "^1.0.1",
|
||||
"is-boolean-object": "^1.1.0",
|
||||
"is-number-object": "^1.0.4",
|
||||
"is-string": "^1.0.5",
|
||||
"is-symbol": "^1.0.3"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user