Compare commits

...

185 Commits

Author SHA1 Message Date
Lea Anthony
77e9dfd412 [linux] Attempt to handle 404 2021-12-05 19:41:51 +11:00
Lea Anthony
41507e966a [linux] Remove signal handlers. Weird errors. 2021-12-04 20:10:37 +11:00
Lea Anthony
3092f04bcf [linux] Clean up signal handlers 2021-12-04 14:35:32 +11:00
Lea\Anthony
ffc0765a2f [website] Add OnBeforeClose docs 2021-12-04 14:31:59 +11:00
Lea Anthony
ac803aa426 Merge pull request #1007 from Ironpark/feature/on_before_close
[v2] feature / on-before-close resolve #978
2021-12-04 14:17:58 +11:00
ironpark
92b63d9fad window delegate modify for onBeforeClose hook 2021-12-04 07:52:34 +09:00
ironpark
fda3323386 basic implement 2021-12-04 04:55:36 +09:00
Lea Anthony
b7a4aba5f3 Merge pull request #1004 from stffabi/feature/improve-processrequest
[v2] Improve processRequest: Handle errors and behave more like a webserver
2021-12-04 05:01:36 +11:00
Lea Anthony
7848a028e3 Merge pull request #1002 from ianmjones/fix-cannot-use-uri-as-string-error
Fix error: cannot use uri (type *_Ctype_char) as type string in argument to common.TranslateUriToFile.
2021-12-04 04:51:09 +11:00
stffabi
d827aafe89 [v2] Improve processRequest: Handle errors and behave more like a webserver
This also fixes that requests remain in "pending" state on
darwin if e.g. a file is not found or an error occurs during
loading of the file.
2021-12-03 16:41:51 +01:00
Ian M. Jones
db8094cd68 Fix error: cannot use uri (type *_Ctype_char) as type string in argument to common.TranslateUriToFile. 2021-12-03 15:25:58 +00:00
Lea Anthony
59d29dc12f Merge pull request #998 from marcio199226/master
added ytd app to showcase
2021-12-03 01:56:53 -08:00
Lea Anthony
7aad934dae Remove yarn.lock 2021-12-03 20:56:30 +11:00
Oskar
0b1e33748a added ytd app to showcase 2021-12-02 21:29:43 +01:00
Lea Anthony
97be694d2a Merge pull request #996 from stffabi/feature/improved-translate-uri
[v2] Improve translation of URI to file to be loaded
2021-12-02 05:38:04 -08:00
Lea Anthony
576e574399 Merge pull request #994 from stffabi/feature/fix-webresourcerequest-memoryleak
[v2] Fix memory leak in processRequest for windows and darwin
2021-12-02 04:01:22 -08:00
Lea Anthony
6d9a195830 Merge pull request #991 from stffabi/feature/windows-frameless-border
[windows] Support drawing a frame for frameless to support hiding the titlebar
2021-12-02 04:00:01 -08:00
stffabi
8107a8bd1e [v2] Improve translation of URI to file to be loaded 2021-12-02 11:53:32 +01:00
stffabi
47d783291d [windows] Support drawing a frame for frameless to support hiding the titlebar 2021-12-02 11:16:13 +01:00
stffabi
0295f8dee2 [v2] Fix memory leak in processRequest for windows and darwin 2021-12-02 11:04:24 +01:00
stffabi
d915f73c6c [v2] Remove replace and bump winc 2021-12-02 11:01:30 +01:00
Lea Anthony
187bf3085c Merge pull request #989 from stffabi/feature/non-blocking-backend-calls
[v2] Do not block during processing of messages
2021-12-02 01:17:03 -08:00
stffabi
a353a653d1 [windows] Replace dispatch with invoke 2021-12-01 13:24:54 +01:00
stffabi
155f1fde49 [v2] Do not block during processing of messages
On windows blocking here results in a blocked main thread
and a blocked webview.
2021-12-01 13:24:19 +01:00
Lea Anthony
ec1a535acb Merge pull request #988 from stffabi/feature/windows-versioninfo
[v2] Windows: Add file information for windows
2021-12-01 03:09:04 -08:00
stffabi
fb5bcdc364 [v2] Windows: Add file information for windows 2021-12-01 11:59:46 +01:00
stffabi
e6f42247e7 [v2] Add missing import 2021-12-01 11:51:43 +01:00
Lea Anthony
4bc0b30231 [linux] Support closing window, hide window on close. 2021-12-01 20:32:23 +11:00
Lea\Anthony
1cd2645b87 [v2] Fix logging in prod builds. Fixes #983 2021-12-01 19:39:00 +11:00
Lea\Anthony
7904d0aadc [v2] Remove export in experimental TS generation for bindings 2021-12-01 19:19:28 +11:00
Lea\Anthony
06fa6850a1 [v2] Update experimental TS generation for bindings 2021-12-01 19:17:57 +11:00
Lea\Anthony
485f5831ac [v2] Experimental TS generation for bindings 2021-11-30 22:14:29 +11:00
Lea Anthony
587bcd8e21 Merge pull request #980 from stffabi/feature/winarm64-port
[v2] windows: Add arm64 support
2021-11-30 01:25:30 -08:00
stffabi
d43b7b1882 [windows] Add arm64 support 2021-11-30 10:07:27 +01:00
Lea\Anthony
ca147143ad [website] Improve binding docs in "how does it work" guide 2021-11-30 19:49:21 +11:00
Lea\Anthony
3371967dad [website] Update bleeding edge guide 2021-11-30 19:15:58 +11:00
Lea\Anthony
b09825ab0f [website] Fix bleeding edge guide 2021-11-30 19:14:48 +11:00
Lea\Anthony
5edf45468c [website] Add bleeding edge guide 2021-11-30 19:14:20 +11:00
Lea\Anthony
507e8d5222 [v2] Fix slash escaping in git username 2021-11-30 19:02:20 +11:00
Lea Anthony
b9283009df Merge pull request #974 from letheanVPN/npm-json-update
Adding name and author, + json handling improvement
2021-11-29 23:48:47 -08:00
Lea Anthony
60ddaf449d Update Sponsors 2021-11-30 18:41:42 +11:00
Lea Anthony
5bad81e182 Merge pull request #982 from stffabi/feature/windows-startstate-only-once
[v2] windows: Do not apply WindowStartState on reloads
2021-11-29 10:55:42 -08:00
stffabi
2e15f22621 [v2] Windows do not apply WindowStartState on reloads 2021-11-29 15:14:03 +01:00
Lea Anthony
6a3a822640 [linux] Fix content length in responses 2021-11-29 20:32:09 +11:00
Lea Anthony
e5057e1627 [linux] Fix installing cli 2021-11-29 20:25:11 +11:00
Lea Anthony
0a8f720586 [linux] Hook up runtime Window methods 2021-11-29 20:19:18 +11:00
Lea Anthony
5dbfb447b1 [linux] Support drag. 2021-11-29 20:04:57 +11:00
Lea Anthony
1f21dfbcfd [v2] Improved runtime builds. 2021-11-29 20:04:38 +11:00
Lea Anthony
53481830a9 [linux] Basic webview working 2021-11-29 08:25:42 +11:00
Lea Anthony
7eb8e6456e [linux] Devtools + dispatch. 2021-11-28 20:35:40 +11:00
Lea Anthony
5f0352404b [linux] Add basic webview. 2021-11-28 14:21:02 +11:00
Lea Anthony
b036b8c547 [linux] Support Window start state. fixed warnings. 2021-11-28 08:40:10 +11:00
Lea Anthony
39ca977b18 [linux] basic windowing pt2 2021-11-27 20:36:48 +11:00
Lea Anthony
abc078fb1b Merge pull request #976 from misitebao/optimize-documentation
docs: optimize document
2021-11-25 03:54:55 -08:00
misitebao
166490845c docs: fix translation 2021-11-25 19:34:53 +08:00
misitebao
c2399e3620 docs: optimize document content links 2021-11-25 19:26:31 +08:00
Lea Anthony
a2890b6d0d Merge pull request #956 from wailsapp/dependabot/npm_and_yarn/v2/internal/runtime/js/ssri-6.0.2
Bump ssri from 6.0.1 to 6.0.2 in /v2/internal/runtime/js
2021-11-25 00:00:05 -08:00
Lea Anthony
a1dee989c7 Merge pull request #957 from wailsapp/dependabot/npm_and_yarn/v2/internal/runtime/js/browserslist-4.18.1
Bump browserslist from 4.11.1 to 4.18.1 in /v2/internal/runtime/js
2021-11-24 23:59:42 -08:00
Lea Anthony
6ff1dac925 Merge pull request #958 from wailsapp/dependabot/npm_and_yarn/v2/internal/runtime/js/path-parse-1.0.7
Bump path-parse from 1.0.6 to 1.0.7 in /v2/internal/runtime/js
2021-11-24 23:59:26 -08:00
Lea Anthony
0b011929bf Merge pull request #959 from wailsapp/dependabot/npm_and_yarn/v2/internal/runtime/js/y18n-4.0.3
Bump y18n from 4.0.0 to 4.0.3 in /v2/internal/runtime/js
2021-11-24 23:59:08 -08:00
Lea Anthony
be3d1ff9e1 Merge pull request #960 from wailsapp/dependabot/npm_and_yarn/v2/internal/runtime/js/lodash-4.17.21
Bump lodash from 4.17.15 to 4.17.21 in /v2/internal/runtime/js
2021-11-24 23:58:48 -08:00
Lea Anthony
9c73b7285f Merge pull request #975 from Juneezee/deprecate-ioutil
refactor: move from io/ioutil to io and os packages
2021-11-24 23:57:51 -08:00
Lea Anthony
810793aba7 Merge pull request #973 from misitebao/fix-image-path
docs: fix image path errors and optimize assets paths
2021-11-24 23:40:29 -08:00
Eng Zer Jun
ef8d7d2fd7 refactor: move from io/ioutil to io and os packages
The io/ioutil package has been deprecated as of Go 1.16, see
https://golang.org/doc/go1.16#ioutil. This commit replaces the existing
io/ioutil functions with their new definitions in io and os packages.

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2021-11-25 12:15:43 +08:00
Eng Zer Jun
ae341be638 chore: run go fmt ./... and go mod tidy
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2021-11-25 12:14:27 +08:00
Snider
dcef8679d2 Adding name and author, also found out while trying to find options for value escaping the string conversion isnt needed :)
Signed-off-by: Snider <snider@lt.hn>
2021-11-24 18:50:26 +00:00
misitebao
0bb09a53ea docs: fix image path errors and optimize assets paths 2021-11-25 02:13:56 +08:00
Lea Anthony
deb1156916 Merge pull request #970 from stffabi/feature/use-winc-invoke
[v2] Use invoke to dispatch callbacks on windows
2021-11-24 04:21:39 -08:00
stffabi
1d87a81f63 [v2] Use invoke to dispatch callbacks on windows 2021-11-24 13:05:31 +01:00
stffabi
8ef8b2528b [v2] Bump winc to 0330cfc6d50c 2021-11-24 13:05:30 +01:00
Lea Anthony
f05109232e Merge pull request #961 from wailsapp/dependabot/npm_and_yarn/v2/internal/runtime/js/elliptic-6.5.4
Bump elliptic from 6.5.2 to 6.5.4 in /v2/internal/runtime/js
2021-11-24 03:06:21 -08:00
Lea Anthony
cf1001bffc Merge pull request #962 from wailsapp/dependabot/npm_and_yarn/v2/internal/runtime/js/ini-1.3.8
Bump ini from 1.3.5 to 1.3.8 in /v2/internal/runtime/js
2021-11-24 03:06:01 -08:00
Lea Anthony
7bf2218c36 Merge pull request #967 from misitebao/synchronize-documents
docs: synchronize and optimize chinese documents
2021-11-24 03:05:21 -08:00
Lea Anthony
48c9879bc4 Merge pull request #966 from wailsapp/dependabot/npm_and_yarn/website/algoliasearch-helper-3.6.2
Bump algoliasearch-helper from 3.5.5 to 3.6.2 in /website
2021-11-24 03:02:41 -08:00
Lea Anthony
2fe5e5ed01 Merge pull request #971 from letheanVPN/npm-workspace
Adding workspace to npm which better integrates wails and frontend npm.
2021-11-24 03:01:43 -08:00
Snider
38fd09bd9a Adding workspace to npm which better integrates wails and frontend npm.
Running `npm install` will now run on the top level of a generated project and additionally the "frontend" workspace (we can add plugins for wails like this, auto update, package, sign, etc, etc)

Other commands that use workspaces (including pre/post hooks mostly) and might be helpful to Wails are `docs`, `install`, `rebuild`, `publish`, `pkg`, `pack`, `ci`

For example, during wails build, you could ask for data from the frontend/package.json to get version, title, etc with.

`npm pkg get name version --workspace=frontend`

Signed-off-by: Snider <snider@lt.hn>
2021-11-24 10:34:29 +00:00
misitebao
4c5a81782b docs: sync the latest blog content 2021-11-24 13:28:35 +08:00
misitebao
ace3122e07 docs: optimize blog content 2021-11-24 13:27:41 +08:00
misitebao
f5c35487d9 docs: synchronize and optimize chinese documents 2021-11-24 12:52:36 +08:00
dependabot[bot]
06df0e1ee4 Bump algoliasearch-helper from 3.5.5 to 3.6.2 in /website
Bumps [algoliasearch-helper](https://github.com/algolia/algoliasearch-helper-js) from 3.5.5 to 3.6.2.
- [Release notes](https://github.com/algolia/algoliasearch-helper-js/releases)
- [Changelog](https://github.com/algolia/algoliasearch-helper-js/blob/develop/CHANGELOG)
- [Commits](https://github.com/algolia/algoliasearch-helper-js/compare/3.5.5...3.6.2)

---
updated-dependencies:
- dependency-name: algoliasearch-helper
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-23 21:42:58 +00:00
Lea Anthony
9735bd1b01 [website] v2.0.0-beta.21 2021-11-24 06:58:09 +11:00
Lea Anthony
cd8bad58cd [v] v2.0.0-beta.21 2021-11-24 06:42:34 +11:00
Lea Anthony
53a3cd9422 Merge pull request #965 from stffabi/feature/winguildflag-crosscompile
[v2] Add windowsgui ldflag when crosscompiling for windows
2021-11-23 10:39:10 -08:00
stffabi
5e2f25af9b [v2] Add windowsgui ldflag when crosscompiling for windows 2021-11-23 14:16:50 +01:00
dependabot[bot]
865d118651 Bump ini from 1.3.5 to 1.3.8 in /v2/internal/runtime/js
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

---
updated-dependencies:
- dependency-name: ini
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-23 11:51:06 +00:00
dependabot[bot]
6ea6bfeed0 Bump y18n from 4.0.0 to 4.0.3 in /v2/internal/runtime/js
Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.3.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/y18n-v4.0.3/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/compare/v4.0.0...y18n-v4.0.3)

---
updated-dependencies:
- dependency-name: y18n
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-23 11:51:05 +00:00
dependabot[bot]
48527eb90a Bump lodash from 4.17.15 to 4.17.21 in /v2/internal/runtime/js
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.21)

---
updated-dependencies:
- dependency-name: lodash
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-23 11:51:05 +00:00
dependabot[bot]
33d8f98da9 Bump elliptic from 6.5.2 to 6.5.4 in /v2/internal/runtime/js
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.2 to 6.5.4.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.2...v6.5.4)

---
updated-dependencies:
- dependency-name: elliptic
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-23 11:51:05 +00:00
dependabot[bot]
658a30d16a Bump path-parse from 1.0.6 to 1.0.7 in /v2/internal/runtime/js
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-23 11:51:04 +00:00
dependabot[bot]
0189d1cb55 Bump browserslist from 4.11.1 to 4.18.1 in /v2/internal/runtime/js
Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.11.1 to 4.18.1.
- [Release notes](https://github.com/browserslist/browserslist/releases)
- [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/browserslist/browserslist/compare/4.11.1...4.18.1)

---
updated-dependencies:
- dependency-name: browserslist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-23 11:51:01 +00:00
dependabot[bot]
8df94fa02b Bump ssri from 6.0.1 to 6.0.2 in /v2/internal/runtime/js
Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

---
updated-dependencies:
- dependency-name: ssri
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-23 11:51:00 +00:00
Lea Anthony
f5f89c31eb Merge pull request #955 from letheanVPN/generated-project-helper
Helper NPM scripts for developers working on a Wails GUI project
2021-11-23 03:50:29 -08:00
Snider
46cb34f2ec Adds a package.json with basic start / setup npm scripts to assist non golang developers working on an end project. 2021-11-23 11:22:25 +00:00
Lea Anthony
f6f13540c8 Merge pull request #954 from stffabi/feature/fix-mac-bgcolor
[macOS] Fix background color
2021-11-23 03:06:33 -08:00
stffabi
21ce7709ab [macOS] Fix background color 2021-11-23 11:18:00 +01:00
Lea Anthony
d569e37b81 [mac] Fix open panel in dev 2021-11-23 21:04:01 +11:00
Lea Anthony
c9c6edeb84 [mac] Fix fullscreen / start fullscreen 2021-11-23 20:06:56 +11:00
Lea Anthony
9525667ebd [windows] Add Frameless resize 2021-11-22 06:47:09 +11:00
Lea Anthony
28a3d86348 Merge pull request #951 from letheanVPN/snider-patch-1
Update Lethean project url
2021-11-20 01:07:43 -08:00
Snider
fc8aa58e62 Update Lethean project url 2021-11-20 07:10:41 +00:00
Lea Anthony
cb2bbacae8 Fix website 2021-11-20 18:02:23 +11:00
Lea Anthony
c3c6261a2d Update sponsors 2021-11-20 17:55:17 +11:00
Lea Anthony
8bfec24108 Support slices + out params in Models.ts generation. Update website with runtime info 2021-11-18 17:54:09 +11:00
Lea Anthony
9ad2665ad8 [mac] Conditionally import UTType header 2021-11-17 21:13:25 +11:00
Lea Anthony
28894868e3 [mac] Fix for file filters MacOS 11+. Some memory leak fixes. 2021-11-17 21:03:40 +11:00
Lea Anthony
a8fcd994c9 Merge branch '930_-_default_window_state' 2021-11-16 18:23:43 +11:00
Lea Anthony
c678ab7d01 [mac] Potential file dialog fix. Fix for starthidden. Partial WindowStartState 2021-11-16 18:20:41 +11:00
Lea Anthony
3a93c08813 [linux] basic windowing 2021-11-14 22:40:37 +11:00
Lea Anthony
ab1469638f [linux] get compiling working 2021-11-13 17:06:48 -08:00
Lea Anthony
9073caf287 Add build flag 2021-11-13 16:31:57 -08:00
Lea Anthony
1bed8234c9 [v2] Fix OnShutdown for production build 2021-11-11 06:05:50 +11:00
Lea Anthony
621c70253d [v2] Remove build constraint for DesktopIPC 2021-11-10 18:12:46 +11:00
Lea Anthony
56ef4ddd47 [v2] Add WindowStartState. Fix startHidden option. Only windows supported atm 2021-11-10 18:11:54 +11:00
Lea Anthony
bad9ad3dd7 [v2] Refactor app options 2021-11-10 08:42:04 +11:00
Lea Anthony
36570645ff [v2] v2.0.0-beta.20 2021-11-09 20:37:44 +11:00
Lea Anthony
3711bdc41e [v2] Add default wailsjsdir when generating module 2021-11-09 20:31:51 +11:00
Lea Anthony
cbdcd9f63e [v2] Add default wailsjsdir to templates 2021-11-09 20:31:31 +11:00
Lea Anthony
a9268bc56e [v2] Re-enable cli flags for assetdir if needed. Fixes debugging from IDE. 2021-11-09 20:11:34 +11:00
Lea Anthony
f489347fca [website] Update sponsors 2021-11-09 06:39:36 +11:00
Lea Anthony
663925f9e8 [v2] v2.0.0-beta.19 2021-11-08 21:03:42 +11:00
Lea Anthony
cc2651c377 [v2] Tidy up 2021-11-08 21:02:54 +11:00
Lea Anthony
e651b9c7ff [v2] Fix dev build when no dev command in project 2021-11-08 21:01:42 +11:00
Lea Anthony
bcad236fb6 [v2] Revert svelte template changes 2021-11-08 20:53:13 +11:00
Lea Anthony
0af8d506c1 [v2] v2.0.0-beta.18 2021-11-08 20:28:04 +11:00
Lea Anthony
0b65a0f508 [v2] Fix svelte template 2021-11-08 20:27:28 +11:00
Lea Anthony
b03a758747 [v2] v2.0.0-beta.17 2021-11-08 20:13:29 +11:00
Lea Anthony
44597f2fbc [v2] Fix svelte template 2021-11-08 20:12:29 +11:00
Lea Anthony
0844113f3a [v2] Fix vanilla template 2021-11-08 20:08:41 +11:00
Lea Anthony
79e99b68d6 [v2] Fix css in templates 2021-11-08 19:23:28 +11:00
Lea Anthony
c64b7bb79c [v2] v2.0.0-beta.16 2021-11-08 19:15:07 +11:00
Lea Anthony
e72b438ad2 [website] Fix blog 2021-11-08 19:13:54 +11:00
Lea Anthony
3e4a112a3d Merge pull request #922 from wailsapp/v2-mac-docs
V2 Mac updates
2021-11-08 08:12:07 +00:00
Lea Anthony
a020b67f67 [website] Fix desktop icon 2021-11-08 19:10:31 +11:00
Lea Anthony
fa958e7a07 [website] assetdir clarification 2021-11-08 17:38:30 +11:00
Lea Anthony
1a3e81a3f8 [website] Misc updates 2021-11-08 17:36:08 +11:00
Lea Anthony
0eb7a8a771 [v2] Update svelte template 2021-11-08 07:00:01 +11:00
Lea Anthony
2fa004808f [website] Update options example 2021-11-08 06:31:34 +11:00
Lea Anthony
cc5fd30256 [v2] Update vanilla template 2021-11-08 06:31:13 +11:00
Lea Anthony
c90bfc310a [mac] Fix lifecycle hooks 2021-11-06 10:40:02 +11:00
Lea Anthony
62d1d621aa [mac] Tidy up 2021-11-04 20:58:08 +11:00
Lea Anthony
6e8cbb8e8f [mac] Ensure minimum osx version 2021-11-04 20:45:22 +11:00
Lea Anthony
32fa543164 [website] Update docs 2021-11-03 19:25:42 +11:00
Lea Anthony
04f93ac54e [v2] Update go.mod 2021-11-03 19:24:12 +11:00
Lea Anthony
3c87d13b21 [mac] Fix fullscreen 2021-11-03 19:23:23 +11:00
Lea Anthony
0949eab72e [linux] add flag 2021-11-03 19:22:59 +11:00
Lea Anthony
aab67b416f [mac] add default menu 2021-11-03 19:22:38 +11:00
Lea Anthony
83a575e43f [v2] warn if wails version out of sync during build 2021-11-02 22:33:34 +11:00
Lea Anthony
333949ee53 [mac] better output text on build 2021-11-02 22:20:44 +11:00
Lea Anthony
1d1238cea3 [website] add cross compile 2021-11-02 22:19:59 +11:00
Lea Anthony
bd7b436631 [mac] Add fallback for app name 2021-11-02 22:05:42 +11:00
Lea Anthony
c136df48b9 [mac] Fix App Name in app menu 2021-11-02 22:04:06 +11:00
Lea Anthony
a090a689cf [mac] Fix plist generation 2021-11-02 21:56:35 +11:00
Lea Anthony
5ef2448a0c [website] updates 2021-11-02 21:00:56 +11:00
Lea Anthony
06ab4c88ad [website] updates 2021-11-02 20:54:42 +11:00
Lea Anthony
48efdea11a [website] updates 2021-11-02 20:54:13 +11:00
Lea Anthony
43cc55cb0a [mac] Small tweaks 2021-11-02 20:06:59 +11:00
Lea Anthony
71f2436562 [website] Add Mac options 2021-11-02 08:31:21 +11:00
Lea Anthony
4653c77a81 Merge branch 'master' into v2-mac-docs 2021-11-02 08:20:20 +11:00
Lea Anthony
72b05c6b44 Merge pull request #907 from phoenix147/appargs
Appargs
2021-11-02 07:23:00 +11:00
Lukas Crepaz
b5f68e24d6 added appargs for application arguments in dev mode 2021-11-01 08:57:10 +01:00
Lukas Crepaz
3948c8ca61 use environment variables to supply the development binary with flags to support CLI arguments in the app 2021-10-31 09:12:22 +01:00
Lea Anthony
cf3a868e3a [mac] Support MenuUpdateApplicationMenu 2021-10-31 15:09:50 +11:00
Lea Anthony
43c29abb23 Merge pull request #901 from misitebao/synchronize-chinese-documents
docs: synchronize chinese documents
2021-10-31 08:55:22 +11:00
Lea Anthony
7ef445f526 [mac] Improve string/memory handling, dialog icon -> []byte 2021-10-31 08:50:14 +11:00
misitebao
f6c2d4ae6b docs: synchronize all chinese documents 2021-10-31 04:32:38 +08:00
misitebao
8f9fae6ad9 docs: synchronize chinese readme logo size 2021-10-31 03:02:00 +08:00
misitebao
b45f264e2a docs: synchronize chinese readme 2021-10-31 02:55:01 +08:00
misitebao
986f8f48c7 docs: organize the readme 2021-10-31 02:54:22 +08:00
misitebao
bbc2e86286 docs: update chinese readme 2021-10-31 02:27:47 +08:00
Lea Anthony
2dc126bf19 [mac] Fix ExecJS 2021-10-30 19:28:25 +11:00
Lea Anthony
86cbcdc089 [mac] Move ops to main thread 2021-10-30 17:19:58 +11:00
Lea Anthony
1dd957f461 [mac] Fix SetPosition 2021-10-30 16:31:06 +11:00
Lea Anthony
4be4946756 [mac] Fix SetMaxSize 2021-10-30 11:07:07 +11:00
Lea Anthony
65979cbc75 Merge pull request #900 from misitebao/synchronize-chinese-documents
docs: synchronize chinese documents
2021-10-30 10:57:05 +11:00
Lea Anthony
6a7118ff6d [mac] Support cross compiling to windows 2021-10-30 10:44:22 +11:00
Lea Anthony
a88b3553ba [mac] Support min/max 2021-10-30 10:34:55 +11:00
Lea Anthony
fd5348d26d [v2] Fix build output 2021-10-30 10:33:30 +11:00
Lea Anthony
569569f1fc [mac] support amd/arm/universal 2021-10-30 10:19:49 +11:00
Lea Anthony
489b9b358b [mac] menu support 2021-10-30 09:51:46 +11:00
misitebao
71cfdfc7c8 feat: increase synchronized content 2021-10-29 03:15:42 +08:00
misitebao
6ebf4ed428 feat: synchronize some chinese documents 2021-10-29 03:15:04 +08:00
misitebao
5be0739c5d feat(website): synchronize chinese credits 2021-10-28 18:45:45 +08:00
Lea Anthony
6721e59277 [v2] Fix build command for dev mode 2021-10-28 19:24:05 +11:00
Lea Anthony
77775d85ab v1.16.8 2021-10-26 19:38:53 +11:00
Lea Anthony
6de0865c3e Merge pull request #896 from wailsapp/develop
Develop
2021-10-26 19:36:48 +11:00
197 changed files with 6876 additions and 1506 deletions

175
README.md
View File

@@ -1,59 +1,92 @@
<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>
## Internationalization
English | [简体中文](README.zh-Hans.md)
[English](README.md) | [简体中文](README.zh-Hans.md)
<span id="nav-2"></span>
## Table of Contents
<details>
<summary>Click me to Open/Close the directory listing</summary>
- [1. Internationalization](#nav-1)
- [2. Table of Contents](#nav-2)
- [3. Introduction](#nav-3)
- [3.1 Official Website](#nav-3-1)
- [4. Features](#nav-4)
- [5. Sponsors](#nav-5)
- [6. Installation](#nav-6)
- [6.1 MacOS](#nav-6-1)
- [6.2 Linux](#nav-6-2)
- [6.2.1 Debian/Ubuntu](#nav-6-2-1)
- [6.2.2 Arch Linux / ArchLabs / Ctlos Linux](#nav-6-2-2)
- [6.2.3 Centos](#nav-6-2-3)
- [6.2.4 Fedora](#nav-6-2-4)
- [6.2.5 VoidLinux & VoidLinux-musl](#nav-6-2-5)
- [6.2.6 Gentoo](#nav-6-2-6)
- [6.3 Windows](#nav-6-3)
- [7. Usage](#nav-7)
- [7.1 Next Steps](#nav-7-1)
- [8. FAQ](#nav-8)
- [9. Contributors](#nav-9)
- [10. Special Mentions](#nav-10)
- [12. Special Thanks](#nav-11)
</details>
<span id="nav-3"></span>
## Introductions
The traditional method of providing web interfaces to Go programs is via a built-in web server. Wails offers a different
approach: it provides the ability to wrap both Go code and a web frontend into a single binary. Tools are provided to
make this easy for you by handling project creation, compilation and bundling. All you have to do is get creative!
<span id="nav-3-1"></span>
### Official Website
The official docs can be found at [https://wails.app](https://wails.app).
Click [here](https://wails.io) if you are interested in trying out v2 Beta for Windows.
<span id="nav-2"></span>
## Contents
- [1. Internationalization](#nav-1)
- [2. Contents](#nav-2)
- [3. Features](#nav-3)
- [4. Sponsors](#nav-4)
- [5. Installation](#nav-5)
- [5.1 MacOS](#nav-5-1)
- [5.2 Linux](#nav-5-2)
- [5.2.1 Debian/Ubuntu](#nav-5-2-1)
- [5.2.2 Arch Linux / ArchLabs / Ctlos Linux](#nav-5-2-2)
- [5.2.3 Centos](#nav-5-2-3)
- [5.2.4 Fedora](#nav-5-2-4)
- [5.2.5 VoidLinux & VoidLinux-musl](#nav-5-2-5)
- [5.2.6 Gentoo](#nav-5-2-6)
- [5.3 Windows](#nav-5-3)
- [6. Installation](#nav-6)
- [7. Next Steps](#nav-7)
- [8. FAQ](#nav-8)
- [9. Contributors](#nav-9)
- [10. Special Mentions](#nav-10)
- [11. Special Thanks](#nav-11)
<span id="nav-3"></span>
<span id="nav-4"></span>
## Features
@@ -67,12 +100,20 @@ Click [here](https://wails.io) if you are interested in trying out v2 Beta for W
- Powerful cli tool
- Multiplatform
<span id="nav-4"></span>
<span id="nav-5"></span>
## Sponsors
This project is supported by these kind people / companies:
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
<img src="sponsors/silver%20sponsor.png" width="100"/>
</a>
<a href="https://github.com/letheanVPN" style="width:100px;">
<img src="https://github.com/letheanVPN.png?size=100" width="100"/>
</a>
<br/>
<br/>
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
<img src="sponsors/bronze%20sponsor.png" width="100"/>
</a>
@@ -82,13 +123,16 @@ This project is supported by these kind people / companies:
<a href="https://github.com/codydbentley" style="width:100px">
<img src="https://github.com/codydbentley.png?size=100" width="100"/>
</a>
<a href="https://github.com/CrackDavid" style="width:100px">
<img src="https://github.com/CrackDavid.png?size=100" width="100"/>
</a>
<br/>
<br/>
<a href="https://github.com/matryer" style="width:100px">
<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"/>
@@ -141,8 +185,11 @@ This project is supported by these kind people / companies:
<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>
<span id="nav-5"></span>
<span id="nav-6"></span>
## Installation
@@ -152,7 +199,7 @@ an installation of Go. The basic requirements are:
- Go 1.16
- npm
<span id="nav-5-1"></span>
<span id="nav-6-1"></span>
### MacOS
@@ -160,11 +207,11 @@ Make sure you have the xcode command line tools installed. This can be done by r
`xcode-select --install`
<span id="nav-5-2"></span>
<span id="nav-6-2"></span>
### Linux
<span id="nav-5-2-1"></span>
<span id="nav-6-2-1"></span>
#### Debian/Ubuntu
@@ -176,7 +223,7 @@ _Ubuntu: 16.04, 18.04, 19.04_
_Also succesfully tested on: Zorin 15, Parrot 4.7, Linuxmint 19, Elementary 5, Kali, Neon_, Pop!\_OS
<span id="nav-5-2-2"></span>
<span id="nav-6-2-2"></span>
#### Arch Linux / ArchLabs / Ctlos Linux
@@ -184,7 +231,7 @@ _Also succesfully tested on: Zorin 15, Parrot 4.7, Linuxmint 19, Elementary 5, K
_Also succesfully test on: Manjaro & ArcoLinux_
<span id="nav-5-2-3"></span>
<span id="nav-6-2-3"></span>
#### Centos
@@ -192,7 +239,7 @@ _Also succesfully test on: Manjaro & ArcoLinux_
_CentOS 6, 7_
<span id="nav-5-2-4"></span>
<span id="nav-6-2-4"></span>
#### Fedora
@@ -200,19 +247,19 @@ _CentOS 6, 7_
_Fedora 29, 30_
<span id="nav-5-2-5"></span>
<span id="nav-6-2-5"></span>
#### VoidLinux & VoidLinux-musl
`xbps-install gtk+3-devel webkit2gtk-devel`
<span id="nav-5-2-6"></span>
<span id="nav-6-2-6"></span>
#### Gentoo
`sudo emerge gtk+:3 webkit-gtk`
<span id="nav-5-3"></span>
<span id="nav-6-3"></span>
### Windows
@@ -220,21 +267,21 @@ Windows requires gcc and related tooling. The recommended download is
from [http://tdm-gcc.tdragon.net/download](http://tdm-gcc.tdragon.net/download). Once this is installed, you are good to
go.
<span id="nav-6"></span>
<span id="nav-7"></span>
## Installation
## Usage
**Ensure Go modules are enabled: GO111MODULE=on and go/bin is in your PATH variable.**
Installation is as simple as running the following command:
<pre style='color:white'>
```
go get -u github.com/wailsapp/wails/cmd/wails
</pre>
```
<span id="nav-7"></span>
<span id="nav-7-1"></span>
## Next Steps
### Next Steps
It is recommended at this stage to read the comprehensive documentation at [https://wails.app](https://wails.app).
@@ -304,11 +351,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>
@@ -344,13 +391,13 @@ 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 <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/>
<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>
<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>

View File

@@ -1,61 +1,97 @@
<p align="center" style="text-align: center">
<img src="logo.png" width="40%"><br/>
<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>
## 国际化
[English](README.md) | 简体中文
向 Go 程序提供 Web 接口的传统方法是通过内置 Web 服务器。Wails 提供了一种不同的方法:它提供了将 Go 代码和 Web
前端都包装成单个二进制文件的能力。通过提供工具,可以很轻松的完成项目的创建、编译和打包。你所要做的就是发挥创意!
官方文档可以在 [https://wails.app](https://wails.app) 中找到。
国内镜像站点 [https://wails.top](https://wails.top)。
[English](README.md) | [简体中文](README.zh-Hans.md)
<span id="nav-2"></span>
## 内容目录
<details>
<summary>点我 打开/关闭 目录列表</summary>
- [1. 国际化](#nav-1)
- [2. 内容目录](#nav-2)
- [3. 特征](#nav-3)
- [4. 赞助商](#nav-4)
- [5. 安装](#nav-5)
- [5.1 MacOS](#nav-5-1)
- [5.2 Linux](#nav-5-2)
- [5.2.1 Debian/Ubuntu](#nav-5-2-1)
- [5.2.2 Arch Linux / ArchLabs / Ctlos Linux](#nav-5-2-2)
- [5.2.3 Centos](#nav-5-2-3)
- [5.2.4 Fedora](#nav-5-2-4)
- [5.2.5 VoidLinux & VoidLinux-musl](#nav-5-2-5)
- [5.2.6 Gentoo](#nav-5-2-6)
- [5.3 Windows](#nav-5-3)
- [3. 项目介绍](#nav-3)
- [3.1 官方网站](#nav-3-1)
- [4. 功能](#nav-4)
- [5. 赞助商](#nav-5)
- [6. 安装](#nav-6)
- [7. 下一步](#nav-7)
- [6.1 MacOS](#nav-6-1)
- [6.2 Linux](#nav-6-2)
- [6.2.1 Debian/Ubuntu](#nav-6-2-1)
- [6.2.2 Arch Linux / ArchLabs / Ctlos Linux](#nav-6-2-2)
- [6.2.3 Centos](#nav-6-2-3)
- [6.2.4 Fedora](#nav-6-2-4)
- [6.2.5 VoidLinux & VoidLinux-musl](#nav-6-2-5)
- [6.2.6 Gentoo](#nav-6-2-6)
- [6.3 Windows](#nav-6-3)
- [7. 使用方法](#nav-7)
- [7.1 下一步](#nav-7-1)
- [8. 常见问题](#nav-8)
- [9. 贡献者](#nav-9)
- [10. 特别提及](#nav-10)
- [11. 许可协议](#nav-11)
- [12. 特别感谢](#nav-12)
- [12. 特别感谢](#nav-11)
</details>
<span id="nav-3"></span>
## 特征
## 项目介绍
为 Go 程序提供 Web 界面的传统方法是通过内置 Web 服务器。Wails 提供了一种不同的方法:它提供了将 Go 代码和 Web
前端一起打包成单个二进制文件的能力。通过提供的工具,可以很轻松的完成项目的创建、编译和打包。你所要做的就是发挥想象力!
<span id="nav-3-1"></span>
### 官方网站
官方文档可以在 [https://wails.app](https://wails.app) 中找到。
如果您对适用于 Windows 的 v2 测试版感兴趣,可以点击[此处](https://wails.io)查看。
镜像网站:
- [中国大陆镜像站点 - https://wails.top](https://wails.top)
<span id="nav-4"></span>
## 功能
- 后端使用标准 Go
- 使用任意前端技术构建 UI 界面
@@ -67,13 +103,20 @@
- 强大的命令行工具
- 跨多个平台
<span id="nav-4"></span>
<span id="nav-5"></span>
## 赞助商
这个项目由以下这些人或者公司支持:
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
<img src="sponsors/silver%20sponsor.png" width="100"/>
</a>
<a href="https://github.com/letheanVPN" style="width:100px;">
<img src="https://github.com/letheanVPN.png?size=100" width="100"/>
</a>
<br/>
<br/>
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
<img src="sponsors/bronze%20sponsor.png" width="100"/>
</a>
@@ -83,13 +126,16 @@
<a href="https://github.com/codydbentley" style="width:100px">
<img src="https://github.com/codydbentley.png?size=100" width="100"/>
</a>
<a href="https://github.com/CrackDavid" style="width:100px">
<img src="https://github.com/CrackDavid.png?size=100" width="100"/>
</a>
<br/>
<br/>
<a href="https://github.com/matryer" style="width:100px">
<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"/>
@@ -142,8 +188,11 @@
<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>
<span id="nav-5"></span>
<span id="nav-6"></span>
## 安装
@@ -152,7 +201,7 @@ Wails 使用 cgo 与原生渲染引擎结合,因此需要依赖一些平台的
- Go 1.16
- npm
<span id="nav-5-1"></span>
<span id="nav-6-1"></span>
### MacOS
@@ -160,11 +209,11 @@ Wails 使用 cgo 与原生渲染引擎结合,因此需要依赖一些平台的
`xcode-select --install`
<span id="nav-5-2"></span>
<span id="nav-6-2"></span>
### Linux
<span id="nav-5-2-1"></span>
<span id="nav-6-2-1"></span>
#### Debian/Ubuntu
@@ -176,7 +225,7 @@ _Ubuntu: 16.04, 18.04, 19.04_
_也成功测试了: Zorin 15, Parrot 4.7, Linuxmint 19, Elementary 5, Kali, Neon_, Pop!\_OS
<span id="nav-5-2-2"></span>
<span id="nav-6-2-2"></span>
#### Arch Linux / ArchLabs / Ctlos Linux
@@ -184,7 +233,7 @@ _也成功测试了: Zorin 15, Parrot 4.7, Linuxmint 19, Elementary 5, Kali, Neo
_也成功测试了: Manjaro & ArcoLinux_
<span id="nav-5-2-3"></span>
<span id="nav-6-2-3"></span>
#### Centos
@@ -192,7 +241,7 @@ _也成功测试了: Manjaro & ArcoLinux_
_CentOS 6, 7_
<span id="nav-5-2-4"></span>
<span id="nav-6-2-4"></span>
#### Fedora
@@ -200,39 +249,39 @@ _CentOS 6, 7_
_Fedora 29, 30_
<span id="nav-5-2-5"></span>
<span id="nav-6-2-5"></span>
#### VoidLinux & VoidLinux-musl
`xbps-install gtk+3-devel webkit2gtk-devel`
<span id="nav-5-2-6"></span>
<span id="nav-6-2-6"></span>
#### Gentoo
`sudo emerge gtk+:3 webkit-gtk`
<span id="nav-5-3"></span>
<span id="nav-6-3"></span>
### Windows
Windows 需要 GCC 和相关工具。 建议从 [http://tdm-gcc.tdragon.net/download](http://tdm-gcc.tdragon.net/download) 下载, 安装完成,您就可以开始了。
<span id="nav-6"></span>
<span id="nav-7"></span>
## 安装
## 使用方法
**确保 Go modules 是开启的GO111MODULE=on 并且 go/bin 在您的 PATH 变量中。**
安装很简单,运行以下命令:
<pre style='color:white'>
```
go get -u github.com/wailsapp/wails/cmd/wails
</pre>
```
<span id="nav-7"></span>
<span id="nav-7-1"></span>
## 下一步
### 下一步
建议在此时阅读 [https://wails.app](https://wails.app) 上面的文档.
@@ -244,14 +293,14 @@ go get -u github.com/wailsapp/wails/cmd/wails
取决于您的要求。它旨在使 Go 程序员可以轻松制作轻量级桌面应用程序或在其现有应用程序中添加前端。尽管 Wails 当前不提供对诸如菜单之类的原生元素的钩子,但将来可能会改变。
- 这个项目针对的是?
- 这个项目针对的是哪些人?
希望将 HTML / JS / CSS 前端与其应用程序捆绑在一起的程序员,而不是借助创建服务并打开浏览器进行查看的方式。
- 名字怎么来的?
当我看到 WebView 时,我想"我真正想要的是围绕构建 WebView 应用程序工作,有点像 Rails 对于 Ruby"。因此最初它是一个文字游戏Webview on
Rails。碰巧也是我来自的 [国家](https://en.wikipedia.org/wiki/Wales) 的英文名字的同音。所以就是了。
Rails。碰巧也是我来自的 [国家](https://en.wikipedia.org/wiki/Wales) 的英文名字的同音。所以就是了。
<span id="nav-9"></span>
@@ -298,10 +347,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/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>
@@ -311,9 +361,9 @@ go get -u github.com/wailsapp/wails/cmd/wails
- [Dustin Krysak](https://wiki.ubuntu.com/bashfulrobot) - 他的支持和反馈是巨大的。
- [Serge Zaitsev](https://github.com/zserge) - Wails 窗口所使用的 [Webview](https://github.com/zserge/webview) 的作者。
- [Byron](https://github.com/bh90210) - 有时Byron 单枪匹马地保持这个项目活着。没有他令人难以置信的投入,我们永远不会得到 v1 。
- [Byron](https://github.com/bh90210) - 有时Byron 一个人保持这个项目活着。没有他令人难以置信的投入,我们永远不会得到 v1 。
This project was mainly coded to the following albums:
编写项目代码时伴随着以下专辑:
- [Manic Street Preachers - Resistance Is Futile](https://open.spotify.com/album/1R2rsEUqXjIvAbzM0yHrxA)
- [Manic Street Preachers - This Is My Truth, Tell Me Yours](https://open.spotify.com/album/4VzCL9kjhgGQeKCiojK1YN)
@@ -331,22 +381,16 @@ This project was mainly coded to the following albums:
<span id="nav-11"></span>
## 许可协议
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwailsapp%2Fwails.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fwailsapp%2Fwails?ref=badge_large)
<span id="nav-12"></span>
## 特别感谢
<p align="center" style="text-align: center">
<a href="https://pace.dev"><img src="pace.jpeg"/></a><br/>
<i>非常<i/>感谢<a href="https://pace.dev">Pace</a>对项目的赞助,并帮助将 Wails 移植到 Apple Silicon !<br/><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>
<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>

View File

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 103 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -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.
@@ -156,14 +155,14 @@ func (fs *FSHelper) LoadRelativeFile(relativePath string) ([]byte, error) {
if err != nil {
return nil, err
}
return ioutil.ReadFile(fullPath)
return os.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 +214,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 +230,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

View 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
}

View File

@@ -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

View File

@@ -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
}
@@ -334,12 +333,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 +386,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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -1,4 +1,4 @@
package cmd
// Version - Wails version
const Version = "v1.16.7"
const Version = "v1.16.8"

View File

@@ -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

View File

@@ -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
View File

@@ -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
View File

@@ -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=

View File

@@ -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

BIN
sponsors/silver sponsor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -5,11 +5,15 @@ import (
"io"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"text/tabwriter"
"time"
"github.com/wailsapp/wails/v2/cmd/wails/internal"
"github.com/wailsapp/wails/v2/internal/gomod"
"github.com/wailsapp/wails/v2/internal/system"
"github.com/leaanthony/clir"
@@ -42,7 +46,7 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
// Setup Platform flag
platform := runtime.GOOS
//command.StringFlag("platform", "Platform to target", &platform)
command.StringFlag("platform", "Platform to target", &platform)
// Verbosity
verbosity := 1
@@ -100,9 +104,10 @@ 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", platform)
return fmt.Errorf("platform %s is not supported. Platforms supported: %s", platform, validPlatformArch.Join(","))
}
if compress && platform == "darwin/universal" {
@@ -129,8 +134,8 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
}
}
if runtime.GOOS == "darwin" && !experimental {
return fmt.Errorf("MacOS version coming soon!")
if runtime.GOOS == "linux" && !experimental {
return fmt.Errorf("Linux version coming soon!")
}
// Webview2 installer strategy (download by default)
@@ -205,6 +210,11 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
fmt.Fprintf(w, "\n")
w.Flush()
err = checkGoModVersion(logger)
if err != nil {
return err
}
return doBuild(buildOptions)
})
}
@@ -228,3 +238,29 @@ func doBuild(buildOptions *build.Options) error {
return nil
}
func checkGoModVersion(logger *clilogger.CLILogger) error {
cwd, err := os.Getwd()
if err != nil {
return err
}
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
}
gomodversion, err := gomod.GetWailsVersionFromModFile(gomodData)
if err != nil {
return err
}
logger.Println("Warning: go.mod is using Wails '%s' but the CLI is '%s'. Consider updating it.\n", gomodversion.String(), internal.Version)
return nil
}

View File

@@ -16,10 +16,10 @@ import (
"syscall"
"time"
"github.com/google/shlex"
"github.com/wailsapp/wails/v2/cmd/wails/internal"
"github.com/wailsapp/wails/v2/internal/gomod"
"github.com/leaanthony/slicer"
"github.com/wailsapp/wails/v2/internal/project"
"github.com/pkg/browser"
@@ -72,6 +72,7 @@ type devFlags struct {
forceBuild bool
debounceMS int
devServerURL string
appargs string
}
// AddSubcommand adds the `dev` command for the Wails application
@@ -93,6 +94,7 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
command.BoolFlag("f", "Force build application", &flags.forceBuild)
command.IntFlag("debounce", "The amount of time to wait to trigger a reload on change", &flags.debounceMS)
command.StringFlag("devserverurl", "The url of the dev server to use", &flags.devServerURL)
command.StringFlag("appargs", "arguments to pass to the underlying app (quoted and space searated)", &flags.appargs)
command.Action(func() error {
// Create logger
@@ -111,8 +113,8 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
}
}
if runtime.GOOS == "darwin" && !experimental {
return fmt.Errorf("MacOS version coming soon!")
if runtime.GOOS == "linux" && !experimental {
return fmt.Errorf("Linux version coming soon!")
}
cwd, err := os.Getwd()
@@ -276,7 +278,7 @@ func generateBuildOptions(flags devFlags) *build.Options {
OutputType: "dev",
Mode: build.Dev,
Arch: runtime.GOARCH,
Pack: false,
Pack: true,
Platform: runtime.GOOS,
LDFlags: flags.ldflags,
Compiler: flags.compilerCommand,
@@ -285,10 +287,7 @@ func generateBuildOptions(flags devFlags) *build.Options {
Verbosity: flags.verbosity,
WailsJSDir: flags.wailsjsdir,
}
switch runtime.GOOS {
case "darwin":
result.Pack = false
}
return result
}
@@ -353,6 +352,10 @@ func loadAndMergeProjectConfig(cwd string, flags *devFlags) (*project.Project, e
shouldSaveConfig = true
}
if flags.appargs == "" && projectConfig.AppArgs != "" {
flags.appargs = projectConfig.AppArgs
}
if shouldSaveConfig {
err = projectConfig.Save()
if err != nil {
@@ -463,16 +466,20 @@ func restartApp(buildOptions *build.Options, debugBinaryProcess *process.Process
debugBinaryProcess = nil
}
// parse appargs if any
args, err := shlex.Split(flags.appargs)
if err != nil {
buildOptions.Logger.Fatal("Unable to parse appargs: %s", err.Error())
}
// Set environment variables accordingly
os.Setenv("loglevel", flags.loglevel)
os.Setenv("assetdir", flags.assetDir)
os.Setenv("devserverurl", flags.devServerURL)
// Start up new binary with correct args
args := slicer.StringSlicer{}
args.Add("-loglevel", flags.loglevel)
if flags.assetDir != "" {
args.Add("-assetdir", flags.assetDir)
}
if flags.devServerURL != "" {
args.Add("-devserverurl", flags.devServerURL)
}
newProcess := process.NewProcess(appBinary, args.AsSlice()...)
newProcess := process.NewProcess(appBinary, args...)
err = newProcess.Start(exitCodeChannel)
if err != nil {
// Remove binary

View File

@@ -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,
},

View File

@@ -0,0 +1,16 @@
{
"name": "{{.ProjectName}}",
"author": "",
"private": true,
"scripts": {
"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"
},
"workspaces": [
"frontend"
]
}

View File

@@ -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
}

View File

@@ -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"
@@ -295,7 +294,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
}

View File

@@ -2,7 +2,7 @@
html {
text-align: center;
color: white;
background-color: rgba(0, 0, 0, 255);
background-color: rgba(33, 37, 43, 0.2);
width: 100%;
height: 100%;
}

View File

@@ -4,6 +4,8 @@ import (
"embed"
"log"
"github.com/wailsapp/wails/v2/pkg/options/mac"
"github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/logger"
"github.com/wailsapp/wails/v2/pkg/options"
@@ -13,6 +15,9 @@ import (
//go:embed frontend/dist
var assets embed.FS
//go:embed build/appicon.png
var icon []byte
func main() {
// Create an instance of the app structure
app := NewApp()
@@ -31,7 +36,7 @@ func main() {
Frameless: false,
StartHidden: false,
HideWindowOnClose: false,
RGBA: &options.RGBA{R: 255, G: 255, B: 255, A: 255},
RGBA: &options.RGBA{R: 33, G: 37, B: 43, A: 255},
Assets: assets,
LogLevel: logger.DEBUG,
OnStartup: app.startup,
@@ -46,6 +51,17 @@ func main() {
WindowIsTranslucent: false,
DisableWindowIcon: false,
},
Mac: &mac.Options{
TitleBar: mac.TitleBarHiddenInset(),
Appearance: mac.NSAppearanceNameDarkAqua,
WebviewIsTransparent: true,
WindowIsTranslucent: true,
About: &mac.AboutInfo{
Title: "My Application",
Message: "© 2021 Me",
Icon: icon,
},
},
})
if err != nil {

View File

@@ -4,6 +4,7 @@
"assetdir": "frontend/dist",
"frontend:install": "npm install",
"frontend:build": "npm run build",
"wailsjsdir": "./frontend",
"author": {
"name": "{{.AuthorName}}",
"email": "{{.AuthorEmail}}"

View File

@@ -1,12 +1,11 @@
html {
background-color: rgba(33, 37, 43, 1);
background-color: rgba(33, 37, 43, 0.2);
text-align: center;
color: white;
}
body {
margin: 0;
color: white;
font-family: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
"Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;

View File

@@ -4,6 +4,8 @@ import (
"embed"
"log"
"github.com/wailsapp/wails/v2/pkg/options/mac"
"github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/logger"
"github.com/wailsapp/wails/v2/pkg/options"
@@ -13,6 +15,9 @@ import (
//go:embed frontend/src
var assets embed.FS
//go:embed build/appicon.png
var icon []byte
func main() {
// Create an instance of the app structure
app := NewApp()
@@ -31,7 +36,7 @@ func main() {
Frameless: false,
StartHidden: false,
HideWindowOnClose: false,
RGBA: &options.RGBA{R: 255, G: 255, B: 255, A: 255},
RGBA: &options.RGBA{R: 33, G: 37, B: 43, A: 255},
Assets: assets,
LogLevel: logger.DEBUG,
OnStartup: app.startup,
@@ -46,6 +51,16 @@ func main() {
WindowIsTranslucent: false,
DisableWindowIcon: false,
},
Mac: &mac.Options{
TitleBar: mac.TitleBarHiddenInset(),
WebviewIsTransparent: true,
WindowIsTranslucent: true,
About: &mac.AboutInfo{
Title: "Vanilla Template",
Message: "Part of the Wails projects",
Icon: icon,
},
},
})
if err != nil {

View File

@@ -2,6 +2,7 @@
"name": "{{.ProjectName}}",
"outputfilename": "{{.BinaryName}}",
"assetdir": "frontend/src",
"wailsjsdir": "./frontend",
"author": {
"name": "{{.AuthorName}}",
"email": "{{.AuthorEmail}}"

View File

@@ -1,3 +1,3 @@
package internal
var Version = "v2.0.0-beta.15"
var Version = "v2.0.0-beta.21"

View File

@@ -13,6 +13,7 @@ require (
github.com/gofiber/fiber/v2 v2.17.0
github.com/gofiber/websocket/v2 v2.0.8
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/google/uuid v1.1.2 // indirect
github.com/gorilla/websocket v1.4.1
github.com/imdario/mergo v0.3.12
@@ -21,13 +22,13 @@ 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 v0.0.0-20211202091502-64deee9a37e3
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
@@ -39,7 +40,6 @@ 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
@@ -54,12 +54,13 @@ require (
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
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
github.com/klauspost/compress v1.12.2 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e // indirect
github.com/mattn/go-runewidth v0.0.7 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect

View File

@@ -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=
@@ -75,6 +75,8 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
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=
@@ -101,8 +103,9 @@ github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -115,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 v0.0.0-20211202091502-64deee9a37e3 h1:vKdQzUWiq5wtVBLTTeYuikcgQbF/HtYaOmxGzbfkcT0=
github.com/leaanthony/go-webview2 v0.0.0-20211202091502-64deee9a37e3/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=
@@ -127,8 +130,8 @@ github.com/leaanthony/typescriptify-golang-structs v0.1.7 h1:yoznzWzyxkO/iWdlpq+
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=
@@ -159,6 +162,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.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/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/savsgio/gotils v0.0.0-20200117113501-90175b0fbe3f h1:PgA+Olipyj258EIEYnpFFONrrCcAIWNUNoFhUfMqAGY=
github.com/savsgio/gotils v0.0.0-20200117113501-90175b0fbe3f/go.mod h1:lHhJedqxCoHN+zMtwGNTXWmF0u9Jt363FYRhV6g0CdY=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
@@ -208,8 +213,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=
@@ -247,10 +250,10 @@ 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=
@@ -280,10 +283,12 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@@ -1,3 +1,4 @@
//go:build !windows
// +build !windows
package wails

View File

@@ -1,3 +1,4 @@
//go:build !desktop && !hybrid && !server && !dev
// +build !desktop,!hybrid,!server,!dev
package app

View File

@@ -1,3 +1,4 @@
//go:build !server && !desktop && hybrid
// +build !server,!desktop,hybrid
package app

View File

@@ -1,4 +1,5 @@
//+build !windows
//go:build !windows
// +build !windows
package app

View File

@@ -1,4 +1,5 @@
//+build windows
//go:build windows
// +build windows
package app

View File

@@ -61,6 +61,9 @@ func generateBindings(bindings *binding.Bindings) error {
return err
}
if projectConfig.WailsJSDir == "" {
projectConfig.WailsJSDir = filepath.Join(cwd, "frontend")
}
wrapperDir := filepath.Join(projectConfig.WailsJSDir, "wailsjs", "runtime")
_ = os.RemoveAll(wrapperDir)
extractor := gosod.New(wrapper.RuntimeWrapper)
@@ -100,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
}

View File

@@ -0,0 +1,32 @@
//go:build !dev && !production && !bindings && linux
package appng
import (
"fmt"
"github.com/wailsapp/wails/v2/pkg/options"
)
// App defines a Wails application structure
type App struct{}
func (a *App) Run() error {
return nil
}
// CreateApp creates the app!
func CreateApp(_ *options.App) (*App, error) {
// result := w32.MessageBox(0,
// `Wails applications will not build without the correct build tags.
//Please use "wails build" or press "OK" to open the documentation on how to use "go build"`,
// "Error",
// w32.MB_ICONERROR|w32.MB_OKCANCEL)
// if result == 1 {
// exec.Command("rundll32", "url.dll,FileProtocolHandler", "https://wails.io").Start()
// }
err := fmt.Errorf(`Wails applications will not build without the correct build tags.`)
return nil, err
}

View File

@@ -6,6 +6,9 @@ package appng
import (
"context"
"flag"
"os"
"path/filepath"
"github.com/wailsapp/wails/v2/internal/binding"
"github.com/wailsapp/wails/v2/internal/frontend"
"github.com/wailsapp/wails/v2/internal/frontend/desktop"
@@ -16,18 +19,14 @@ import (
"github.com/wailsapp/wails/v2/internal/logger"
"github.com/wailsapp/wails/v2/internal/menumanager"
"github.com/wailsapp/wails/v2/internal/project"
"github.com/wailsapp/wails/v2/internal/signal"
pkglogger "github.com/wailsapp/wails/v2/pkg/logger"
"github.com/wailsapp/wails/v2/pkg/options"
"os"
"path/filepath"
)
// App defines a Wails application structure
type App struct {
frontend frontend.Frontend
logger *logger.Logger
signal *signal.Manager
options *options.App
menuManager *menumanager.Manager
@@ -60,19 +59,47 @@ func CreateApp(appoptions *options.App) (*App, error) {
myLogger.SetLogLevel(appoptions.LogLevel)
// Check for CLI Flags
assetdir := flag.String("assetdir", "", "Directory to serve assets")
devServerURL := flag.String("devserverurl", "", "URL of development server")
loglevel := flag.String("loglevel", "debug", "Loglevel to use - Trace, Debug, Info, Warning, Error")
flag.Parse()
if devServerURL != nil && *devServerURL != "" {
ctx = context.WithValue(ctx, "devserverurl", *devServerURL)
var assetdirFlag *string
var devServerURLFlag *string
var loglevelFlag *string
assetdir := os.Getenv("assetdir")
if assetdir == "" {
assetdirFlag = flag.String("assetdir", "", "Directory to serve assets")
}
if assetdir != nil && *assetdir != "" {
ctx = context.WithValue(ctx, "assetdir", *assetdir)
devServerURL := os.Getenv("devserverurl")
if devServerURL == "" {
devServerURLFlag = flag.String("devserverurl", "", "URL of development server")
}
if loglevel != nil && *loglevel != "" {
level, err := pkglogger.StringToLogLevel(*loglevel)
loglevel := os.Getenv("loglevel")
if loglevel == "" {
loglevelFlag = flag.String("loglevel", "debug", "Loglevel to use - Trace, Debug, Info, Warning, Error")
}
// If we weren't given the assetdir in the environment variables
if assetdir == "" {
flag.Parse()
if assetdirFlag != nil {
assetdir = *assetdirFlag
}
if devServerURLFlag != nil {
devServerURL = *devServerURLFlag
}
if loglevelFlag != nil {
loglevel = *loglevelFlag
}
}
if devServerURL != "" {
ctx = context.WithValue(ctx, "devserverurl", devServerURL)
}
if assetdir != "" {
ctx = context.WithValue(ctx, "assetdir", assetdir)
}
if loglevel != "" {
level, err := pkglogger.StringToLogLevel(loglevel)
if err != nil {
return nil, err
}
@@ -166,6 +193,13 @@ 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
}

View File

@@ -0,0 +1,15 @@
//go:build linux && !bindings
package appng
import (
"github.com/wailsapp/wails/v2/internal/logger"
"github.com/wailsapp/wails/v2/pkg/options"
)
func PreflightChecks(options *options.App, logger *logger.Logger) error {
_ = options
return nil
}

View File

@@ -5,6 +5,7 @@ package appng
import (
"context"
"github.com/wailsapp/wails/v2/internal/binding"
"github.com/wailsapp/wails/v2/internal/frontend"
"github.com/wailsapp/wails/v2/internal/frontend/desktop"
@@ -12,7 +13,6 @@ import (
"github.com/wailsapp/wails/v2/internal/frontend/runtime"
"github.com/wailsapp/wails/v2/internal/logger"
"github.com/wailsapp/wails/v2/internal/menumanager"
"github.com/wailsapp/wails/v2/internal/signal"
"github.com/wailsapp/wails/v2/pkg/options"
)
@@ -20,7 +20,6 @@ import (
type App struct {
frontend frontend.Frontend
logger *logger.Logger
signal *signal.Manager
options *options.App
menuManager *menumanager.Manager
@@ -82,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,

View File

@@ -1,4 +1,6 @@
//go:build !desktop
// +build !desktop
package assetdb
import (

View File

@@ -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)
}

View File

@@ -78,10 +78,16 @@ func (b *Bindings) getMethods(value interface{}) ([]*BoundMethod, error) {
input := methodType.In(inputIndex)
thisParam := newParameter("", input)
thisInput := input
if thisInput.Kind() == reflect.Slice {
thisInput = thisInput.Elem()
}
// Process struct pointer params
if input.Kind() == reflect.Ptr {
if input.Elem().Kind() == reflect.Struct {
typ := input.Elem()
if thisInput.Kind() == reflect.Ptr {
if thisInput.Elem().Kind() == reflect.Struct {
typ := thisInput.Elem()
a := reflect.New(typ)
s := reflect.Indirect(a).Interface()
b.converter.Add(s)
@@ -89,8 +95,8 @@ func (b *Bindings) getMethods(value interface{}) ([]*BoundMethod, error) {
}
// Process struct params
if input.Kind() == reflect.Struct {
a := reflect.New(input)
if thisInput.Kind() == reflect.Struct {
a := reflect.New(thisInput)
s := reflect.Indirect(a).Interface()
b.converter.Add(s)
}
@@ -108,6 +114,30 @@ func (b *Bindings) getMethods(value interface{}) ([]*BoundMethod, error) {
for outputIndex := 0; outputIndex < outputParamCount; outputIndex++ {
output := methodType.Out(outputIndex)
thisParam := newParameter("", output)
thisOutput := output
if thisOutput.Kind() == reflect.Slice {
thisOutput = thisOutput.Elem()
}
// Process struct pointer params
if thisOutput.Kind() == reflect.Ptr {
if thisOutput.Elem().Kind() == reflect.Struct {
typ := thisOutput.Elem()
a := reflect.New(typ)
s := reflect.Indirect(a).Interface()
b.converter.Add(s)
}
}
// Process struct params
if thisOutput.Kind() == reflect.Struct {
a := reflect.New(thisOutput)
s := reflect.Indirect(a).Interface()
b.converter.Add(s)
}
outputs = append(outputs, thisParam)
}
boundMethod.Outputs = outputs

View File

@@ -1,3 +1,4 @@
//go:build !windows
// +build !windows
package ffenestri

View File

@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package ffenestri

View File

@@ -1,3 +1,4 @@
//go:build wv2runtime.browser
// +build wv2runtime.browser
package wv2runtime

View File

@@ -1,6 +1,5 @@
// +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

View File

@@ -1,3 +1,4 @@
//go:build wv2runtime.embed
// +build wv2runtime.embed
package wv2runtime

View File

@@ -1,3 +1,4 @@
//go:build wv2runtime.error
// +build wv2runtime.error
package wv2runtime

View File

@@ -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"
)
/* ---------------------------------------------------------------------------------

View File

@@ -1,4 +1,5 @@
//+build windows,debug
//go:build windows && debug
// +build windows,debug
package ffenestri

View File

@@ -1,3 +1,4 @@
//go:build windows && !debug
// +build windows,!debug
package ffenestri

View File

@@ -1,4 +1,5 @@
//+build windows
//go:build windows
// +build windows
package ffenestri

View File

@@ -1,4 +1,5 @@
//+build windows
//go:build windows
// +build windows
package ffenestri

View File

@@ -1,4 +1,5 @@
//+build windows
//go:build windows
// +build windows
package ffenestri

View File

@@ -1,4 +1,5 @@
//+build windows
//go:build windows
// +build windows
package ffenestri

View 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 || (len(expectedHost) > 0 && url.Host != expectedHost) {
return "", false, nil
}
filePath := url.Path
if filePath == "" {
filePath = "/"
}
return filePath, true, nil
}

View File

@@ -9,11 +9,14 @@
#define AppDelegate_h
#import <Cocoa/Cocoa.h>
#import "WailsContext.h"
@interface AppDelegate : NSResponder <NSTouchBarProvider>
@property bool alwaysOnTop;
@property (retain) NSWindow* mainWindow;
@property bool startHidden;
@property bool startFullscreen;
@property (retain) WailsWindow* mainWindow;
@end

View File

@@ -16,37 +16,27 @@
}
- (void)applicationWillFinishLaunching:(NSNotification *)aNotification {
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[self.mainWindow makeKeyAndOrderFront:self];
if (self.alwaysOnTop) {
[self.mainWindow setLevel:NSStatusWindowLevel];
}
if ( !self.startHidden ) {
[self.mainWindow makeKeyAndOrderFront:self];
}
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[NSApp activateIgnoringOtherApps:YES];
if ( self.startFullscreen ) {
NSWindowCollectionBehavior behaviour = [self.mainWindow collectionBehavior];
behaviour |= NSWindowCollectionBehaviorFullScreenPrimary;
[self.mainWindow setCollectionBehavior:behaviour];
[self.mainWindow toggleFullScreen:nil];
}
}
- (void)dealloc {
[super dealloc];
}
//
//- (void) CreateMenu {
// [NSApplication sharedApplication];
// menubar = [[NSMenu new] autorelease];
// id appMenuItem = [[NSMenuItem new] autorelease];
// [menubar addItem:appMenuItem];
// [NSApp setMainMenu:menubar];
// id appMenu = [[NSMenu new] autorelease];
// id appName = [[NSProcessInfo processInfo] processName];
// id quitTitle = [@"Quit " stringByAppendingString:appName];
// id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:quitTitle
// action:@selector(terminate:) keyEquivalent:@"q"]
// autorelease];
// [appMenu addItem:quitMenuItem];
// [appMenuItem setSubmenu:appMenu];
//}
//
//- (void) dealloc {
// [super dealloc];
// window = nil;
// menubar = nil;
//}
@synthesize touchBar;

View File

@@ -12,7 +12,12 @@
#import <Cocoa/Cocoa.h>
#import "WailsContext.h"
WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug);
#define WindowStartsNormal 0
#define WindowStartsMaximised 1
#define WindowStartsMinimised 2
#define WindowStartsFullscreen 3
WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight);
void Run(void*);
void SetTitle(void* ctx, const char *title);
@@ -36,9 +41,26 @@ void Quit(void*);
const char* GetSize(void *ctx);
const char* GetPos(void *ctx);
void ProcessURLResponse(void *inctx, const char *url, const char *contentType, const char *data, int datalength);
void ProcessURLResponse(void *inctx, const char *url, int statusCode, const char *contentType, void* data, int datalength);
void MessageDialog(void *inctx, const char* dialogType, const char* title, const char* message, const char* button1, const char* button2, const char* button3, const char* button4, const char* defaultButton, const char* cancelButton);
/* Dialogs */
void MessageDialog(void *inctx, const char* dialogType, const char* title, const char* message, const char* button1, const char* button2, const char* button3, const char* button4, const char* defaultButton, const char* cancelButton, void* iconData, int iconDataLength);
void OpenFileDialog(void *inctx, const char* title, const char* defaultFilename, const char* defaultDirectory, int allowDirectories, int allowFiles, int canCreateDirectories, int treatPackagesAsDirectories, int resolveAliases, int showHiddenFiles, int allowMultipleSelection, const char* filters);
void SaveFileDialog(void *inctx, const char* title, const char* defaultFilename, const char* defaultDirectory, int canCreateDirectories, int treatPackagesAsDirectories, int showHiddenFiles, const char* filters);
/* Application Menu */
void* NewMenu(const char* name);
void AppendSubmenu(void* parent, void* child);
void AppendRole(void *inctx, void *inMenu, int role);
void SetAsApplicationMenu(void *inctx, void *inMenu);
void UpdateApplicationMenu(void *inctx);
void SetAbout(void *inctx, const char* title, const char* description, void* imagedata, int datalen);
void* AppendMenuItem(void* inctx, void* nsmenu, const char* label, const char* shortcutKey, int modifiers, int disabled, int checked, int menuItemID);
void AppendSeparator(void* inMenu);
void UpdateMenuItem(void* nsmenuitem, int checked);
NSString* safeInit(const char* input);
#endif /* Application_h */

View File

@@ -9,43 +9,72 @@
#import "WailsContext.h"
#import "Application.h"
#import "AppDelegate.h"
#import "WailsMenu.h"
#import "WailsMenuItem.h"
WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug) {
WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight) {
[NSApplication sharedApplication];
WailsContext *result = [WailsContext new];
result.debug = debug;
[result CreateWindow:width :height :frameless :resizable :fullscreen :fullSizeContent :hideTitleBar :titlebarAppearsTransparent :hideTitle :useToolbar :hideToolbarSeparator :webviewIsTransparent :hideWindowOnClose :appearance :windowIsTranslucent];
[result SetTitle:title];
if ( windowStartState == WindowStartsFullscreen ) {
fullscreen = 1;
}
[result CreateWindow:width :height :frameless :resizable :fullscreen :fullSizeContent :hideTitleBar :titlebarAppearsTransparent :hideTitle :useToolbar :hideToolbarSeparator :webviewIsTransparent :hideWindowOnClose :safeInit(appearance) :windowIsTranslucent :minWidth :minHeight :maxWidth :maxHeight];
[result SetTitle:safeInit(title)];
[result Center];
switch( windowStartState ) {
case WindowStartsMaximised:
[result.mainWindow zoom:nil];
break;
case WindowStartsMinimised:
//TODO: Can you start a mac app minimised?
break;
}
if ( startsHidden == 1 ) {
result.startHidden = true;
}
if ( fullscreen == 1 ) {
result.startFullscreen = true;
}
result.alwaysOnTop = alwaysOnTop;
result.hideOnClose = hideWindowOnClose;
return result;
}
void ProcessURLResponse(void *inctx, const char *url, const char *contentType, const char* 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 = [[NSString alloc] initWithUTF8String:url];
NSString *nsContentType = [[NSString alloc] initWithUTF8String:contentType];
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) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
NSString *nsscript = safeInit(script);
ON_MAIN_THREAD(
[ctx ExecJS:script];
[ctx ExecJS:nsscript];
);
}
void SetTitle(void* inctx, const char *title) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
NSString *_title = safeInit(title);
ON_MAIN_THREAD(
[ctx SetTitle:title];
[ctx SetTitle:_title];
);
}
@@ -81,7 +110,7 @@ void SetMaxSize(void* inctx, int width, int height) {
void SetPosition(void* inctx, int x, int y) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
ON_MAIN_THREAD(
[ctx SetSize:x :y];
[ctx SetPosition:x :y];
);
}
@@ -173,42 +202,138 @@ void Show(void *inctx) {
);
}
void MessageDialog(void *inctx, const char* dialogType, const char* title, const char* message, const char* button1, const char* button2, const char* button3, const char* button4, const char* defaultButton, const char* cancelButton) {
NSString* safeInit(const char* input) {
NSString *result = nil;
if (input != nil) {
result = [NSString stringWithUTF8String:input];
}
return result;
}
void MessageDialog(void *inctx, const char* dialogType, const char* title, const char* message, const char* button1, const char* button2, const char* button3, const char* button4, const char* defaultButton, const char* cancelButton, void* iconData, int iconDataLength) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
NSString *_dialogType = safeInit(dialogType);
NSString *_title = safeInit(title);
NSString *_message = safeInit(message);
NSString *_button1 = safeInit(button1);
NSString *_button2 = safeInit(button2);
NSString *_button3 = safeInit(button3);
NSString *_button4 = safeInit(button4);
NSString *_defaultButton = safeInit(defaultButton);
NSString *_cancelButton = safeInit(cancelButton);
ON_MAIN_THREAD(
[ctx MessageDialog:dialogType :title :message :button1 :button2 :button3 :button4 :defaultButton :cancelButton];
[ctx MessageDialog:_dialogType :_title :_message :_button1 :_button2 :_button3 :_button4 :_defaultButton :_cancelButton :iconData :iconDataLength];
)
}
void OpenFileDialog(void *inctx, const char* title, const char* defaultFilename, const char* defaultDirectory, int allowDirectories, int allowFiles, int canCreateDirectories, int treatPackagesAsDirectories, int resolveAliases, int showHiddenFiles, int allowMultipleSelection, const char* filters) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
NSString *_title = safeInit(title);
NSString *_defaultFilename = safeInit(defaultFilename);
NSString *_defaultDirectory = safeInit(defaultDirectory);
NSString *_filters = safeInit(filters);
ON_MAIN_THREAD(
[ctx OpenFileDialog:title :defaultFilename :defaultDirectory :allowDirectories :allowFiles :canCreateDirectories :treatPackagesAsDirectories :resolveAliases :showHiddenFiles :allowMultipleSelection :filters];
[ctx OpenFileDialog:_title :_defaultFilename :_defaultDirectory :allowDirectories :allowFiles :canCreateDirectories :treatPackagesAsDirectories :resolveAliases :showHiddenFiles :allowMultipleSelection :_filters];
)
}
void SaveFileDialog(void *inctx, const char* title, const char* defaultFilename, const char* defaultDirectory, int canCreateDirectories, int treatPackagesAsDirectories, int showHiddenFiles, const char* filters) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
NSString *_title = safeInit(title);
NSString *_defaultFilename = safeInit(defaultFilename);
NSString *_defaultDirectory = safeInit(defaultDirectory);
NSString *_filters = safeInit(filters);
ON_MAIN_THREAD(
[ctx SaveFileDialog:title :defaultFilename :defaultDirectory :canCreateDirectories :treatPackagesAsDirectories :showHiddenFiles :filters];
[ctx SaveFileDialog:_title :_defaultFilename :_defaultDirectory :canCreateDirectories :treatPackagesAsDirectories :showHiddenFiles :_filters];
)
}
void AppendRole(void *inctx, void *inMenu, int role) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
WailsMenu *menu = (__bridge WailsMenu*) inMenu;
[menu appendRole :ctx :role];
}
void* NewMenu(const char *name) {
NSString *title = @"";
if (name != nil) {
title = [NSString stringWithUTF8String:name];
}
WailsMenu *result = [[WailsMenu new] initWithNSTitle:title];
return result;
}
void AppendSubmenu(void* inparent, void* inchild) {
WailsMenu *parent = (__bridge WailsMenu*) inparent;
WailsMenu *child = (__bridge WailsMenu*) inchild;
[parent appendSubmenu:child];
}
void SetAsApplicationMenu(void *inctx, void *inMenu) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
WailsMenu *menu = (__bridge WailsMenu*) inMenu;
ctx.applicationMenu = menu;
}
void UpdateApplicationMenu(void *inctx) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
ON_MAIN_THREAD(
NSApplication *app = [NSApplication sharedApplication];
[app setMainMenu:ctx.applicationMenu];
)
}
void SetAbout(void *inctx, const char* title, const char* description, void* imagedata, int datalen) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
NSString *_title = safeInit(title);
NSString *_description = safeInit(description);
[ctx SetAbout :_title :_description :imagedata :datalen];
}
void* AppendMenuItem(void* inctx, void* inMenu, const char* label, const char* shortcutKey, int modifiers, int disabled, int checked, int menuItemID) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
WailsMenu *menu = (__bridge WailsMenu*) inMenu;
NSString *_label = safeInit(label);
NSString *_shortcutKey = safeInit(shortcutKey);
return [menu AppendMenuItem:ctx :_label :_shortcutKey :modifiers :disabled :checked :menuItemID];
}
void UpdateMenuItem(void* nsmenuitem, int checked) {
ON_MAIN_THREAD(
WailsMenuItem *menuItem = (__bridge WailsMenuItem*) nsmenuitem;
[menuItem setState:(checked == 1?NSControlStateValueOn:NSControlStateValueOff)];
)
}
void AppendSeparator(void* inMenu) {
WailsMenu *menu = (__bridge WailsMenu*) inMenu;
[menu AppendSeparator];
}
void Run(void *inctx) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
[NSApplication sharedApplication];
NSApplication *app = [NSApplication sharedApplication];
AppDelegate* delegate = [AppDelegate new];
[NSApp setDelegate:(id)delegate];
[app setDelegate:(id)delegate];
ctx.appdelegate = delegate;
delegate.mainWindow = ctx.mainWindow;
delegate.alwaysOnTop = ctx.alwaysOnTop;
delegate.startHidden = ctx.startHidden;
delegate.startFullscreen = ctx.startFullscreen;
[ctx loadRequest:@"wails://wails/"];
[NSApp run];
[app setMainMenu:ctx.applicationMenu];
[app run];
[ctx release];
NSLog(@"Here");
}

View File

@@ -0,0 +1,16 @@
//
// Role.h
// test
//
// Created by Lea Anthony on 24/10/21.
//
#ifndef Role_h
#define Role_h
typedef int Role;
static const Role AppMenu = 1;
static const Role EditMenu = 2;
#endif /* Role_h */

View File

@@ -11,7 +11,7 @@
#import <Cocoa/Cocoa.h>
@interface WailsAlert : NSAlert
- (void)addButton:(const char*)text :(const char*)defaultButton :(const char*)cancelButton;
- (void)addButton:(NSString*)text :(NSString*)defaultButton :(NSString*)cancelButton;
@end

View File

@@ -11,14 +11,14 @@
@implementation WailsAlert
- (void)addButton:(const char*)text :(const char*)defaultButton :(const char*)cancelButton {
- (void)addButton:(NSString*)text :(NSString*)defaultButton :(NSString*)cancelButton {
if( text == nil ) {
return;
}
NSButton *button = [self addButtonWithTitle:[NSString stringWithUTF8String:text]];
if( defaultButton != nil && strcmp(text, defaultButton) == 0) {
NSButton *button = [self addButtonWithTitle:text];
if( defaultButton != nil && [text isEqualToString:defaultButton]) {
[button setKeyEquivalent:@"\r"];
} else if( cancelButton != nil && strcmp(text, cancelButton) == 0) {
} else if( cancelButton != nil && [text isEqualToString:cancelButton]) {
[button setKeyEquivalent:@"\033"];
} else {
[button setKeyEquivalent:@""];

View File

@@ -11,13 +11,24 @@
#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
#if __has_include(<UniformTypeIdentifiers/UTType.h>)
#import <UniformTypeIdentifiers/UTType.h>
#endif
#define ON_MAIN_THREAD(str) dispatch_async(dispatch_get_main_queue(), ^{ str; });
#define unicode(input) [NSString stringWithFormat:@"%C", input]
@interface WailsWindow : NSWindow
- (BOOL)canBecomeKeyWindow;
@property NSSize userMinSize;
@property NSSize userMaxSize;
- (BOOL) canBecomeKeyWindow;
- (void) applyWindowConstraints;
- (void) disableWindowConstraints;
@end
@interface WailsContext : NSObject <WKURLSchemeHandler,WKScriptMessageHandler>
@interface WailsContext : NSObject <WKURLSchemeHandler,WKScriptMessageHandler,WKNavigationDelegate>
@property (retain) WailsWindow* mainWindow;
@property (retain) WKWebView* webview;
@@ -25,27 +36,30 @@
@property bool hideOnClose;
@property bool shuttingDown;
@property NSSize maxSize;
@property NSSize minSize;
@property bool startHidden;
@property bool startFullscreen;
@property (retain) NSEvent* mouseEvent;
@property bool alwaysOnTop;
@property bool maximised;
@property bool debug;
@property (retain) WKUserContentController* userContentController;
@property (retain) NSMutableDictionary *urlRequests;
- (void) CreateWindow:(int)width :(int)height :(bool)frameless :(bool)resizable :(bool)fullscreen :(bool)fullSizeContent :(bool)hideTitleBar :(bool)titlebarAppearsTransparent :(bool)hideTitle :(bool)useToolbar :(bool)hideToolbarSeparator :(bool)webviewIsTransparent :(bool)hideWindowOnClose :(const char *)appearance :(bool)windowIsTranslucent;
@property (retain) NSMenu* applicationMenu;
@property (retain) NSImage* aboutImage;
@property (retain) NSString* aboutTitle;
@property (retain) NSString* aboutDescription;
- (void) CreateWindow:(int)width :(int)height :(bool)frameless :(bool)resizable :(bool)fullscreen :(bool)fullSizeContent :(bool)hideTitleBar :(bool)titlebarAppearsTransparent :(bool)hideTitle :(bool)useToolbar :(bool)hideToolbarSeparator :(bool)webviewIsTransparent :(bool)hideWindowOnClose :(NSString *)appearance :(bool)windowIsTranslucent :(int)minWidth :(int)minHeight :(int)maxWidth :(int)maxHeight;
- (void) SetSize:(int)width :(int)height;
- (void) SetPosition:(int)x :(int) y;
- (void) SetMinSize:(int)minWidth :(int)minHeight;
- (void) SetMaxSize:(int)maxWidth :(int)maxHeight;
- (void) SetTitle:(const char*)title;
- (void) SetTitle:(NSString*)title;
- (void) Center;
- (void) Fullscreen;
- (void) UnFullscreen;
@@ -58,16 +72,20 @@
- (void) ShowMouse;
- (void) Hide;
- (void) Show;
- (void) Quit;
-(void) MessageDialog :(const char*)dialogType :(const char*)title :(const char*)message :(const char*)button1 :(const char*)button2 :(const char*)button3 :(const char*)button4 :(const char*)defaultButton :(const char*)cancelButton;
-(void) OpenFileDialog :(const char*)title :(const char*)defaultFilename :(const char*)defaultDirectory :(bool)allowDirectories :(bool)allowFiles :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)resolveAliases :(bool)showHiddenFiles :(bool)allowMultipleSelection :(const char*)filters;
-(void) SaveFileDialog :(const char*)title :(const char*)defaultFilename :(const char*)defaultDirectory :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)showHiddenFiles :(const char*)filters;
-(void) MessageDialog :(NSString*)dialogType :(NSString*)title :(NSString*)message :(NSString*)button1 :(NSString*)button2 :(NSString*)button3 :(NSString*)button4 :(NSString*)defaultButton :(NSString*)cancelButton :(void*)iconData :(int)iconDataLength;
- (void) OpenFileDialog :(NSString*)title :(NSString*)defaultFilename :(NSString*)defaultDirectory :(bool)allowDirectories :(bool)allowFiles :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)resolveAliases :(bool)showHiddenFiles :(bool)allowMultipleSelection :(NSString*)filters;
- (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) ExecJS:(const char*)script;
- (void) processURLResponse:(NSString *)url :(int)statusCode :(NSString *)contentType :(NSData*)data;
- (void) ExecJS:(NSString*)script;
- (NSScreen*) getCurrentScreen;
- (void) SetAbout :(NSString*)title :(NSString*)description :(void*)imagedata :(int)datalen;
- (void) dealloc;
@end

View File

@@ -9,8 +9,10 @@
#import <WebKit/WebKit.h>
#import "WailsContext.h"
#import "WailsAlert.h"
#import "WailsMenu.h"
#import "WindowDelegate.h"
#import "message.h"
#import "Role.h"
@implementation WailsWindow
@@ -19,6 +21,16 @@
return YES;
}
- (void) applyWindowConstraints {
[self setMinSize:self.userMinSize];
[self setMaxSize:self.userMaxSize];
}
- (void) disableWindowConstraints {
[self setMinSize:NSMakeSize(0, 0)];
[self setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
}
@end
@implementation WailsContext
@@ -40,9 +52,9 @@
NSScreen* screen = [self getCurrentScreen];
NSRect windowFrame = [self.mainWindow frame];
NSRect screenFrame = [screen visibleFrame];
windowFrame.origin.x += screenFrame.origin.x + (float)x;
windowFrame.origin.y += (screenFrame.origin.y + screenFrame.size.height) - windowFrame.size.height - (float)y;
NSRect screenFrame = [screen frame];
windowFrame.origin.x = screenFrame.origin.x + (float)x;
windowFrame.origin.y = (screenFrame.origin.y + screenFrame.size.height) - windowFrame.size.height - (float)y;
[self.mainWindow setFrame:windowFrame display:TRUE animate:FALSE];
}
@@ -52,11 +64,8 @@
if (self.shuttingDown) return;
NSSize size = { minWidth, minHeight };
self.minSize = size;
self.mainWindow.userMinSize = size;
[self.mainWindow setMinSize:size];
[self adjustWindowSize];
}
@@ -70,10 +79,8 @@
size.width = maxWidth > 0 ? maxWidth : FLT_MAX;
size.height = maxHeight > 0 ? maxHeight : FLT_MAX;
self.maxSize = size;
[self.mainWindow setMinSize:size];
self.mainWindow.userMaxSize = size;
[self.mainWindow setMaxSize:size];
[self adjustWindowSize];
}
@@ -84,22 +91,23 @@
NSRect currentFrame = [self.mainWindow frame];
if ( currentFrame.size.width > self.maxSize.width ) currentFrame.size.width = self.maxSize.width;
if ( currentFrame.size.width < self.minSize.width ) currentFrame.size.width = self.minSize.width;
if ( currentFrame.size.height > self.maxSize.height ) currentFrame.size.height = self.maxSize.height;
if ( currentFrame.size.height < self.minSize.height ) currentFrame.size.height = self.minSize.height;
[self.mainWindow setFrame:currentFrame display:TRUE animate:FALSE];
if ( currentFrame.size.width > self.mainWindow.userMaxSize.width ) currentFrame.size.width = self.mainWindow.userMaxSize.width;
if ( currentFrame.size.width < self.mainWindow.userMinSize.width ) currentFrame.size.width = self.mainWindow.userMinSize.width;
if ( currentFrame.size.height > self.mainWindow.userMaxSize.height ) currentFrame.size.height = self.mainWindow.userMaxSize.height;
if ( currentFrame.size.height < self.mainWindow.userMinSize.height ) currentFrame.size.height = self.mainWindow.userMinSize.height;
[self.mainWindow setFrame:currentFrame display:YES animate:FALSE];
}
- (void) dealloc {
[super dealloc];
[self.appdelegate release];
[self.mainWindow release];
[self.mouseEvent release];
[self.userContentController release];
[self.urlRequests release];
[self.applicationMenu release];
[super dealloc];
}
- (NSScreen*) getCurrentScreen {
@@ -110,55 +118,58 @@
return screen;
}
- (void) SetTitle:(const char *)title {
NSString *_title = [NSString stringWithUTF8String:title];
[self.mainWindow setTitle:_title];
- (void) SetTitle:(NSString*)title {
[self.mainWindow setTitle:title];
}
- (void) Center {
[self.mainWindow center];
[self.mainWindow center];
}
- (void) CreateWindow:(int)width :(int)height :(bool)frameless :(bool)resizable :(bool)fullscreen :(bool)fullSizeContent :(bool)hideTitleBar :(bool)titlebarAppearsTransparent :(bool)hideTitle :(bool)useToolbar :(bool)hideToolbarSeparator :(bool)webviewIsTransparent :(bool)hideWindowOnClose :(const char *)appearance :(bool)windowIsTranslucent {
- (BOOL) isFullscreen {
NSWindowStyleMask masks = [self.mainWindow styleMask];
if ( masks & NSWindowStyleMaskFullScreen ) {
return YES;
}
return NO;
}
- (void) CreateWindow:(int)width :(int)height :(bool)frameless :(bool)resizable :(bool)fullscreen :(bool)fullSizeContent :(bool)hideTitleBar :(bool)titlebarAppearsTransparent :(bool)hideTitle :(bool)useToolbar :(bool)hideToolbarSeparator :(bool)webviewIsTransparent :(bool)hideWindowOnClose :(NSString*)appearance :(bool)windowIsTranslucent :(int)minWidth :(int)minHeight :(int)maxWidth :(int)maxHeight {
self.urlRequests = [NSMutableDictionary new];
NSWindowStyleMask styleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
NSWindowStyleMask styleMask = 0;
if (frameless) {
styleMask = NSWindowStyleMaskBorderless;
} else {
if (resizable) {
styleMask |= NSWindowStyleMaskResizable;
if( !frameless ) {
if (!hideTitleBar) {
styleMask |= NSWindowStyleMaskTitled;
}
styleMask |= NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
}
if (fullscreen) {
styleMask |= NSWindowStyleMaskFullScreen;
}
if( fullSizeContent || frameless || titlebarAppearsTransparent ) {
styleMask |= NSWindowStyleMaskFullSizeContentView;
}
self.mainWindow = [[[WailsWindow alloc] initWithContentRect:NSMakeRect(0, 0, width, height)
styleMask:styleMask backing:NSBackingStoreBuffered defer:NO]
autorelease];
if (frameless) {
return;
if (resizable) {
styleMask |= NSWindowStyleMaskResizable;
}
if (useToolbar) {
NSLog(@"Using Toolbar");
self.mainWindow = [[WailsWindow alloc] initWithContentRect:NSMakeRect(0, 0, width, height)
styleMask:styleMask backing:NSBackingStoreBuffered defer:NO];
if (!frameless && useToolbar) {
id toolbar = [[NSToolbar alloc] initWithIdentifier:@"wails.toolbar"];
[toolbar autorelease];
[toolbar setShowsBaselineSeparator:!hideToolbarSeparator];
[self.mainWindow setToolbar:toolbar];
}
[self.mainWindow setTitleVisibility:hideTitle];
[self.mainWindow setTitlebarAppearsTransparent:titlebarAppearsTransparent];
[self.mainWindow canBecomeKeyWindow];
// [self.mainWindow canBecomeKeyWindow];
id contentView = [self.mainWindow contentView];
if (windowIsTranslucent) {
@@ -172,20 +183,29 @@
}
if (appearance != nil) {
NSString *name = [NSString stringWithUTF8String:appearance];
NSAppearance *nsAppearance = [NSAppearance appearanceNamed:name];
NSAppearance *nsAppearance = [NSAppearance appearanceNamed:appearance];
[self.mainWindow setAppearance:nsAppearance];
}
// Set up min/max
NSSize maxSize = { FLT_MAX, FLT_MAX };
self.maxSize = maxSize;
NSSize minSize = { 0, 0 };
self.minSize = minSize;
[self adjustWindowSize];
NSSize minSize = { minWidth, minHeight };
NSSize maxSize = { maxWidth, maxHeight };
if (maxSize.width == 0) {
maxSize.width = FLT_MAX;
}
if (maxSize.height == 0) {
maxSize.height = FLT_MAX;
}
self.mainWindow.userMaxSize = maxSize;
self.mainWindow.userMinSize = minSize;
if( !fullscreen ) {
[self.mainWindow applyWindowConstraints];
}
WindowDelegate *windowDelegate = [WindowDelegate new];
windowDelegate.hideOnClose = hideWindowOnClose;
windowDelegate.ctx = self;
[self.mainWindow setDelegate:windowDelegate];
// Webview stuff here!
@@ -193,7 +213,7 @@
config.suppressesIncrementalRendering = true;
[config setURLSchemeHandler:self forURLScheme:@"wails"];
[config.preferences setValue:[NSNumber numberWithBool:true] forKey:@"developerExtrasEnabled"];
// [config.preferences setValue:[NSNumber numberWithBool:true] forKey:@"developerExtrasEnabled"];
WKUserContentController* userContentController = [WKUserContentController new];
[userContentController addScriptMessageHandler:self name:@"external"];
@@ -223,6 +243,8 @@
[self.webview setValue:[NSNumber numberWithBool:!webviewIsTransparent] forKey:@"drawsBackground"];
}
[self.webview setNavigationDelegate:self];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:FALSE forKey:@"NSAutomaticQuoteSubstitutionEnabled"];
@@ -244,6 +266,30 @@
return event;
}];
self.applicationMenu = [NSMenu new];
}
- (NSMenuItem*) newMenuItem :(NSString*)title :(SEL)selector :(NSString*)key :(NSEventModifierFlags)flags {
NSMenuItem *result = [[[NSMenuItem alloc] initWithTitle:title action:selector keyEquivalent:key] autorelease];
if( flags != 0 ) {
[result setKeyEquivalentModifierMask:flags];
}
return result;
}
- (NSMenuItem*) newMenuItem :(NSString*)title :(SEL)selector :(NSString*)key {
return [self newMenuItem :title :selector :key :0];
}
- (NSMenu*) newMenu :(NSString*)title {
WailsMenu *result = [[WailsMenu new] initWithTitle:title];
[result setAutoenablesItems:NO];
return result;
}
- (void) Quit {
processMessage("Q");
}
- (void) loadRequest :(NSString*)url {
@@ -253,10 +299,10 @@
}
- (void) SetRGBA:(int)r :(int)g :(int)b :(int)a {
float red = r/255;
float green = g/255;
float blue = b/255;
float alpha = a/255;
float red = r/255.0;
float green = g/255.0;
float blue = b/255.0;
float alpha = a/255.0;
id colour = [NSColor colorWithCalibratedRed:red green:green blue:blue alpha:alpha ];
@@ -276,9 +322,15 @@
return (mask & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen;
}
- (bool) isMaximised {
long mask = [self.mainWindow styleMask];
return (mask & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen;
}
// Fullscreen sets the main window to be fullscreen
- (void) Fullscreen {
if( ! [self isFullScreen] ) {
[self.mainWindow disableWindowConstraints];
[self.mainWindow toggleFullScreen:nil];
}
}
@@ -286,6 +338,7 @@
// UnFullscreen resets the main window after a fullscreen
- (void) UnFullscreen {
if( [self isFullScreen] ) {
[self.mainWindow applyWindowConstraints];
[self.mainWindow toggleFullScreen:nil];
}
}
@@ -308,34 +361,35 @@
}
- (void) Maximise {
if (! self.maximised) {
if (![self.mainWindow isZoomed]) {
[self.mainWindow zoom:nil];
}
}
- (void) UnMaximise {
if (self.maximised) {
if ([self.mainWindow isZoomed]) {
[self.mainWindow zoom:nil];
}
}
- (void) ExecJS:(const char*)script {
NSString *nsscript = [NSString stringWithUTF8String:script];
[self.webview evaluateJavaScript:nsscript completionHandler:nil];
- (void) ExecJS:(NSString*)script {
[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];
NSHTTPURLResponse *response = [NSHTTPURLResponse new];
NSMutableDictionary *headerFields = [NSMutableDictionary new];
headerFields[@"content-type"] = contentType;
[response 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];
[self.urlRequests removeObjectForKey:url];
[response release];
[headerFields release];
}
- (void)webView:(nonnull WKWebView *)webView startURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
@@ -348,20 +402,22 @@
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
processMessage("DomReady");
}
- (void)userContentController:(nonnull WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message {
NSString *m = message.body;
// Check for drag
if ( [m isEqualToString:@"drag"] ) {
if( ! [self isFullScreen] ) {
if( self.mouseEvent != nil ) {
[self HideMouse];
ON_MAIN_THREAD(
[self.mainWindow performWindowDragWithEvent:self.mouseEvent];
);
}
if( [self isFullScreen] ) {
return;
}
if( self.mouseEvent != nil ) {
[self.mainWindow performWindowDragWithEvent:self.mouseEvent];
}
return;
}
const char *_m = [m UTF8String];
@@ -371,25 +427,25 @@
/***** Dialogs ******/
-(void) MessageDialog :(const char*)dialogType :(const char*)title :(const char*)message :(const char*)button1 :(const char*)button2 :(const char*)button3 :(const char*)button4 :(const char*)defaultButton :(const char*)cancelButton {
-(void) MessageDialog :(NSString*)dialogType :(NSString*)title :(NSString*)message :(NSString*)button1 :(NSString*)button2 :(NSString*)button3 :(NSString*)button4 :(NSString*)defaultButton :(NSString*)cancelButton :(void*)iconData :(int)iconDataLength {
WailsAlert *alert = [WailsAlert new];
int style = NSAlertStyleInformational;
if (dialogType != nil ) {
if( strcmp(dialogType, "warning") == 0 ) {
if( [dialogType isEqualToString:@"warning"] ) {
style = NSAlertStyleWarning;
}
if( strcmp(dialogType, "error") == 0) {
if( [dialogType isEqualToString:@"error"] ) {
style = NSAlertStyleCritical;
}
}
[alert setAlertStyle:style];
if( strlen(title) > 0 ) {
[alert setMessageText:[NSString stringWithUTF8String:title]];
if( title != nil ) {
[alert setMessageText:title];
}
if( strlen(message) > 0 ) {
[alert setInformativeText:[NSString stringWithUTF8String:message]];
if( message != nil ) {
[alert setInformativeText:message];
}
[alert addButton:button1 :defaultButton :cancelButton];
@@ -397,9 +453,19 @@
[alert addButton:button3 :defaultButton :cancelButton];
[alert addButton:button4 :defaultButton :cancelButton];
NSImage *icon = nil;
if (iconData != nil) {
NSData *imageData = [NSData dataWithBytes:iconData length:iconDataLength];
icon = [[NSImage alloc] initWithData:imageData];
}
if( icon != nil) {
[alert setIcon:icon];
}
[alert.window setLevel:NSFloatingWindowLevel];
long response = [alert runModal];
int result;
if( response == NSAlertFirstButtonReturn ) {
result = 0;
}
@@ -414,30 +480,39 @@
processMessageDialogResponse(result);
}
-(void) OpenFileDialog :(const char*)title :(const char*)defaultFilename :(const char*)defaultDirectory :(bool)allowDirectories :(bool)allowFiles :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)resolveAliases :(bool)showHiddenFiles :(bool)allowMultipleSelection :(const char*)filters {
-(void) OpenFileDialog :(NSString*)title :(NSString*)defaultFilename :(NSString*)defaultDirectory :(bool)allowDirectories :(bool)allowFiles :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)resolveAliases :(bool)showHiddenFiles :(bool)allowMultipleSelection :(NSString*)filters {
// Create the dialog
NSOpenPanel *dialog = [NSOpenPanel openPanel];
// Valid but appears to do nothing.... :/
if( strlen(title) > 0 ) {
[dialog setTitle:[NSString stringWithUTF8String:title]];
if( title != nil ) {
[dialog setTitle:title];
}
// Filters - semicolon delimited list of file extensions
if( allowFiles ) {
if( filters != nil && strlen(filters) > 0) {
NSString *filterString = [[NSString stringWithUTF8String:filters] stringByReplacingOccurrencesOfString:@"*." withString:@""];
filterString = [filterString stringByReplacingOccurrencesOfString:@" " withString:@""];
NSArray *filterList = [filterString componentsSeparatedByString:@";"];
[dialog setAllowedFileTypes:filterList];
if( filters != nil && [filters length] > 0) {
filters = [filters stringByReplacingOccurrencesOfString:@"*." withString:@""];
filters = [filters stringByReplacingOccurrencesOfString:@" " withString:@""];
NSArray *filterList = [filters componentsSeparatedByString:@";"];
if (@available(macOS 10.16, *)) {
NSMutableArray *contentTypes = [[NSMutableArray new] autorelease];
for (NSString *filter in filterList) {
UTType *t = [UTType typeWithFilenameExtension:filter];
[contentTypes addObject:t];
}
[dialog setAllowedContentTypes:contentTypes];
} else {
[dialog setAllowedFileTypes:filterList];
}
} else {
[dialog setAllowsOtherFileTypes:true];
}
// Default Filename
if( defaultFilename != NULL && strlen(defaultFilename) > 0 ) {
[dialog setNameFieldStringValue:[NSString stringWithUTF8String:defaultFilename]];
if( defaultFilename != nil ) {
[dialog setNameFieldStringValue:defaultFilename];
}
[dialog setAllowsMultipleSelection: allowMultipleSelection];
@@ -446,8 +521,8 @@
}
// Default Directory
if( defaultDirectory != NULL && strlen(defaultDirectory) > 0 ) {
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:defaultDirectory]];
if( defaultDirectory != nil ) {
NSURL *url = [NSURL fileURLWithPath:defaultDirectory];
[dialog setDirectoryURL:url];
}
@@ -468,42 +543,41 @@
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:arr options:0 error:nil];
NSString *nsjson = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
processOpenFileDialogResponse([nsjson UTF8String]);
[nsjson release];
[arr release];
}];
[dialog runModal];
}
-(void) SaveFileDialog :(const char*)title :(const char*)defaultFilename :(const char*)defaultDirectory :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)showHiddenFiles :(const char*)filters; {
-(void) SaveFileDialog :(NSString*)title :(NSString*)defaultFilename :(NSString*)defaultDirectory :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)showHiddenFiles :(NSString*)filters; {
// Create the dialog
NSSavePanel *dialog = [NSOpenPanel savePanel];
// Valid but appears to do nothing.... :/
if( strlen(title) > 0 ) {
[dialog setTitle:[NSString stringWithUTF8String:title]];
if( title != nil ) {
[dialog setTitle:title];
}
// Filters - semicolon delimited list of file extensions
if( filters != nil && strlen(filters) > 0) {
NSString *filterString = [[NSString stringWithUTF8String:filters] stringByReplacingOccurrencesOfString:@"*." withString:@""];
filterString = [filterString stringByReplacingOccurrencesOfString:@" " withString:@""];
NSArray *filterList = [filterString componentsSeparatedByString:@";"];
if( filters != nil ) {
filters = [filters stringByReplacingOccurrencesOfString:@"*." withString:@""];
filters = [filters stringByReplacingOccurrencesOfString:@" " withString:@""];
NSArray *filterList = [filters componentsSeparatedByString:@";"];
[dialog setAllowedFileTypes:filterList];
} else {
[dialog setAllowsOtherFileTypes:true];
}
// Default Filename
if( defaultFilename != NULL && strlen(defaultFilename) > 0 ) {
[dialog setNameFieldStringValue:[NSString stringWithUTF8String:defaultFilename]];
if( defaultFilename != nil ) {
[dialog setNameFieldStringValue:defaultFilename];
}
// Default Directory
if( defaultDirectory != NULL && strlen(defaultDirectory) > 0 ) {
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:defaultDirectory]];
if( defaultDirectory != nil ) {
NSURL *url = [NSURL fileURLWithPath:defaultDirectory];
[dialog setDirectoryURL:url];
}
@@ -515,13 +589,42 @@
// Setup callback handler
[dialog beginSheetModalForWindow:self.mainWindow completionHandler:^(NSModalResponse returnCode) {
NSURL *url = [dialog URL];
processSaveFileDialogResponse([url.path UTF8String]);
if ( url != nil ) {
processSaveFileDialogResponse([url.path UTF8String]);
return;
}
processSaveFileDialogResponse("");
}];
[dialog runModal];
}
- (void) SetAbout :(NSString*)title :(NSString*)description :(void*)imagedata :(int)datalen {
self.aboutTitle = title;
self.aboutDescription = description;
NSData *imageData = [NSData dataWithBytes:imagedata length:datalen];
self.aboutImage = [[NSImage alloc] initWithData:imageData];
}
-(void) About {
WailsAlert *alert = [WailsAlert new];
[alert setAlertStyle:NSAlertStyleInformational];
if( self.aboutTitle != nil ) {
[alert setMessageText:self.aboutTitle];
}
if( self.aboutDescription != nil ) {
[alert setInformativeText:self.aboutDescription];
}
[alert.window setLevel:NSFloatingWindowLevel];
if ( self.aboutImage != nil) {
[alert setIcon:self.aboutImage];
}
[alert runModal];
}
@end

View File

@@ -0,0 +1,30 @@
//
// WailsMenu.h
// test
//
// Created by Lea Anthony on 25/10/21.
//
#ifndef WailsMenu_h
#define WailsMenu_h
#import <Cocoa/Cocoa.h>
#import "Role.h"
#import "WailsMenu.h"
#import "WailsContext.h"
@interface WailsMenu : NSMenu
//- (void) AddMenuByRole :(Role)role;
- (WailsMenu*) initWithNSTitle :(NSString*)title;
- (void) appendSubmenu :(WailsMenu*)child;
- (void) appendRole :(WailsContext*)ctx :(Role)role;
- (NSMenuItem*) newMenuItemWithContext :(WailsContext*)ctx :(NSString*)title :(SEL)selector :(NSString*)key :(NSEventModifierFlags)flags;
- (void*) AppendMenuItem :(WailsContext*)ctx :(NSString*)label :(NSString *)shortcutKey :(int)modifiers :(bool)disabled :(bool)checked :(int)menuItemID;
- (void) AppendSeparator;
@end
#endif /* WailsMenu_h */

View File

@@ -0,0 +1,318 @@
//
// WailsMenu.m
// test
//
// Created by Lea Anthony on 25/10/21.
//
#import <Foundation/Foundation.h>
#import "WailsMenu.h"
#import "WailsMenuItem.h"
#import "Role.h"
@implementation WailsMenu
- (NSMenuItem*) newMenuItem :(NSString*)title :(SEL)selector :(NSString*)key :(NSEventModifierFlags)flags {
NSMenuItem *result = [[[NSMenuItem alloc] initWithTitle:title action:selector keyEquivalent:key] autorelease];
[result setKeyEquivalentModifierMask:flags];
return result;
}
- (NSMenuItem*) newMenuItemWithContext :(WailsContext*)ctx :(NSString*)title :(SEL)selector :(NSString*)key :(NSEventModifierFlags)flags {
NSMenuItem *result = [NSMenuItem new];
if ( title != nil ) {
[result setTitle:title];
}
if (selector != nil) {
[result setAction:selector];
}
if (key) {
[result setKeyEquivalent:key];
}
if( flags != 0 ) {
[result setKeyEquivalentModifierMask:flags];
}
result.target = ctx;
return result;
}
- (NSMenuItem*) newMenuItem :(NSString*)title :(SEL)selector :(NSString*)key {
return [self newMenuItem :title :selector :key :0];
}
- (WailsMenu*) initWithNSTitle:(NSString *)title {
if( title != nil ) {
[super initWithTitle:title];
}
[self setAutoenablesItems:NO];
return [self init];
}
- (void) appendSubmenu :(WailsMenu*)child {
NSMenuItem *childMenuItem = [[NSMenuItem new] autorelease];
[childMenuItem setTitle:[child title]];
[self addItem:childMenuItem];
[childMenuItem setSubmenu:child];
}
- (void) appendRole :(WailsContext*)ctx :(Role)role {
switch(role) {
case AppMenu:
{
NSString *appName = [NSRunningApplication currentApplication].localizedName;
if( appName == nil ) {
appName = [[NSProcessInfo processInfo] processName];
}
WailsMenu *appMenu = [[[WailsMenu new] initWithNSTitle:appName] autorelease];
id quitTitle = [@"Quit " stringByAppendingString:appName];
NSMenuItem* quitMenuItem = [self newMenuItem:quitTitle :@selector(Quit) :@"q" :NSEventModifierFlagCommand];
quitMenuItem.target = ctx;
if (ctx.aboutTitle != nil) {
[appMenu addItem:[self newMenuItemWithContext :ctx :[@"About " stringByAppendingString:appName] :@selector(About) :nil :0]];
}
[appMenu addItem:quitMenuItem];
[self appendSubmenu:appMenu];
break;
}
case EditMenu:
{
WailsMenu *editMenu = [[[WailsMenu new] initWithNSTitle:@"Edit"] autorelease];
[editMenu addItem:[self newMenuItem:@"Undo" :@selector(undoActionName) :@"z" :NSEventModifierFlagCommand]];
[editMenu addItem:[self newMenuItem:@"Redo" :@selector(redoActionName) :@"z" :(NSEventModifierFlagShift | NSEventModifierFlagCommand)]];
[editMenu addItem:[NSMenuItem separatorItem]];
[editMenu addItem:[self newMenuItem:@"Cut" :@selector(cut:) :@"x" :NSEventModifierFlagCommand]];
[editMenu addItem:[self newMenuItem:@"Copy" :@selector(copy:) :@"c" :NSEventModifierFlagCommand]];
[editMenu addItem:[self newMenuItem:@"Paste" :@selector(paste:) :@"v" :NSEventModifierFlagCommand]];
[editMenu addItem:[self newMenuItem:@"Paste and Match Style" :@selector(pasteAsRichText:) :@"v" :(NSEventModifierFlagOption | NSEventModifierFlagShift | NSEventModifierFlagCommand)]];
[editMenu addItem:[self newMenuItem:@"Delete" :@selector(delete:) :[self accel:@"backspace"] :0]];
[editMenu addItem:[self newMenuItem:@"Select All" :@selector(selectAll:) :@"a" :NSEventModifierFlagCommand]];
[editMenu addItem:[NSMenuItem separatorItem]];
// NSMenuItem *speechMenuItem = [[NSMenuItem new] autorelease];
// [speechMenuItem setTitle:@"Speech"];
// [editMenu addItem:speechMenuItem];
WailsMenu *speechMenu = [[[WailsMenu new] initWithNSTitle:@"Speech"] autorelease];
[speechMenu addItem:[self newMenuItem:@"Start Speaking" :@selector(startSpeaking:) :@""]];
[speechMenu addItem:[self newMenuItem:@"Stop Speaking" :@selector(stopSpeaking:) :@""]];
[editMenu appendSubmenu:speechMenu];
[self appendSubmenu:editMenu];
break;
}
}
}
- (void*) AppendMenuItem :(WailsContext*)ctx :(NSString*)label :(NSString *)shortcutKey :(int)modifiers :(bool)disabled :(bool)checked :(int)menuItemID {
NSString *nslabel = @"";
if (label != nil ) {
nslabel = label;
}
WailsMenuItem *menuItem = [WailsMenuItem new];
// Label
menuItem.title = nslabel;
// Process callback
menuItem.menuItemID = menuItemID;
menuItem.action = @selector(handleClick);
menuItem.target = menuItem;
// Shortcut
if (shortcutKey != nil) {
[menuItem setKeyEquivalent:[self accel:shortcutKey]];
[menuItem setKeyEquivalentModifierMask:modifiers];
}
// Enabled/Disabled
[menuItem setEnabled:!disabled];
// Checked
[menuItem setState:(checked ? NSControlStateValueOn : NSControlStateValueOff)];
[self addItem:menuItem];
return menuItem;
}
- (void) AppendSeparator {
[self addItem:[NSMenuItem separatorItem]];
}
- (NSString*) accel :(NSString*)key {
// Guard against no accelerator key
if( key == NULL ) {
return @"";
}
if( [key isEqualToString:@"backspace"] ) {
return unicode(0x0008);
}
if( [key isEqualToString:@"tab"] ) {
return unicode(0x0009);
}
if( [key isEqualToString:@"return"] ) {
return unicode(0x000d);
}
if( [key isEqualToString:@"enter"] ) {
return unicode(0x000d);
}
if( [key isEqualToString:@"escape"] ) {
return unicode(0x001b);
}
if( [key isEqualToString:@"left"] ) {
return unicode(0x001c);
}
if( [key isEqualToString:@"right"] ) {
return unicode(0x001d);
}
if( [key isEqualToString:@"up"] ) {
return unicode(0x001e);
}
if( [key isEqualToString:@"down"] ) {
return unicode(0x001f);
}
if( [key isEqualToString:@"space"] ) {
return unicode(0x0020);
}
if( [key isEqualToString:@"delete"] ) {
return unicode(0x007f);
}
if( [key isEqualToString:@"home"] ) {
return unicode(0x2196);
}
if( [key isEqualToString:@"end"] ) {
return unicode(0x2198);
}
if( [key isEqualToString:@"page up"] ) {
return unicode(0x21de);
}
if( [key isEqualToString:@"page down"] ) {
return unicode(0x21df);
}
if( [key isEqualToString:@"f1"] ) {
return unicode(0xf704);
}
if( [key isEqualToString:@"f2"] ) {
return unicode(0xf705);
}
if( [key isEqualToString:@"f3"] ) {
return unicode(0xf706);
}
if( [key isEqualToString:@"f4"] ) {
return unicode(0xf707);
}
if( [key isEqualToString:@"f5"] ) {
return unicode(0xf708);
}
if( [key isEqualToString:@"f6"] ) {
return unicode(0xf709);
}
if( [key isEqualToString:@"f7"] ) {
return unicode(0xf70a);
}
if( [key isEqualToString:@"f8"] ) {
return unicode(0xf70b);
}
if( [key isEqualToString:@"f9"] ) {
return unicode(0xf70c);
}
if( [key isEqualToString:@"f10"] ) {
return unicode(0xf70d);
}
if( [key isEqualToString:@"f11"] ) {
return unicode(0xf70e);
}
if( [key isEqualToString:@"f12"] ) {
return unicode(0xf70f);
}
if( [key isEqualToString:@"f13"] ) {
return unicode(0xf710);
}
if( [key isEqualToString:@"f14"] ) {
return unicode(0xf711);
}
if( [key isEqualToString:@"f15"] ) {
return unicode(0xf712);
}
if( [key isEqualToString:@"f16"] ) {
return unicode(0xf713);
}
if( [key isEqualToString:@"f17"] ) {
return unicode(0xf714);
}
if( [key isEqualToString:@"f18"] ) {
return unicode(0xf715);
}
if( [key isEqualToString:@"f19"] ) {
return unicode(0xf716);
}
if( [key isEqualToString:@"f20"] ) {
return unicode(0xf717);
}
if( [key isEqualToString:@"f21"] ) {
return unicode(0xf718);
}
if( [key isEqualToString:@"f22"] ) {
return unicode(0xf719);
}
if( [key isEqualToString:@"f23"] ) {
return unicode(0xf71a);
}
if( [key isEqualToString:@"f24"] ) {
return unicode(0xf71b);
}
if( [key isEqualToString:@"f25"] ) {
return unicode(0xf71c);
}
if( [key isEqualToString:@"f26"] ) {
return unicode(0xf71d);
}
if( [key isEqualToString:@"f27"] ) {
return unicode(0xf71e);
}
if( [key isEqualToString:@"f28"] ) {
return unicode(0xf71f);
}
if( [key isEqualToString:@"f29"] ) {
return unicode(0xf720);
}
if( [key isEqualToString:@"f30"] ) {
return unicode(0xf721);
}
if( [key isEqualToString:@"f31"] ) {
return unicode(0xf722);
}
if( [key isEqualToString:@"f32"] ) {
return unicode(0xf723);
}
if( [key isEqualToString:@"f33"] ) {
return unicode(0xf724);
}
if( [key isEqualToString:@"f34"] ) {
return unicode(0xf725);
}
if( [key isEqualToString:@"f35"] ) {
return unicode(0xf726);
}
// if( [key isEqualToString:@"Insert"] ) {
// return unicode(0xf727);
// }
// if( [key isEqualToString:@"PrintScreen"] ) {
// return unicode(0xf72e);
// }
// if( [key isEqualToString:@"ScrollLock"] ) {
// return unicode(0xf72f);
// }
if( [key isEqualToString:@"numLock"] ) {
return unicode(0xf739);
}
return key;
}
@end

View File

@@ -0,0 +1,22 @@
//
// WailsMenuItem.h
// test
//
// Created by Lea Anthony on 27/10/21.
//
#ifndef WailsMenuItem_h
#define WailsMenuItem_h
#import <Cocoa/Cocoa.h>
@interface WailsMenuItem : NSMenuItem
@property int menuItemID;
- (void) handleClick;
@end
#endif /* WailsMenuItem_h */

View File

@@ -0,0 +1,20 @@
//
// WailsMenuItem.m
// test
//
// Created by Lea Anthony on 27/10/21.
//
#import <Foundation/Foundation.h>
#import "WailsMenuItem.h"
#include "message.h"
@implementation WailsMenuItem
- (void) handleClick {
processCallback(self.menuItemID);
}
@end

View File

@@ -8,10 +8,17 @@
#ifndef WindowDelegate_h
#define WindowDelegate_h
#import "WailsContext.h"
@interface WindowDelegate : NSObject <NSWindowDelegate>
@property bool hideOnClose;
@property (assign) WailsContext* ctx;
- (void)windowDidExitFullScreen:(NSNotification *)notification;
@end

View File

@@ -9,15 +9,29 @@
#import <Cocoa/Cocoa.h>
#import "WindowDelegate.h"
#import "message.h"
#import "WailsContext.h"
@implementation WindowDelegate
- (BOOL)windowShouldClose:(NSWindow *)sender {
[sender orderOut:nil];
if( self.hideOnClose == false ) {
processMessage("Q");
- (BOOL)windowShouldClose:(WailsWindow *)sender {
if( self.hideOnClose ) {
[NSApp hide:nil];
return false;
}
return !self.hideOnClose;
processMessage("Q");
return false;
}
- (void)windowDidExitFullScreen:(NSNotification *)notification {
[self.ctx.mainWindow applyWindowConstraints];
}
- (void)windowWillEnterFullScreen:(NSNotification *)notification {
[self.ctx.mainWindow disableWindowConstraints];
}
- (NSApplicationPresentationOptions)window:(WailsWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions {
return NSApplicationPresentationAutoHideToolbar | NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationFullScreen;
}
@end

View File

@@ -0,0 +1,51 @@
//go:build darwin
// +build darwin
package darwin
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit
#import <Foundation/Foundation.h>
#import "Application.h"
#include <stdlib.h>
*/
import "C"
import (
"errors"
"strconv"
"github.com/wailsapp/wails/v2/pkg/menu"
)
func (f *Frontend) handleCallback(menuItemID uint) error {
menuItem := getMenuItemForID(menuItemID)
if menuItem == nil {
return errors.New("unknown menuItem ID: " + strconv.Itoa(int(menuItemID)))
}
wailsMenuItem := menuItem.wailsMenuItem
if wailsMenuItem.Type == menu.CheckboxType {
wailsMenuItem.Checked = !wailsMenuItem.Checked
C.UpdateMenuItem(menuItem.nsmenuitem, bool2Cint(wailsMenuItem.Checked))
}
if wailsMenuItem.Type == menu.RadioType {
// Ignore if we clicked the item that is already checked
if !wailsMenuItem.Checked {
for _, item := range menuItem.radioGroupMembers {
if item.wailsMenuItem.Checked {
item.wailsMenuItem.Checked = false
C.UpdateMenuItem(item.nsmenuitem, C.int(0))
}
}
wailsMenuItem.Checked = true
C.UpdateMenuItem(menuItem.nsmenuitem, C.int(1))
}
}
if wailsMenuItem.Click != nil {
go wailsMenuItem.Click(&menu.CallbackData{MenuItem: wailsMenuItem})
}
return nil
}

View File

@@ -16,6 +16,7 @@ import (
"fmt"
"strings"
"sync"
"unsafe"
"github.com/leaanthony/slicer"
"github.com/wailsapp/wails/v2/internal/frontend"
@@ -155,7 +156,14 @@ func (f *Frontend) MessageDialog(options frontend.MessageDialogOptions) (string,
buttons[index] = c.String(buttonText)
}
C.MessageDialog(f.mainWindow.context, dialogType, title, message, buttons[0], buttons[1], buttons[2], buttons[3], defaultButton, cancelButton)
var iconData unsafe.Pointer
var iconDataLength C.int
if options.Icon != nil {
iconData = unsafe.Pointer(&options.Icon[0])
iconDataLength = C.int(len(options.Icon))
}
C.MessageDialog(f.mainWindow.context, dialogType, title, message, buttons[0], buttons[1], buttons[2], buttons[3], defaultButton, cancelButton, iconData, iconDataLength)
var result = <-messageDialogResponse

View File

@@ -5,7 +5,7 @@ package darwin
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit -framework UniformTypeIdentifiers
#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"
)
@@ -36,6 +38,7 @@ type request struct {
var messageBuffer = make(chan string, 100)
var requestBuffer = make(chan *request, 100)
var callbackBuffer = make(chan uint, 10)
type Frontend struct {
@@ -50,11 +53,10 @@ type Frontend struct {
assets *assetserver.DesktopAssetServer
// main window handle
mainWindow *Window
minWidth, minHeight, maxWidth, maxHeight int
bindings *binding.Bindings
dispatcher frontend.Dispatcher
servingFromDisk bool
mainWindow *Window
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 {
@@ -65,10 +67,6 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.
bindings: appBindings,
dispatcher: dispatcher,
ctx: ctx,
minHeight: appoptions.MinHeight,
minWidth: appoptions.MinWidth,
maxHeight: appoptions.MaxHeight,
maxWidth: appoptions.MaxWidth,
}
// Check if we have been given a directory to serve assets from.
@@ -92,6 +90,7 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.
go result.startMessageProcessor()
go result.startRequestProcessor()
go result.startCallbackProcessor()
return result
}
@@ -106,6 +105,14 @@ func (f *Frontend) startRequestProcessor() {
f.processRequest(request)
}
}
func (f *Frontend) startCallbackProcessor() {
for callback := range callbackBuffer {
err := f.handleCallback(callback)
if err != nil {
println(err.Error())
}
}
}
func (f *Frontend) WindowReload() {
f.ExecJS("runtime.WindowReload();")
@@ -157,15 +164,11 @@ func (f *Frontend) WindowSetTitle(title string) {
}
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() {
@@ -189,13 +192,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,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()
}
@@ -229,68 +231,104 @@ func (f *Frontend) Notify(name string, data ...interface{}) {
}
func (f *Frontend) processMessage(message string) {
if message == "drag" {
err := f.startDrag()
if err != nil {
f.logger.Error(err.Error())
if message == "DomReady" {
if f.frontendOptions.OnDomReady != nil {
f.frontendOptions.OnDomReady(f.ctx)
}
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)
}
//if strings.HasPrefix(message, "systemevent:") {
// f.processSystemEvent(message)
// 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)
}
}()
}
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.mainWindow.Handle(), w32.WM_NCLBUTTONDOWN, w32.HTCAPTION, 0)
return nil
}
func (f *Frontend) ExecJS(js string) {
f.mainWindow.ExecJS(js)
}
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])
}
data := C.CString(string(_contents))
defer C.free(unsafe.Pointer(data))
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) {
// sl := strings.Split(message, ":")
// if len(sl) != 2 {
// f.logger.Error("Invalid system message: %s", message)
// return
// }
// switch sl[1] {
// case "fullscreen":
// f.mainWindow.DisableSizeConstraints()
// case "unfullscreen":
// f.mainWindow.EnableSizeConstraints()
// default:
// f.logger.Error("Unknown system message: %s", message)
// }
//}
//export processMessage
func processMessage(message *C.char) {
goMessage := C.GoString(message)
@@ -304,3 +342,8 @@ func processURLRequest(ctx unsafe.Pointer, url *C.char) {
ctx: ctx,
}
}
//export processCallback
func processCallback(callbackID uint) {
callbackBuffer <- callbackID
}

View File

@@ -12,7 +12,6 @@
void processMessage(const char*t) {
NSLog(@"processMessage called");
}
void processMessageDialogResponse(int t) {
@@ -22,33 +21,218 @@ void processMessageDialogResponse(int t) {
void processOpenFileDialogResponse(const char *t) {
NSLog(@"processMessage called %s", t);
}
void processSaveFileDialogResponse(const char *t) {
NSLog(@"processMessage called %s", t);
}
void processCallback(int callbackID) {
NSLog(@"Process callback %d", 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", myByteArray, 21);
ProcessURLResponse(ctx, url, "text/html", (void*)myByteArray, 21);
}
unsigned char _Users_username_Pictures_SaltBae_png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14,
0x08, 0x06, 0x00, 0x00, 0x00, 0x8d, 0x89, 0x1d, 0x0d, 0x00, 0x00, 0x00,
0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61,
0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a,
0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80,
0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a,
0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00,
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x01, 0xd5, 0x69, 0x54,
0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64,
0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78,
0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62,
0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20,
0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50,
0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22,
0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44,
0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d,
0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f,
0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79,
0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64,
0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78,
0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68,
0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f,
0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f,
0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f,
0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c,
0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65,
0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72,
0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c,
0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x50, 0x68,
0x6f, 0x74, 0x6f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x49, 0x6e, 0x74,
0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e,
0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x50, 0x68, 0x6f, 0x74,
0x6f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x49, 0x6e, 0x74, 0x65, 0x72,
0x70, 0x72, 0x65, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44,
0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a,
0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46,
0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74,
0x61, 0x3e, 0x0a, 0x02, 0xd8, 0x80, 0x05, 0x00, 0x00, 0x04, 0xdc, 0x49,
0x44, 0x41, 0x54, 0x38, 0x11, 0x1d, 0x94, 0x49, 0x6c, 0x1b, 0x65, 0x18,
0x86, 0x9f, 0x99, 0xf9, 0x67, 0xc6, 0x6b, 0xbc, 0x26, 0xce, 0xda, 0xa4,
0x25, 0x69, 0x0b, 0x2d, 0x28, 0x34, 0x2c, 0x95, 0x00, 0x89, 0x45, 0x08,
0x5a, 0x95, 0x03, 0x08, 0x09, 0x21, 0xe0, 0x80, 0x38, 0xc3, 0x85, 0x03,
0xe2, 0x00, 0x47, 0xc4, 0x1d, 0x38, 0x70, 0xe3, 0xc6, 0x01, 0x01, 0x42,
0x20, 0x54, 0x7a, 0x2a, 0x6b, 0x0b, 0x94, 0xd2, 0xd2, 0x25, 0x69, 0x9b,
0xa4, 0x0d, 0x2d, 0xa9, 0xb3, 0x78, 0x89, 0x9d, 0xf1, 0x2c, 0x9e, 0x85,
0x2f, 0xb5, 0x35, 0xb6, 0x35, 0x96, 0xde, 0x79, 0xdf, 0xef, 0x7f, 0x9f,
0x4f, 0xfb, 0xe0, 0xad, 0x37, 0x12, 0xfd, 0xf0, 0xb3, 0x9c, 0xfb, 0xb7,
0xc5, 0x8d, 0x46, 0x9b, 0x71, 0x5b, 0xf1, 0xd0, 0xf4, 0x18, 0xdb, 0xeb,
0x4b, 0x1c, 0xff, 0xf1, 0x57, 0x98, 0xdc, 0x87, 0x72, 0x3a, 0x8c, 0x3a,
0xcb, 0x8c, 0xea, 0x31, 0x35, 0xb7, 0xc3, 0x99, 0xba, 0xc3, 0xd7, 0xab,
0x3e, 0x87, 0x2a, 0x8a, 0xb3, 0xff, 0xdc, 0xe0, 0x9b, 0x8f, 0x5f, 0xa2,
0x1c, 0xc5, 0xfc, 0x72, 0xc9, 0x41, 0x99, 0x71, 0x48, 0xca, 0x84, 0x3c,
0x3e, 0xda, 0xd2, 0x05, 0x9a, 0xb1, 0xc7, 0x35, 0x67, 0x1c, 0xdd, 0x4c,
0x68, 0xeb, 0x26, 0xd9, 0x30, 0x26, 0x09, 0x23, 0x5c, 0x3f, 0xc2, 0xd3,
0x43, 0xc2, 0x24, 0x21, 0x4e, 0x34, 0x40, 0x27, 0x89, 0x13, 0xf9, 0x1e,
0x22, 0x6e, 0xd5, 0x45, 0x43, 0x63, 0xc6, 0xd2, 0x50, 0xa9, 0xc4, 0x67,
0x24, 0x15, 0x72, 0xa9, 0x7e, 0x95, 0xfa, 0x4f, 0x27, 0x78, 0x64, 0x76,
0x86, 0x23, 0x61, 0xc0, 0xf0, 0x58, 0x15, 0xc3, 0x29, 0x71, 0x06, 0x45,
0x2e, 0xa5, 0x48, 0xbb, 0x0a, 0x3d, 0x89, 0xa0, 0x8f, 0x08, 0x8a, 0x8e,
0x08, 0xbb, 0xc1, 0x8e, 0xb0, 0x8d, 0xdd, 0x0f, 0xc9, 0x84, 0x06, 0x65,
0x34, 0xf4, 0xed, 0x8d, 0xff, 0x58, 0xbd, 0xfc, 0x27, 0x17, 0x2f, 0x9e,
0xe3, 0xf0, 0x81, 0x49, 0x5e, 0xde, 0x5f, 0xe1, 0x9e, 0x82, 0xcd, 0xdc,
0x78, 0x8d, 0xd9, 0xb2, 0xc9, 0x56, 0x12, 0x32, 0x94, 0x4f, 0x91, 0xcb,
0x88, 0x68, 0xda, 0x42, 0x13, 0x77, 0x11, 0xa2, 0xa8, 0xc3, 0x5a, 0x5f,
0x46, 0x30, 0x65, 0x52, 0x29, 0xe4, 0x24, 0x4d, 0x8e, 0xcc, 0x68, 0x19,
0xe5, 0x76, 0xbb, 0xac, 0x5c, 0x98, 0xa7, 0xb3, 0xed, 0xd0, 0x37, 0x62,
0xa2, 0xb0, 0xc7, 0x89, 0xe5, 0x2e, 0x03, 0x0d, 0x97, 0x95, 0x46, 0x8f,
0x31, 0xd7, 0xa6, 0x63, 0x81, 0x65, 0x25, 0x84, 0xba, 0x45, 0x5f, 0x65,
0x31, 0x2c, 0x71, 0x6b, 0x77, 0x69, 0xf5, 0x7a, 0xbc, 0xb0, 0x3b, 0xcd,
0xf9, 0xa5, 0x90, 0xd1, 0xb0, 0xcd, 0xd4, 0xb0, 0xdc, 0xd7, 0xc4, 0xfa,
0xf0, 0x78, 0x95, 0x7b, 0x27, 0xab, 0x5c, 0x5e, 0x6e, 0xd2, 0xee, 0x05,
0xdc, 0xd8, 0xea, 0xf1, 0xf7, 0xe2, 0x1a, 0xc7, 0xee, 0x1a, 0x62, 0x2e,
0x1f, 0xe3, 0xe8, 0xb6, 0xc4, 0x4c, 0xd3, 0x6d, 0x6e, 0xd0, 0x6b, 0xfc,
0x4c, 0xe3, 0xd4, 0x1f, 0xc4, 0x4b, 0xf3, 0x1c, 0x2c, 0x65, 0x29, 0x67,
0x4d, 0xbe, 0xfb, 0xad, 0x45, 0x65, 0x0c, 0xea, 0x7e, 0x1f, 0x15, 0x6b,
0x09, 0x0b, 0x8b, 0xb7, 0x19, 0xc9, 0xa5, 0x78, 0x75, 0x6e, 0x18, 0xdf,
0xf5, 0x79, 0x72, 0xd0, 0xa2, 0x2d, 0xb3, 0x3a, 0xbb, 0xb4, 0x41, 0x3e,
0x53, 0xe6, 0xf4, 0xca, 0x3c, 0xa5, 0x7c, 0x86, 0xe9, 0xfd, 0x47, 0x18,
0x2e, 0xbd, 0xce, 0xd1, 0x97, 0x26, 0x78, 0xbc, 0x7e, 0x1d, 0xff, 0xcc,
0xa7, 0x5c, 0x71, 0x74, 0x16, 0xe3, 0x18, 0xd7, 0x1e, 0x23, 0xe8, 0xac,
0xa3, 0x0c, 0xcd, 0x60, 0x22, 0x6f, 0x43, 0x36, 0x43, 0x3b, 0x19, 0xc6,
0x08, 0x7a, 0xe0, 0x6c, 0xe3, 0x27, 0x8a, 0xdb, 0x4e, 0xc0, 0xd4, 0xa0,
0xcd, 0x27, 0xaf, 0xbd, 0xcb, 0x86, 0x36, 0xc6, 0xcc, 0xfe, 0x59, 0xd2,
0xca, 0x90, 0x93, 0x36, 0x70, 0xaf, 0x9c, 0xe4, 0xcb, 0x6f, 0x65, 0x54,
0xd9, 0x47, 0x59, 0x70, 0xbb, 0x74, 0x1b, 0x0e, 0x89, 0xe7, 0xa3, 0xc7,
0x12, 0x39, 0x63, 0xea, 0x68, 0x12, 0x6b, 0x53, 0x5c, 0x9e, 0xef, 0x76,
0xf0, 0x55, 0x86, 0x0d, 0x17, 0x56, 0x9a, 0x4d, 0x94, 0x95, 0x65, 0xe6,
0xbe, 0x67, 0x98, 0xbe, 0xfb, 0x21, 0x52, 0xd2, 0x43, 0xaf, 0x5d, 0x47,
0x6b, 0x5c, 0xa3, 0x59, 0xbf, 0xc2, 0x62, 0xdd, 0x26, 0xa5, 0x12, 0x6a,
0x41, 0x44, 0xdf, 0xbd, 0xcd, 0x92, 0x17, 0xa0, 0xb6, 0x03, 0x43, 0xba,
0x66, 0x91, 0xe9, 0xdc, 0xc2, 0xce, 0xed, 0xa1, 0xfc, 0xc0, 0x2b, 0x14,
0xff, 0xfd, 0x1e, 0x4b, 0xb3, 0xa9, 0x29, 0x87, 0x81, 0xd2, 0x04, 0x8e,
0x66, 0x89, 0x58, 0x00, 0x7e, 0x07, 0xaf, 0xdb, 0xa4, 0xbb, 0xb5, 0x49,
0xb9, 0xaa, 0x18, 0xb9, 0x77, 0x8e, 0xcd, 0xdb, 0x6d, 0x1e, 0x1c, 0xb5,
0x38, 0x7d, 0xa5, 0xcf, 0xaa, 0x08, 0xeb, 0x77, 0x3f, 0x35, 0xc7, 0xda,
0xfc, 0x02, 0xaa, 0xf6, 0x1c, 0xbb, 0x9f, 0x78, 0x9f, 0x89, 0x43, 0x47,
0xa4, 0x6f, 0x3d, 0x06, 0xed, 0x90, 0x92, 0x79, 0x95, 0xd4, 0xe4, 0xfd,
0x98, 0x66, 0x4a, 0x6a, 0xd7, 0xc7, 0x0b, 0x62, 0xa4, 0xe3, 0x8c, 0x4d,
0xc4, 0xe8, 0x85, 0x98, 0xe5, 0x46, 0x44, 0x26, 0x97, 0x21, 0xe9, 0xf7,
0xf9, 0x61, 0xc5, 0xe3, 0xd4, 0x66, 0x84, 0xd2, 0x70, 0xc9, 0xee, 0x79,
0x98, 0x43, 0xc7, 0x5e, 0x27, 0xb6, 0x8a, 0xd2, 0x5a, 0x1f, 0xf3, 0xa9,
0xf7, 0x88, 0xce, 0x7d, 0x85, 0x71, 0xe0, 0x79, 0x98, 0x7a, 0x90, 0x9e,
0x1b, 0xd0, 0x13, 0x52, 0x4a, 0x66, 0x97, 0x7d, 0x33, 0x1e, 0xed, 0xae,
0xc7, 0x87, 0x1f, 0x7d, 0xce, 0xc2, 0xd5, 0x3a, 0xe6, 0xde, 0x02, 0xcb,
0xdb, 0x3e, 0xbe, 0xa6, 0x91, 0x95, 0x62, 0x6b, 0x2f, 0xce, 0x90, 0x3c,
0xfd, 0xce, 0x71, 0x0e, 0xcc, 0x3e, 0x82, 0x13, 0xf4, 0x09, 0xd5, 0x00,
0x16, 0x82, 0x98, 0xb3, 0x49, 0x24, 0xb1, 0x83, 0xc8, 0xc0, 0xd6, 0x3a,
0x54, 0x33, 0xab, 0x14, 0x8c, 0x16, 0x4e, 0x38, 0xcc, 0xe5, 0xeb, 0x4d,
0x5e, 0x7b, 0xfb, 0x4d, 0xaa, 0x79, 0xa1, 0x45, 0x1c, 0x9b, 0xd2, 0x94,
0xcc, 0x0e, 0x8c, 0x52, 0x7a, 0x65, 0x17, 0xc7, 0xa9, 0x0c, 0x8e, 0xe2,
0xf7, 0xba, 0xa8, 0xc8, 0x13, 0x87, 0x32, 0x87, 0x0b, 0x27, 0x30, 0x36,
0x57, 0xe8, 0xea, 0x15, 0xce, 0x06, 0x65, 0x5e, 0x3d, 0x5a, 0x94, 0x53,
0xb7, 0x59, 0x58, 0xdf, 0x25, 0xc4, 0xe4, 0xc9, 0x65, 0x3d, 0xb4, 0xb4,
0x4e, 0x37, 0x0c, 0x29, 0x98, 0x4a, 0xe8, 0x11, 0xde, 0x85, 0x42, 0x43,
0x1c, 0xaa, 0x38, 0x55, 0xc4, 0xb4, 0x2c, 0x22, 0x3d, 0xcd, 0xfa, 0xea,
0x0d, 0xf4, 0x8d, 0x1f, 0xc9, 0x5f, 0xfa, 0x82, 0x6d, 0xc7, 0xe1, 0xa6,
0x57, 0xe3, 0x56, 0x6e, 0x96, 0xbf, 0x16, 0x1f, 0xa3, 0x54, 0xaa, 0x91,
0x16, 0x5a, 0xb2, 0xa9, 0x04, 0xaf, 0x67, 0xc9, 0xac, 0x6c, 0xfa, 0x32,
0x9e, 0x48, 0xea, 0xa5, 0x0b, 0x89, 0x3b, 0x54, 0x47, 0xf2, 0xa1, 0xf2,
0x2a, 0x4d, 0xeb, 0xf4, 0x17, 0xdc, 0xd4, 0x72, 0x6c, 0xb5, 0x36, 0x28,
0xb6, 0x7e, 0x17, 0x04, 0xd3, 0xac, 0x7a, 0x42, 0xc1, 0xf4, 0x6e, 0x9e,
0xbf, 0x6b, 0xb7, 0x3c, 0x3a, 0x21, 0x67, 0xcb, 0x41, 0x48, 0x07, 0x91,
0xde, 0x1a, 0xe2, 0xaa, 0x9c, 0xb1, 0x59, 0xdb, 0x12, 0x25, 0xc1, 0x32,
0x92, 0xea, 0xc9, 0xaf, 0x3b, 0x97, 0xca, 0xca, 0xfe, 0x5b, 0xfe, 0xe5,
0x33, 0x29, 0xeb, 0x16, 0x95, 0xd2, 0x24, 0xeb, 0xda, 0x30, 0xeb, 0x95,
0x1a, 0xd3, 0xf7, 0x0f, 0x51, 0x1c, 0xd9, 0x0b, 0x99, 0x12, 0x7a, 0x4a,
0xd0, 0xd3, 0x25, 0x9a, 0x88, 0x45, 0xb1, 0x04, 0x33, 0x2c, 0x8a, 0x99,
0x34, 0x6b, 0x75, 0x19, 0x91, 0x9d, 0x92, 0x29, 0x89, 0xa0, 0x2c, 0x8b,
0x9d, 0xd8, 0x7a, 0x5e, 0x04, 0x07, 0x87, 0x66, 0x28, 0x56, 0x67, 0xb9,
0xd6, 0xd2, 0x39, 0xd9, 0xec, 0x33, 0x30, 0xb2, 0x8b, 0xea, 0xae, 0x83,
0x18, 0xb9, 0x31, 0x34, 0xbb, 0x42, 0x22, 0x0b, 0x21, 0x96, 0x3c, 0x61,
0xac, 0xcb, 0x95, 0x60, 0x2a, 0xe9, 0x68, 0x79, 0x08, 0x36, 0x56, 0x65,
0x27, 0x4a, 0xd9, 0x83, 0x00, 0xcf, 0x0b, 0xf1, 0xfc, 0x10, 0x15, 0x0a,
0x6a, 0x75, 0x77, 0x8b, 0x86, 0xdc, 0x58, 0x57, 0x45, 0x52, 0xe9, 0x84,
0x81, 0x7c, 0x91, 0x28, 0x55, 0x23, 0x96, 0x13, 0xd7, 0x24, 0xbe, 0xac,
0x17, 0xfa, 0xf2, 0x78, 0x63, 0xc7, 0x82, 0x08, 0xda, 0xa6, 0xc5, 0x50,
0x55, 0x04, 0xe5, 0x65, 0x5b, 0x06, 0xde, 0xce, 0xf0, 0x24, 0xf3, 0x4e,
0x70, 0xb5, 0x15, 0x6a, 0x34, 0x7b, 0x11, 0x9d, 0xbe, 0x10, 0x53, 0xd0,
0xa8, 0x86, 0x2e, 0x76, 0xb6, 0x2a, 0x9d, 0x2c, 0x48, 0x3c, 0x5b, 0xa2,
0xc8, 0x3a, 0x37, 0xd4, 0x9d, 0xed, 0x6c, 0x4a, 0xab, 0x95, 0x6e, 0x08,
0x66, 0x3d, 0x5a, 0xad, 0x4d, 0x18, 0xc8, 0xca, 0xfa, 0xd5, 0x85, 0x6f,
0xf9, 0x5f, 0xde, 0x02, 0x30, 0xff, 0x03, 0x8c, 0x47, 0x35, 0xad, 0xbc,
0xbf, 0x26, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
0x42, 0x60, 0x82
};
unsigned int _Users_username_Pictures_SaltBae_png_len = 1863;
int main(int argc, const char * argv[]) {
// insert code here...
int frameless = 0;
int resizable = 1;
int fullscreen = 0;
int fullscreen = 1;
int fullSizeContent = 1;
int hideTitleBar = 0;
int titlebarAppearsTransparent = 1;
int titlebarAppearsTransparent = 0;
int hideTitle = 0;
int useToolbar = 1;
int hideToolbarSeparator = 1;
int webviewIsTransparent = 0;
int alwaysOnTop = 1;
int useToolbar = 0;
int hideToolbarSeparator = 0;
int webviewIsTransparent = 1;
int alwaysOnTop = 0;
int hideWindowOnClose = 0;
const char* appearance = "NSAppearanceNameDarkAqua";
int windowIsTranslucent = 1;
int debug = 1;
WailsContext *result = Create("OI OI!",400,400, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug);
int windowStartState = 0;
int startsHidden = 0;
WailsContext *result = Create("OI OI!",400,400, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug, windowStartState,
startsHidden, 400, 400, 600, 600);
SetRGBA(result, 255, 0, 0, 255);
void *m = NewMenu("");
SetAbout(result, "Fake title", "I am a description", _Users_username_Pictures_SaltBae_png, _Users_username_Pictures_SaltBae_png_len);
// AddMenuByRole(result, 1);
AppendRole(result, m, 1);
AppendRole(result, m, 2);
void* submenu = NewMenu("test");
void* menuITem = AppendMenuItem(result, submenu, "Woohoo", "p", 0, 0, 0, 470);
AppendSubmenu(m, submenu);
UpdateMenuItem(menuITem, 1);
SetAsApplicationMenu(result, m);
// SetPosition(result, 100, 100);
Run((void*)CFBridgingRetain(result));

View File

@@ -3,96 +3,133 @@
package darwin
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit
#import <Foundation/Foundation.h>
#import "Application.h"
#import "WailsContext.h"
#include <stdlib.h>
*/
import "C"
import (
"unsafe"
"github.com/wailsapp/wails/v2/pkg/menu"
"github.com/wailsapp/wails/v2/pkg/menu/keys"
)
type NSMenu struct {
context unsafe.Pointer
nsmenu unsafe.Pointer
}
func NewNSMenu(context unsafe.Pointer, name string) *NSMenu {
c := NewCalloc()
defer c.Free()
title := c.String(name)
nsmenu := C.NewMenu(title)
return &NSMenu{
context: context,
nsmenu: nsmenu,
}
}
func (m *NSMenu) AddSubMenu(label string) *NSMenu {
result := NewNSMenu(m.context, label)
C.AppendSubmenu(m.nsmenu, result.nsmenu)
return result
}
func (m *NSMenu) AppendRole(role menu.Role) {
C.AppendRole(m.context, m.nsmenu, C.int(role))
}
type MenuItem struct {
id uint
nsmenuitem unsafe.Pointer
wailsMenuItem *menu.MenuItem
radioGroupMembers []*MenuItem
}
func (m *NSMenu) AddMenuItem(menuItem *menu.MenuItem) *MenuItem {
c := NewCalloc()
defer c.Free()
var modifier C.int
var key *C.char
if menuItem.Accelerator != nil {
modifier = C.int(keys.ToMacModifier(menuItem.Accelerator))
key = c.String(menuItem.Accelerator.Key)
}
result := &MenuItem{
wailsMenuItem: menuItem,
}
result.id = createMenuItemID(result)
result.nsmenuitem = C.AppendMenuItem(m.context, m.nsmenu, c.String(menuItem.Label), key, modifier, bool2Cint(menuItem.Disabled), bool2Cint(menuItem.Checked), C.int(result.id))
return result
}
//func (w *Window) SetApplicationMenu(menu *menu.Menu) {
//w.applicationMenu = menu
//processMenu(w, menu)
//}
//func processMenu(window *Window, menu *menu.Menu) {
//mainMenu := window.NewMenu()
//for _, menuItem := range menu.Items {
// submenu := mainMenu.AddSubMenu(menuItem.Label)
// for _, menuItem := range menuItem.SubMenu.Items {
// processMenuItem(submenu, menuItem)
// }
//}
//mainMenu.Show()
//}
func processMenu(parent *NSMenu, wailsMenu *menu.Menu) {
var radioGroups []*MenuItem
//func processMenuItem(parent *winc.MenuItem, menuItem *menu.MenuItem) {
// if menuItem.Hidden {
// return
// }
// switch menuItem.Type {
// case menu.SeparatorType:
// parent.AddSeparator()
// case menu.TextType:
// shortcut := acceleratorToWincShortcut(menuItem.Accelerator)
// newItem := parent.AddItem(menuItem.Label, shortcut)
// if menuItem.Tooltip != "" {
// newItem.SetToolTip(menuItem.Tooltip)
// }
// if menuItem.Click != nil {
// newItem.OnClick().Bind(func(e *winc.Event) {
// menuItem.Click(&menu.CallbackData{
// MenuItem: menuItem,
// })
// })
// }
// newItem.SetEnabled(!menuItem.Disabled)
//
// case menu.CheckboxType:
// shortcut := acceleratorToWincShortcut(menuItem.Accelerator)
// newItem := parent.AddItem(menuItem.Label, shortcut)
// newItem.SetCheckable(true)
// newItem.SetChecked(menuItem.Checked)
// if menuItem.Tooltip != "" {
// newItem.SetToolTip(menuItem.Tooltip)
// }
// if menuItem.Click != nil {
// newItem.OnClick().Bind(func(e *winc.Event) {
// toggleCheckBox(menuItem)
// menuItem.Click(&menu.CallbackData{
// MenuItem: menuItem,
// })
// })
// }
// newItem.SetEnabled(!menuItem.Disabled)
// addCheckBoxToMap(menuItem, newItem)
// case menu.RadioType:
// shortcut := acceleratorToWincShortcut(menuItem.Accelerator)
// newItem := parent.AddItemRadio(menuItem.Label, shortcut)
// newItem.SetCheckable(true)
// newItem.SetChecked(menuItem.Checked)
// if menuItem.Tooltip != "" {
// newItem.SetToolTip(menuItem.Tooltip)
// }
// if menuItem.Click != nil {
// newItem.OnClick().Bind(func(e *winc.Event) {
// toggleRadioItem(menuItem)
// menuItem.Click(&menu.CallbackData{
// MenuItem: menuItem,
// })
// })
// }
// newItem.SetEnabled(!menuItem.Disabled)
// addRadioItemToMap(menuItem, newItem)
// case menu.SubmenuType:
// submenu := parent.AddSubMenu(menuItem.Label)
// for _, menuItem := range menuItem.SubMenu.Items {
// processMenuItem(submenu, menuItem)
// }
// }
//}
for _, menuItem := range wailsMenu.Items {
if menuItem.SubMenu != nil {
if len(radioGroups) > 0 {
processRadioGroups(radioGroups)
radioGroups = []*MenuItem{}
}
submenu := parent.AddSubMenu(menuItem.Label)
processMenu(submenu, menuItem.SubMenu)
} else {
lastMenuItem := processMenuItem(parent, menuItem)
if menuItem.Type == menu.RadioType {
radioGroups = append(radioGroups, lastMenuItem)
} else {
if len(radioGroups) > 0 {
processRadioGroups(radioGroups)
radioGroups = []*MenuItem{}
}
}
}
}
}
func processRadioGroups(groups []*MenuItem) {
for _, item := range groups {
item.radioGroupMembers = groups
}
}
func processMenuItem(parent *NSMenu, menuItem *menu.MenuItem) *MenuItem {
if menuItem.Hidden {
return nil
}
if menuItem.Role != 0 {
parent.AppendRole(menuItem.Role)
return nil
}
if menuItem.Type == menu.SeparatorType {
C.AppendSeparator(parent.nsmenu)
return nil
}
return parent.AddMenuItem(menuItem)
}
func (f *Frontend) MenuSetApplicationMenu(menu *menu.Menu) {
//f.mainWindow.SetApplicationMenu(menu)
f.mainWindow.SetApplicationMenu(menu)
}
func (f *Frontend) MenuUpdateApplicationMenu() {
//processMenu(f.mainWindow, f.mainWindow.applicationMenu)
f.MenuSetApplicationMenu(f.frontendOptions.Menu)
f.mainWindow.UpdateApplicationMenu()
}

View File

@@ -0,0 +1,51 @@
//go:build darwin
// +build darwin
package darwin
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit
#import <Foundation/Foundation.h>
#import "Application.h"
#import "WailsContext.h"
#include <stdlib.h>
*/
import "C"
import (
"log"
"math"
"sync"
)
var menuItemToID = make(map[*MenuItem]uint)
var idToMenuItem = make(map[uint]*MenuItem)
var menuItemLock sync.Mutex
var menuItemIDCounter uint = 0
func createMenuItemID(item *MenuItem) uint {
menuItemLock.Lock()
defer menuItemLock.Unlock()
counter := 0
for {
menuItemIDCounter++
value := idToMenuItem[menuItemIDCounter]
if value == nil {
break
}
counter++
if counter == math.MaxInt {
log.Fatal("insane amounts of menuitems detected! Aborting before the collapse of the world!")
}
}
idToMenuItem[menuItemIDCounter] = item
menuItemToID[item] = menuItemIDCounter
return menuItemIDCounter
}
func getMenuItemForID(id uint) *MenuItem {
menuItemLock.Lock()
defer menuItemLock.Unlock()
return idToMenuItem[id]
}

View File

@@ -19,6 +19,7 @@ void processURLRequest(void*, const char *);
void processMessageDialogResponse(int);
void processOpenFileDialogResponse(const char*);
void processSaveFileDialogResponse(const char*);
void processCallback(int);
#ifdef __cplusplus
}

View File

@@ -1,3 +1,6 @@
//go:build darwin
// +build darwin
package darwin
/*
@@ -17,6 +20,8 @@ import (
"strings"
"unsafe"
"github.com/wailsapp/wails/v2/pkg/menu"
"github.com/wailsapp/wails/v2/pkg/options"
)
@@ -45,11 +50,8 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
fullscreen := bool2Cint(frontendOptions.Fullscreen)
alwaysOnTop := bool2Cint(frontendOptions.AlwaysOnTop)
hideWindowOnClose := bool2Cint(frontendOptions.HideWindowOnClose)
startsHidden := bool2Cint(frontendOptions.StartHidden)
debug := bool2Cint(debugMode)
alpha := C.int(frontendOptions.RGBA.A)
red := C.int(frontendOptions.RGBA.R)
green := C.int(frontendOptions.RGBA.G)
blue := C.int(frontendOptions.RGBA.B)
var fullSizeContent, hideTitleBar, hideTitle, useToolbar, webviewIsTransparent C.int
var titlebarAppearsTransparent, hideToolbarSeparator, windowIsTranslucent C.int
@@ -57,6 +59,11 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
width := C.int(frontendOptions.Width)
height := C.int(frontendOptions.Height)
minWidth := C.int(frontendOptions.MinWidth)
minHeight := C.int(frontendOptions.MinHeight)
maxWidth := C.int(frontendOptions.MaxWidth)
maxHeight := C.int(frontendOptions.MaxHeight)
windowStartState := C.int(int(frontendOptions.WindowStartState))
title = c.String(frontendOptions.Title)
@@ -75,13 +82,37 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
appearance = c.String(string(mac.Appearance))
}
var context *C.WailsContext = C.Create(title, width, height, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug)
var context *C.WailsContext = C.Create(title, width, height, frameless, resizable, fullscreen, fullSizeContent,
hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent,
alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug, windowStartState, startsHidden,
minWidth, minHeight, maxWidth, maxHeight)
C.SetRGBA(unsafe.Pointer(context), red, green, blue, alpha)
return &Window{
// Create menu
result := &Window{
context: unsafe.Pointer(context),
}
if frontendOptions.RGBA != nil {
result.SetRGBA(frontendOptions.RGBA.R, frontendOptions.RGBA.G, frontendOptions.RGBA.B, frontendOptions.RGBA.A)
}
if frontendOptions.Mac != nil && frontendOptions.Mac.About != nil {
title := c.String(frontendOptions.Mac.About.Title)
description := c.String(frontendOptions.Mac.About.Message)
var icon unsafe.Pointer
var length C.int
if frontendOptions.Mac.About.Icon != nil {
icon = unsafe.Pointer(&frontendOptions.Mac.About.Icon[0])
length = C.int(len(frontendOptions.Mac.About.Icon))
}
C.SetAbout(result.context, title, description, icon, length)
}
if frontendOptions.Menu != nil {
result.SetApplicationMenu(frontendOptions.Menu)
}
return result
}
func (w *Window) Center() {
@@ -90,7 +121,6 @@ func (w *Window) Center() {
func (w *Window) Run() {
C.Run(w.context)
println("I exited!")
}
func (w *Window) Quit() {
@@ -185,3 +215,13 @@ func (w *Window) Size() (int, int) {
temp := C.GoString(_result)
return parseIntDuo(temp)
}
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)
}

View File

@@ -0,0 +1,17 @@
//go:build linux
// +build linux
package desktop
import (
"context"
"github.com/wailsapp/wails/v2/internal/binding"
"github.com/wailsapp/wails/v2/internal/frontend"
"github.com/wailsapp/wails/v2/internal/frontend/desktop/linux"
"github.com/wailsapp/wails/v2/internal/logger"
"github.com/wailsapp/wails/v2/pkg/options"
)
func NewFrontend(ctx context.Context, appoptions *options.App, logger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher) frontend.Frontend {
return linux.NewFrontend(ctx, appoptions, logger, appBindings, dispatcher)
}

View File

@@ -0,0 +1,12 @@
//go:build linux
// +build linux
package linux
import "github.com/pkg/browser"
// BrowserOpenURL Use the default browser to open the url
func (f *Frontend) BrowserOpenURL(url string) {
// Specific method implementation
_ = browser.OpenURL(url)
}

View File

@@ -0,0 +1,26 @@
//go:build linux
// +build linux
package linux
import "github.com/wailsapp/wails/v2/internal/frontend"
func (f *Frontend) OpenFileDialog(dialogOptions frontend.OpenDialogOptions) (string, error) {
panic("implement me")
}
func (f *Frontend) OpenMultipleFilesDialog(dialogOptions frontend.OpenDialogOptions) ([]string, error) {
panic("implement me")
}
func (f *Frontend) OpenDirectoryDialog(dialogOptions frontend.OpenDialogOptions) (string, error) {
panic("implement me")
}
func (f *Frontend) SaveFileDialog(dialogOptions frontend.SaveDialogOptions) (string, error) {
panic("implement me")
}
func (f *Frontend) MessageDialog(dialogOptions frontend.MessageDialogOptions) (string, error) {
panic("implement me")
}

View File

@@ -0,0 +1,370 @@
//go:build linux
// +build linux
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"
)
type Frontend struct {
// Context
ctx context.Context
frontendOptions *options.App
logger *logger.Logger
debug bool
// Assets
assets *assetserver.DesktopAssetServer
startURL string
// main window handle
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 {
// Set GDK_BACKEND=x11 to prevent warnings
os.Setenv("GDK_BACKEND", "x11")
result := &Frontend{
frontendOptions: appoptions,
logger: myLogger,
bindings: appBindings,
dispatcher: dispatcher,
ctx: ctx,
startURL: "file://wails/",
}
bindingsJSON, err := appBindings.ToJSON()
if err != nil {
log.Fatal(err)
}
_devServerURL := ctx.Value("devserverurl")
if _devServerURL != nil {
devServerURL := _devServerURL.(string)
if len(devServerURL) > 0 && devServerURL != "http://localhost:34115" {
result.startURL = devServerURL
return result
}
}
// 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 webkit.
_assetdir := ctx.Value("assetdir")
if _assetdir != nil {
result.servingFromDisk = true
}
assets, err := assetserver.NewDesktopAssetServer(ctx, appoptions.Assets, bindingsJSON)
if err != nil {
log.Fatal(err)
}
result.assets = assets
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();")
}
func (f *Frontend) Run(ctx context.Context) error {
f.ctx = context.WithValue(ctx, "frontend", f)
go func() {
if f.frontendOptions.OnStartup != nil {
f.frontendOptions.OnStartup(f.ctx)
}
}()
f.mainWindow.Run()
return nil
}
func (f *Frontend) WindowCenter() {
f.mainWindow.Center()
}
func (f *Frontend) WindowSetPos(x, y int) {
f.mainWindow.SetPos(x, y)
}
func (f *Frontend) WindowGetPos() (int, int) {
return f.mainWindow.Pos()
}
func (f *Frontend) WindowSetSize(width, height int) {
f.mainWindow.SetSize(width, height)
}
func (f *Frontend) WindowGetSize() (int, int) {
return f.mainWindow.Size()
}
func (f *Frontend) WindowSetTitle(title string) {
f.mainWindow.SetTitle(title)
}
func (f *Frontend) WindowFullscreen() {
f.mainWindow.Fullscreen()
}
func (f *Frontend) WindowUnFullscreen() {
f.mainWindow.UnFullscreen()
}
func (f *Frontend) WindowShow() {
f.mainWindow.Show()
}
func (f *Frontend) WindowHide() {
f.mainWindow.Hide()
}
func (f *Frontend) WindowMaximise() {
f.mainWindow.Maximise()
}
func (f *Frontend) WindowUnmaximise() {
f.mainWindow.UnMaximise()
}
func (f *Frontend) WindowMinimise() {
f.mainWindow.Minimise()
}
func (f *Frontend) WindowUnminimise() {
f.mainWindow.UnMinimise()
}
func (f *Frontend) WindowSetMinSize(width int, height int) {
f.mainWindow.SetMinSize(width, height)
}
func (f *Frontend) WindowSetMaxSize(width int, height int) {
f.mainWindow.SetMaxSize(width, height)
}
func (f *Frontend) WindowSetRGBA(col *options.RGBA) {
if col == nil {
return
}
}
func (f *Frontend) Quit() {
if f.frontendOptions.OnBeforeClose != nil && f.frontendOptions.OnBeforeClose(f.ctx) {
return
}
f.mainWindow.Quit()
}
type EventNotify struct {
Name string `json:"name"`
Data []interface{} `json:"data"`
}
func (f *Frontend) Notify(name string, data ...interface{}) {
notification := EventNotify{
Name: name,
Data: data,
}
payload, err := json.Marshal(notification)
if err != nil {
f.logger.Error(err.Error())
return
}
f.ExecJS(`window.wails.EventsNotify('` + template.JSEscapeString(string(payload)) + `');`)
}
func (f *Frontend) processMessage(message string) {
if message == "drag" {
// if !f.mainWindow.IsFullScreen() {
f.startDrag()
// }
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)
}
}()
}
func (f *Frontend) Callback(message string) {
f.ExecJS(`window.wails.Callback(` + strconv.Quote(message) + `);`)
}
func (f *Frontend) startDrag() {
f.dispatch(func() {
f.mainWindow.StartDrag()
})
}
func (f *Frontend) ExecJS(js string) {
f.dispatch(func() {
f.mainWindow.ExecJS(js)
})
}
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) {
id := int(cid)
fn := dispatchCallbacks[id]
if fn != nil {
go 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) {
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)
}

View File

@@ -0,0 +1,14 @@
//go:build linux
// +build linux
package linux
import "github.com/wailsapp/wails/v2/pkg/menu"
func (f *Frontend) MenuSetApplicationMenu(menu *menu.Menu) {
panic("implement me")
}
func (f *Frontend) MenuUpdateApplicationMenu() {
panic("implement me")
}

View File

@@ -0,0 +1,410 @@
//go:build linux
// +build linux
package linux
/*
#cgo linux pkg-config: gtk+-3.0 webkit2gtk-4.0
#include "gtk/gtk.h"
#include "webkit2/webkit2.h"
#include <stdio.h>
#include <limits.h>
static GtkWidget* GTKWIDGET(void *pointer) {
return GTK_WIDGET(pointer);
}
static GtkWindow* GTKWINDOW(void *pointer) {
return GTK_WINDOW(pointer);
}
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;
}
if( height == 0 ) {
height = INT_MAX;
}
size.max_height = height;
size.max_width = width;
gtk_window_set_geometry_hints(window, NULL, &size, GDK_HINT_MAX_SIZE);
}
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*)
{
#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);
}
// 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*)
{
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);
}
*/
import "C"
import (
"github.com/wailsapp/wails/v2/pkg/options"
"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,
}
gtkWindow := C.gtk_window_new(C.GTK_WINDOW_TOPLEVEL)
C.g_object_ref_sink(C.gpointer(gtkWindow))
result.gtkWindow = unsafe.Pointer(gtkWindow)
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)
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))
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) asGTKWidget() *C.GtkWidget {
return C.GTKWIDGET(w.gtkWindow)
}
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() {
C.gtk_window_fullscreen(w.asGTKWindow())
}
func (w *Window) 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() {
C.gtk_window_close(w.asGTKWindow())
}
func (w *Window) Center() {
C.Center(w.asGTKWindow())
}
func (w *Window) SetPos(x int, y int) {
cX := C.int(x)
cY := C.int(y)
C.gtk_window_move(w.asGTKWindow(), cX, cY)
}
func (w *Window) Size() (int, int) {
var width, height C.int
C.gtk_window_get_size(w.asGTKWindow(), &width, &height)
return int(width), int(height)
}
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) {
C.SetMaxSize(w.asGTKWindow(), C.int(maxWidth), C.int(maxHeight))
}
func (w *Window) SetMinSize(minWidth int, minHeight int) {
C.SetMinSize(w.asGTKWindow(), C.int(minWidth), C.int(minHeight))
}
func (w *Window) Show() {
C.gtk_widget_show(w.asGTKWidget())
}
func (w *Window) Hide() {
C.gtk_widget_hide(w.asGTKWidget())
}
func (w *Window) Maximise() {
C.gtk_window_maximize(w.asGTKWindow())
}
func (w *Window) UnMaximise() {
C.gtk_window_unmaximize(w.asGTKWindow())
}
func (w *Window) Minimise() {
C.gtk_window_iconify(w.asGTKWindow())
}
func (w *Window) UnMinimise() {
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.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()
}

View File

@@ -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 {
@@ -130,10 +134,6 @@ func (f *Frontend) Run(ctx context.Context) error {
}
}()
if f.frontendOptions.Fullscreen {
mainWindow.Fullscreen()
}
mainWindow.Run()
mainWindow.Close()
return nil
@@ -172,11 +172,17 @@ func (f *Frontend) WindowFullscreen() {
runtime.LockOSThread()
f.mainWindow.SetMaxSize(0, 0)
f.mainWindow.SetMinSize(0, 0)
if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false {
f.ExecJS("window.wails.flags.enableResize = false;")
}
f.mainWindow.Fullscreen()
}
func (f *Frontend) WindowUnFullscreen() {
runtime.LockOSThread()
if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false {
f.ExecJS("window.wails.flags.enableResize = true;")
}
f.mainWindow.UnFullscreen()
f.mainWindow.SetMaxSize(f.maxWidth, f.maxHeight)
f.mainWindow.SetMinSize(f.minWidth, f.minHeight)
@@ -227,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()
@@ -255,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() {
@@ -329,33 +340,66 @@ 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{
"n-resize": w32.HTTOP,
"ne-resize": w32.HTTOPRIGHT,
"e-resize": w32.HTRIGHT,
"se-resize": w32.HTBOTTOMRIGHT,
"s-resize": w32.HTBOTTOM,
"sw-resize": w32.HTBOTTOMLEFT,
"w-resize": w32.HTLEFT,
"nw-resize": w32.HTTOPLEFT,
}
func (f *Frontend) processMessage(message string) {
@@ -368,27 +412,45 @@ 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 == "" {
if strings.HasPrefix(message, "resize:") {
if !f.mainWindow.IsFullScreen() {
sl := strings.Split(message, ":")
if len(sl) != 2 {
f.logger.Info("Unknown message returned from dispatcher: %+v", message)
return
}
edge := edgeMap[sl[1]]
err := f.startResize(edge)
if err != nil {
f.logger.Error(err.Error())
}
}
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) + `);`)
})
}
@@ -401,8 +463,16 @@ func (f *Frontend) startDrag() error {
return nil
}
func (f *Frontend) startResize(border uintptr) error {
if !w32.ReleaseCapture() {
return fmt.Errorf("unable to release mouse capture")
}
w32.SendMessage(f.mainWindow.Handle(), w32.WM_NCLBUTTONDOWN, border, 0)
return nil
}
func (f *Frontend) ExecJS(js string) {
f.mainWindow.Dispatch(func() {
f.mainWindow.Invoke(func() {
f.chromium.Eval(js)
})
}
@@ -412,10 +482,14 @@ func (f *Frontend) navigationCompleted(sender *edge.ICoreWebView2, args *edge.IC
go f.frontendOptions.OnDomReady(f.ctx)
}
// If you want to start hidden, return
if f.frontendOptions.StartHidden {
if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false {
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()
@@ -426,6 +500,24 @@ func (f *Frontend) navigationCompleted(sender *edge.ICoreWebView2, args *edge.IC
if err != nil {
log.Fatal(err)
}
f.mainWindow.Show()
if f.frontendOptions.StartHidden {
return
}
switch f.frontendOptions.WindowStartState {
case options.Maximised:
f.mainWindow.Maximise()
case options.Minimised:
f.mainWindow.Minimise()
case options.Fullscreen:
f.mainWindow.Fullscreen()
f.mainWindow.Show()
default:
if f.frontendOptions.Fullscreen {
f.mainWindow.Fullscreen()
}
f.mainWindow.Show()
}
}

View File

@@ -7,36 +7,36 @@ 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, options *options.App) *Window {
func NewWindow(parent winc.Controller, appoptions *options.App) *Window {
result := new(Window)
result.frontendOptions = options
result.frontendOptions = appoptions
result.SetIsForm(true)
var exStyle int
if options.Windows != nil {
if appoptions.Windows != nil {
exStyle = w32.WS_EX_CONTROLPARENT | w32.WS_EX_APPWINDOW
if options.Windows.WindowIsTranslucent {
if appoptions.Windows.WindowIsTranslucent {
exStyle |= w32.WS_EX_NOREDIRECTIONBITMAP
}
}
if options.AlwaysOnTop {
if appoptions.AlwaysOnTop {
exStyle |= w32.WS_EX_TOPMOST
}
var dwStyle = w32.WS_OVERLAPPEDWINDOW
if options.Frameless {
if appoptions.Frameless {
dwStyle = w32.WS_POPUP
if winoptions := appoptions.Windows; winoptions != nil && winoptions.EnableFramelessBorder {
dwStyle |= w32.WS_BORDER
}
}
winc.RegClassOnlyOnce("wailsWindow")
@@ -44,7 +44,7 @@ func NewWindow(parent winc.Controller, options *options.App) *Window {
result.SetParent(parent)
loadIcon := true
if options.Windows != nil && options.Windows.DisableWindowIcon == true {
if appoptions.Windows != nil && appoptions.Windows.DisableWindowIcon == true {
loadIcon = false
}
if loadIcon {
@@ -53,21 +53,21 @@ func NewWindow(parent winc.Controller, options *options.App) *Window {
}
}
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)
result.SetSize(appoptions.Width, appoptions.Height)
result.SetText(appoptions.Title)
if appoptions.Frameless == false && !appoptions.Fullscreen {
result.EnableMaxButton(!appoptions.DisableResize)
result.EnableSizable(!appoptions.DisableResize)
result.SetMinSize(appoptions.MinWidth, appoptions.MinHeight)
result.SetMaxSize(appoptions.MaxWidth, appoptions.MaxHeight)
}
if options.Windows != nil {
if options.Windows.WindowIsTranslucent {
if appoptions.Windows != nil {
if appoptions.Windows.WindowIsTranslucent {
result.SetTranslucentBackground()
}
if options.Windows.DisableWindowIcon {
if appoptions.Windows.DisableWindowIcon {
result.DisableIcon()
}
}
@@ -78,40 +78,13 @@ func NewWindow(parent winc.Controller, options *options.App) *Window {
result.SetFont(winc.DefaultFont)
if options.Menu != nil {
result.SetApplicationMenu(options.Menu)
if appoptions.Menu != nil {
result.SetApplicationMenu(appoptions.Menu)
}
return result
}
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()
}

View File

@@ -55,7 +55,7 @@ type MessageDialogOptions struct {
Buttons []string
DefaultButton string
CancelButton string
Icon string
Icon []byte
}
type Frontend interface {

View File

@@ -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);
}
})();

View File

@@ -43,6 +43,8 @@ window.wails = {
flags: {
disableScrollbarDrag: false,
disableWailsDefaultContextMenu: false,
enableResize: false,
defaultCursor: null
}
};
@@ -60,6 +62,15 @@ if (ENV === 0) {
// Setup drag handler
// Based on code from: https://github.com/patr0nus/DeskGap
window.addEventListener('mousedown', (e) => {
// Check for resizing
if (window.wails.flags.resizeEdge) {
window.WailsInvoke("resize:" + window.wails.flags.resizeEdge);
e.preventDefault();
return;
}
// Check for dragging
let currentElement = e.target;
while (currentElement != null) {
if (currentElement.hasAttribute('data-wails-no-drag')) {
@@ -79,6 +90,40 @@ window.addEventListener('mousedown', (e) => {
}
});
function setResize(cursor) {
document.body.style.cursor = cursor || window.wails.flags.defaultCursor;
window.wails.flags.resizeEdge = cursor;
}
window.addEventListener('mousemove', function (e) {
if (!window.wails.flags.enableResize) {
return;
}
if (window.wails.flags.defaultCursor == null) {
window.wails.flags.defaultCursor = document.body.style.cursor;
}
if (window.outerWidth - e.clientX < 16 && window.outerHeight - e.clientY < 16) {
document.body.style.cursor = "se-resize";
}
let rightBorder = window.outerWidth - e.clientX < 16;
let leftBorder = e.clientX < 16;
let topBorder = e.clientY < 16;
let bottomBorder = window.outerHeight - e.clientY < 16;
// If we aren't on an edge, but were, reset the cursor to default
if (!leftBorder && !rightBorder && !topBorder && !bottomBorder && window.wails.flags.resizeEdge !== undefined) {
setResize();
} else if (rightBorder && bottomBorder) setResize("se-resize");
else if (leftBorder && bottomBorder) setResize("sw-resize");
else if (leftBorder && topBorder) setResize("nw-resize");
else if (topBorder && rightBorder) setResize("ne-resize");
else if (leftBorder) setResize("w-resize");
else if (topBorder) setResize("n-resize");
else if (bottomBorder) setResize("s-resize");
else if (rightBorder) setResize("e-resize");
});
// Setup context menu hook
window.addEventListener('contextmenu', function (e) {
if (window.wails.flags.disableWailsDefaultContextMenu) {

View File

@@ -1,8 +1,812 @@
{
"name": "dev",
"version": "2.0.0",
"lockfileVersion": 1,
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "2.0.0",
"license": "ISC",
"devDependencies": {
"esbuild": "^0.12.17",
"esbuild-svelte": "^0.5.6",
"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.21",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.21.tgz",
"integrity": "sha512-7hyXbU3g94aREufI/5nls7Xcc+RGQeZWZApm6hoBaFvt2BPtpT4TjFMQ9Tb1jU8XyBGz00ShmiyflCogphMHFQ==",
"dev": true,
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
}
},
"node_modules/esbuild-svelte": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/esbuild-svelte/-/esbuild-svelte-0.5.6.tgz",
"integrity": "sha512-Bz8nU45FrT6sP/Tf3M2rQUuBGxnDSNSPZNIoYwSNt5H+wjSyo/t+zm94tgnOZsR6GgpDMbNQgo4jGbK0NLvEfw==",
"dev": true,
"dependencies": {
"svelte": "^3.42.6"
}
},
"node_modules/esbuild-svelte/node_modules/svelte": {
"version": "3.43.1",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.43.1.tgz",
"integrity": "sha512-nvPIaKx4HLzYlSdquISZpgG1Kqr2VAWQjZOt3Iwm3UhbqmA0LnSx4k1YpRMEhjQYW3ZCqQoK8Egto9tv4YewMA==",
"dev": true,
"engines": {
"node": ">= 8"
}
},
"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.8",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"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/has-tostringtag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
"dev": true,
"dependencies": {
"has-symbols": "^1.0.2"
},
"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.4",
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
"integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
"dev": true,
"dependencies": {
"has-bigints": "^1.0.1"
}
},
"node_modules/is-boolean-object": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
"integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/is-callable": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
"integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
},
"node_modules/is-core-module": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz",
"integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==",
"dev": true,
"dependencies": {
"has": "^1.0.3"
}
},
"node_modules/is-date-object": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
"dev": true,
"dependencies": {
"has-tostringtag": "^1.0.0"
},
"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.6",
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz",
"integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==",
"dev": true,
"dependencies": {
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/is-string": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
"integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
"dev": true,
"dependencies": {
"has-tostringtag": "^1.0.0"
},
"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.10",
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz",
"integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==",
"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.2",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.42.2.tgz",
"integrity": "sha512-FOyNYKXb8wdE0Ot+Ctt2/OyDLsNBP8+V6PUE9ag6ZKeLslIou0LnMu1fhtWUA+HjzKTbAM1yj+4PFLtg/3pMJA==",
"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",

View File

@@ -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"
}
}

View File

@@ -1,5 +1,3 @@
//go:build darwin || windows
package runtime
import _ "embed"

View File

@@ -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))})();})();

View File

@@ -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