mirror of
https://github.com/taigrr/wails.git
synced 2026-04-04 06:02:43 -07:00
Compare commits
58 Commits
243-multip
...
angular-fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
288feee1d9 | ||
|
|
416bd7bfc4 | ||
|
|
aca72d3f7a | ||
|
|
ad20e2622b | ||
|
|
daeda501f4 | ||
|
|
fb1e8647bc | ||
|
|
723236f348 | ||
|
|
394a823d82 | ||
|
|
afe57802ad | ||
|
|
914642bd1d | ||
|
|
dafd9bcb24 | ||
|
|
7f75f27f6b | ||
|
|
d77fa1ee74 | ||
|
|
82e00ff83a | ||
|
|
14f91ab109 | ||
|
|
19706a12a4 | ||
|
|
52e6091f0f | ||
|
|
2db1624faf | ||
|
|
f5d3fb0848 | ||
|
|
85a64914aa | ||
|
|
0819207e33 | ||
|
|
50a0bc7701 | ||
|
|
c51f0cad6f | ||
|
|
6795f6c678 | ||
|
|
315ef5f7ea | ||
|
|
24530d9da4 | ||
|
|
d572418ec3 | ||
|
|
8c7480d277 | ||
|
|
96fc70df26 | ||
|
|
1c8d4c902a | ||
|
|
08fc1d53d0 | ||
|
|
6c5d5e40f4 | ||
|
|
3f1dfe931c | ||
|
|
cb850c9653 | ||
|
|
8d8f47363a | ||
|
|
d399b7580d | ||
|
|
1b04b71254 | ||
|
|
0b19ad1427 | ||
|
|
9aca99911e | ||
|
|
a7f61e335e | ||
|
|
9fff0a513e | ||
|
|
f453be12c8 | ||
|
|
20428b0407 | ||
|
|
7fd5b77cbe | ||
|
|
d2cac50f93 | ||
|
|
00f1f82520 | ||
|
|
02fbb14e34 | ||
|
|
f961659ada | ||
|
|
93942111bc | ||
|
|
dc5a68acce | ||
|
|
12ff0f8c97 | ||
|
|
694f80434a | ||
|
|
099967ae94 | ||
|
|
718bb1b852 | ||
|
|
3d9e9a1342 | ||
|
|
1a82406d2b | ||
|
|
54b4b157b3 | ||
|
|
add7e89097 |
@@ -18,3 +18,6 @@ Wails is what it is because of the time and effort given by these great people.
|
|||||||
* [Florian Didran](https://github.com/fdidron)
|
* [Florian Didran](https://github.com/fdidron)
|
||||||
* [Nikolai Zimmermann](https://github.com/Chronophylos)
|
* [Nikolai Zimmermann](https://github.com/Chronophylos)
|
||||||
* [Toyam Cox](https://github.com/Vaelatern)
|
* [Toyam Cox](https://github.com/Vaelatern)
|
||||||
|
* [Robin Eklind](https://github.com/mewmew)
|
||||||
|
* [Kris Raney](https://github.com/kraney)
|
||||||
|
* [Jack Mordaunt](https://github.com/JackMordaunt)
|
||||||
|
|||||||
@@ -8,9 +8,10 @@
|
|||||||
<a href="http://godoc.org/github.com/wailsapp/wails"><img src="https://img.shields.io/badge/godoc-reference-blue.svg"/></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://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://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://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/avelino/awesome-go" rel="nofollow"><img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome"></a>
|
||||||
<a href="https://dashboard.guardrails.io/default/gh/wailsapp/wails"><img src="https://badges.guardrails.io/wailsapp/wails.svg?token=53657bc22ec360d7673c894fdd70568e918ec581d10d84427ed4de5fe1eeff1a"></a>
|
<a href="https://dev.azure.com/leaanthony/Wails/_build/latest?definitionId=1&branchName=master" rel="nofollow"><img src="https://dev.azure.com/leaanthony/Wails/_apis/build/status/wailsapp.wails?branchName=master" alt="Pipelines"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
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!
|
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!
|
||||||
@@ -60,7 +61,7 @@ _Also succesfully tested on: Zorin 15, Parrot 4.7, Linuxmint 19, Elementary 5, K
|
|||||||
|
|
||||||
`sudo pacman -S webkit2gtk gtk3`
|
`sudo pacman -S webkit2gtk gtk3`
|
||||||
|
|
||||||
_Also succesfully test on: ArcoLinuxB_
|
_Also succesfully test on: Manjaro & ArcoLinux_
|
||||||
|
|
||||||
#### Centos
|
#### Centos
|
||||||
|
|
||||||
@@ -143,3 +144,7 @@ This project was mainly coded to the following albums:
|
|||||||
* [Bloc Party - Silent Alarm](https://open.spotify.com/album/6SsIdN05HQg2GwYLfXuzLB)
|
* [Bloc Party - Silent Alarm](https://open.spotify.com/album/6SsIdN05HQg2GwYLfXuzLB)
|
||||||
* [Maxthor - Another World](https://open.spotify.com/album/3tklE2Fgw1hCIUstIwPBJF)
|
* [Maxthor - Another World](https://open.spotify.com/album/3tklE2Fgw1hCIUstIwPBJF)
|
||||||
* [Alun Tan Lan - Y Distawrwydd](https://open.spotify.com/album/0c32OywcLpdJCWWMC6vB8v)
|
* [Alun Tan Lan - Y Distawrwydd](https://open.spotify.com/album/0c32OywcLpdJCWWMC6vB8v)
|
||||||
|
|
||||||
|
## Licensing
|
||||||
|
|
||||||
|
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fwailsapp%2Fwails?ref=badge_large)
|
||||||
|
|||||||
60
app.go
60
app.go
@@ -1,6 +1,12 @@
|
|||||||
package wails
|
package wails
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/syossan27/tebata"
|
||||||
"github.com/wailsapp/wails/cmd"
|
"github.com/wailsapp/wails/cmd"
|
||||||
"github.com/wailsapp/wails/lib/binding"
|
"github.com/wailsapp/wails/lib/binding"
|
||||||
"github.com/wailsapp/wails/lib/event"
|
"github.com/wailsapp/wails/lib/event"
|
||||||
@@ -61,11 +67,31 @@ func CreateApp(optionalConfig ...*AppConfig) *App {
|
|||||||
result.config.DisableInspector = true
|
result.config.DisableInspector = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If running windows, do a hidpi fix
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
err := SetProcessDPIAware()
|
||||||
|
if err != nil {
|
||||||
|
result.log.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetProcessDPIAware via user32.dll
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setprocessdpiaware
|
||||||
|
// Also, thanks Jack Mordaunt! https://github.com/wailsapp/wails/issues/293
|
||||||
|
func SetProcessDPIAware() error {
|
||||||
|
status, r, err := syscall.NewLazyDLL("user32.dll").NewProc("SetProcessDPIAware").Call()
|
||||||
|
if status == 0 {
|
||||||
|
return fmt.Errorf("exit status %d: %v %v", status, r, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Run the app
|
// Run the app
|
||||||
func (a *App) Run() error {
|
func (a *App) Run() error {
|
||||||
|
|
||||||
if BuildMode != cmd.BuildModeProd {
|
if BuildMode != cmd.BuildModeProd {
|
||||||
return a.cli.Run()
|
return a.cli.Run()
|
||||||
}
|
}
|
||||||
@@ -97,6 +123,13 @@ func (a *App) start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start signal handler
|
||||||
|
t := tebata.New(os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL)
|
||||||
|
t.Reserve(func() {
|
||||||
|
a.log.Debug("SIGNAL CAUGHT! Starting Shutdown")
|
||||||
|
a.renderer.Close()
|
||||||
|
})
|
||||||
|
|
||||||
// Start event manager and give it our renderer
|
// Start event manager and give it our renderer
|
||||||
a.eventManager.Start(a.renderer)
|
a.eventManager.Start(a.renderer)
|
||||||
|
|
||||||
@@ -112,8 +145,33 @@ func (a *App) start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Defer the shutdown
|
||||||
|
defer a.shutdown()
|
||||||
|
|
||||||
// Run the renderer
|
// Run the renderer
|
||||||
return a.renderer.Run()
|
err = a.renderer.Run()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// shutdown the app
|
||||||
|
func (a *App) shutdown() {
|
||||||
|
// Make sure this is only called once
|
||||||
|
a.log.Debug("Shutting down")
|
||||||
|
|
||||||
|
// Shutdown Binding Manager
|
||||||
|
a.bindingManager.Shutdown()
|
||||||
|
|
||||||
|
// Shutdown IPC Manager
|
||||||
|
a.ipc.Shutdown()
|
||||||
|
|
||||||
|
// Shutdown Event Manager
|
||||||
|
a.eventManager.Shutdown()
|
||||||
|
|
||||||
|
a.log.Debug("Cleanly Shutdown")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind allows the user to bind the given object
|
// Bind allows the user to bind the given object
|
||||||
|
|||||||
138
azure-pipelines.yml
Normal file
138
azure-pipelines.yml
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
# avoid double trigger by applying some rules
|
||||||
|
# start a pipeline when push to 'master' branch
|
||||||
|
trigger:
|
||||||
|
- master
|
||||||
|
# or when pull request on 'develop' branch
|
||||||
|
pr:
|
||||||
|
- develop
|
||||||
|
|
||||||
|
# for now there is only one stage 'Build'
|
||||||
|
# in the future we could use multistage strategy for releases
|
||||||
|
stages:
|
||||||
|
- stage: Build
|
||||||
|
|
||||||
|
# there are 3 jobs
|
||||||
|
# one for each os
|
||||||
|
jobs:
|
||||||
|
- deployment: Linux
|
||||||
|
displayName: Lin
|
||||||
|
variables:
|
||||||
|
GOPATH: '$(Agent.BuildDirectory)/gopath' # Go workspace path
|
||||||
|
GOROOT: '$(Agent.BuildDirectory)/go' # Go installation path
|
||||||
|
GOBIN: '$(GOPATH)/bin' # Go binaries path
|
||||||
|
GOMODULE: 'on'
|
||||||
|
modulePath: '$(Agent.BuildDirectory)/wails' # Path to the module's code
|
||||||
|
pool:
|
||||||
|
vmImage: 'Ubuntu-16.04'
|
||||||
|
environment: 'linux-dev'
|
||||||
|
strategy:
|
||||||
|
runOnce:
|
||||||
|
deploy:
|
||||||
|
steps:
|
||||||
|
- checkout: self # self represents the repo where the initial Pipelines YAML file was found
|
||||||
|
clean: true # whether to fetch clean each time
|
||||||
|
path: wails # path to check out source code, relative to the agent's build directory (e.g. \_work\1)
|
||||||
|
# go version 1.12.7
|
||||||
|
- script: |
|
||||||
|
wget "https://storage.googleapis.com/golang/go1.12.7.linux-amd64.tar.gz" --output-document "$(Agent.BuildDirectory)/go1.12.7.tar.gz"
|
||||||
|
tar -C '$(Agent.BuildDirectory)' -xzf "$(Agent.BuildDirectory)/go1.12.7.tar.gz"
|
||||||
|
displayName: 'Install Go 1.12.7 Linux'
|
||||||
|
- script: |
|
||||||
|
mkdir -p '$(GOBIN)'
|
||||||
|
mkdir -p '$(GOPATH)/pkg'
|
||||||
|
mkdir -p '$(GOROOT)'
|
||||||
|
shopt -s extglob
|
||||||
|
shopt -s dotglob
|
||||||
|
echo '##vso[task.prependpath]$(GOBIN)'
|
||||||
|
echo '##vso[task.prependpath]$(GOROOT)/bin'
|
||||||
|
displayName: 'Set up the Go workspace'
|
||||||
|
- script: |
|
||||||
|
go version
|
||||||
|
go get -v -d ./...
|
||||||
|
cd cmd/wails
|
||||||
|
go install
|
||||||
|
workingDirectory: '$(modulePath)'
|
||||||
|
displayName: 'Get dependencies, then build'
|
||||||
|
- script: |
|
||||||
|
wails version
|
||||||
|
workingDirectory: '$(modulePath)'
|
||||||
|
displayName: 'Check we have output'
|
||||||
|
|
||||||
|
- deployment: Mac
|
||||||
|
displayName: Mac
|
||||||
|
variables:
|
||||||
|
GOPATH: '$(Agent.BuildDirectory)/gopath' # Go workspace path
|
||||||
|
GOROOT: '$(Agent.BuildDirectory)/go' # Go installation path
|
||||||
|
GOBIN: '$(GOPATH)/bin' # Go binaries path
|
||||||
|
GOMODULE: 'on'
|
||||||
|
modulePath: '$(Agent.BuildDirectory)/wails' # Path to the module's code
|
||||||
|
pool:
|
||||||
|
vmImage: 'macOS-10.14'
|
||||||
|
environment: 'mac-dev'
|
||||||
|
strategy:
|
||||||
|
runOnce:
|
||||||
|
deploy:
|
||||||
|
steps:
|
||||||
|
- checkout: self # self represents the repo where the initial Pipelines YAML file was found
|
||||||
|
clean: true # whether to fetch clean each time
|
||||||
|
path: wails # path to check out source code, relative to the agent's build directory (e.g. \_work\1)
|
||||||
|
# go version 1.12.7
|
||||||
|
- script: |
|
||||||
|
wget "https://storage.googleapis.com/golang/go1.12.7.darwin-amd64.tar.gz" --output-document "$(Agent.BuildDirectory)/go1.12.7.tar.gz"
|
||||||
|
tar -C '$(Agent.BuildDirectory)' -xzf "$(Agent.BuildDirectory)/go1.12.7.tar.gz"
|
||||||
|
displayName: 'Install Go 1.12.7 Linux'
|
||||||
|
- script: |
|
||||||
|
mkdir -p '$(GOBIN)'
|
||||||
|
mkdir -p '$(GOPATH)/pkg'
|
||||||
|
mkdir -p '$(GOROOT)'
|
||||||
|
shopt -s extglob
|
||||||
|
shopt -s dotglob
|
||||||
|
echo '##vso[task.prependpath]$(GOBIN)'
|
||||||
|
echo '##vso[task.prependpath]$(GOROOT)/bin'
|
||||||
|
displayName: 'Set up the Go workspace'
|
||||||
|
- script: |
|
||||||
|
go version
|
||||||
|
go get -v -d ./...
|
||||||
|
cd cmd/wails
|
||||||
|
go install
|
||||||
|
workingDirectory: '$(modulePath)'
|
||||||
|
displayName: 'Get dependencies, then build'
|
||||||
|
- script: |
|
||||||
|
wails version
|
||||||
|
workingDirectory: '$(modulePath)'
|
||||||
|
displayName: 'Check we have output'
|
||||||
|
|
||||||
|
- deployment: Win
|
||||||
|
displayName: Win
|
||||||
|
variables:
|
||||||
|
GOMODULE: 'on'
|
||||||
|
modulePath: '$(Agent.BuildDirectory)/wails' # Path to the module's code
|
||||||
|
pool:
|
||||||
|
vmImage: 'windows-2019'
|
||||||
|
environment: 'win-dev'
|
||||||
|
strategy:
|
||||||
|
runOnce:
|
||||||
|
deploy:
|
||||||
|
steps:
|
||||||
|
- checkout: self # self represents the repo where the initial Pipelines YAML file was found
|
||||||
|
clean: true # whether to fetch clean each time
|
||||||
|
path: wails # path to check out source code, relative to the agent's build directory (e.g. \_work\1)
|
||||||
|
# Go tool installer
|
||||||
|
# Find in cache or download a specific version of Go and add it to the PATH
|
||||||
|
- task: GoTool@0
|
||||||
|
inputs:
|
||||||
|
version: '1.12.7'
|
||||||
|
goPath: '$(Agent.BuildDirectory)/go'
|
||||||
|
goBin: '$(Agent.BuildDirectory)/go/bin'
|
||||||
|
displayName: 'Set up the Go workspace'
|
||||||
|
- script: |
|
||||||
|
go version
|
||||||
|
go get -v -d ./...
|
||||||
|
cd cmd/wails
|
||||||
|
go install
|
||||||
|
workingDirectory: '$(modulePath)'
|
||||||
|
displayName: 'Get dependencies, then build'
|
||||||
|
- script: |
|
||||||
|
wails version
|
||||||
|
workingDirectory: '$(Agent.BuildDirectory)/go/bin'
|
||||||
|
displayName: 'Check we have output'
|
||||||
File diff suppressed because one or more lines are too long
@@ -7,6 +7,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/leaanthony/mewn"
|
"github.com/leaanthony/mewn"
|
||||||
@@ -87,6 +88,17 @@ func BuildApplication(binaryName string, forceRebuild bool, buildMode string, pa
|
|||||||
buildCommand.Add("build")
|
buildCommand.Add("build")
|
||||||
|
|
||||||
if binaryName != "" {
|
if binaryName != "" {
|
||||||
|
// Alter binary name based on OS
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "windows":
|
||||||
|
if !strings.HasSuffix(binaryName, ".exe") {
|
||||||
|
binaryName += ".exe"
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if strings.HasSuffix(binaryName, ".exe") {
|
||||||
|
binaryName = strings.TrimSuffix(binaryName, ".exe")
|
||||||
|
}
|
||||||
|
}
|
||||||
buildCommand.Add("-o")
|
buildCommand.Add("-o")
|
||||||
buildCommand.Add(binaryName)
|
buildCommand.Add(binaryName)
|
||||||
}
|
}
|
||||||
@@ -103,7 +115,7 @@ func BuildApplication(binaryName string, forceRebuild bool, buildMode string, pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add windows flags
|
// Add windows flags
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" && buildMode == BuildModeProd {
|
||||||
ldflags += "-H windowsgui "
|
ldflags += "-H windowsgui "
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,6 +231,15 @@ func InstallFrontendDeps(projectDir string, projectOptions *ProjectOptions, forc
|
|||||||
|
|
||||||
const md5sumFile = "package.json.md5"
|
const md5sumFile = "package.json.md5"
|
||||||
|
|
||||||
|
// If node_modules does not exist, force a rebuild.
|
||||||
|
nodeModulesPath, err := filepath.Abs(filepath.Join(".", "node_modules"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !fs.DirExists(nodeModulesPath) {
|
||||||
|
forceRebuild = true
|
||||||
|
}
|
||||||
|
|
||||||
// If we aren't forcing the install and the md5sum file exists
|
// If we aren't forcing the install and the md5sum file exists
|
||||||
if !forceRebuild && fs.FileExists(md5sumFile) {
|
if !forceRebuild && fs.FileExists(md5sumFile) {
|
||||||
// Yes - read contents
|
// Yes - read contents
|
||||||
@@ -275,7 +296,7 @@ func InstallRuntime(caller string, projectDir string, projectOptions *ProjectOpt
|
|||||||
// InstallBridge installs the relevant bridge javascript library
|
// InstallBridge installs the relevant bridge javascript library
|
||||||
func InstallBridge(projectDir string, projectOptions *ProjectOptions) error {
|
func InstallBridge(projectDir string, projectOptions *ProjectOptions) error {
|
||||||
bridgeFileData := mewn.String("../runtime/assets/bridge.js")
|
bridgeFileData := mewn.String("../runtime/assets/bridge.js")
|
||||||
bridgeFileTarget := filepath.Join(projectDir, projectOptions.FrontEnd.Dir, "node_modules", "@wailsapp", "runtime", "main.js")
|
bridgeFileTarget := filepath.Join(projectDir, projectOptions.FrontEnd.Dir, "node_modules", "@wailsapp", "runtime", "init.js")
|
||||||
err := fs.CreateFile(bridgeFileTarget, []byte(bridgeFileData))
|
err := fs.CreateFile(bridgeFileTarget, []byte(bridgeFileData))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -283,7 +304,7 @@ func InstallBridge(projectDir string, projectOptions *ProjectOptions) error {
|
|||||||
// InstallProdRuntime installs the production runtime
|
// InstallProdRuntime installs the production runtime
|
||||||
func InstallProdRuntime(projectDir string, projectOptions *ProjectOptions) error {
|
func InstallProdRuntime(projectDir string, projectOptions *ProjectOptions) error {
|
||||||
prodInit := mewn.String("../runtime/js/runtime/init.js")
|
prodInit := mewn.String("../runtime/js/runtime/init.js")
|
||||||
bridgeFileTarget := filepath.Join(projectDir, projectOptions.FrontEnd.Dir, "node_modules", "@wailsapp", "runtime", "main.js")
|
bridgeFileTarget := filepath.Join(projectDir, projectOptions.FrontEnd.Dir, "node_modules", "@wailsapp", "runtime", "init.js")
|
||||||
err := fs.CreateFile(bridgeFileTarget, []byte(prodInit))
|
err := fs.CreateFile(bridgeFileTarget, []byte(prodInit))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ const (
|
|||||||
Kali
|
Kali
|
||||||
// Neon distribution
|
// Neon distribution
|
||||||
Neon
|
Neon
|
||||||
|
// Manjaro distribution
|
||||||
|
Manjaro
|
||||||
)
|
)
|
||||||
|
|
||||||
// DistroInfo contains all the information relating to a linux distribution
|
// DistroInfo contains all the information relating to a linux distribution
|
||||||
@@ -126,6 +128,8 @@ func parseOsRelease(osRelease string) *DistroInfo {
|
|||||||
result.Distribution = Kali
|
result.Distribution = Kali
|
||||||
case "neon":
|
case "neon":
|
||||||
result.Distribution = Neon
|
result.Distribution = Neon
|
||||||
|
case "manjaro":
|
||||||
|
result.Distribution = Manjaro
|
||||||
default:
|
default:
|
||||||
result.Distribution = Unknown
|
result.Distribution = Unknown
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,18 +146,27 @@ distributions:
|
|||||||
version: default
|
version: default
|
||||||
name: Arch Linux
|
name: Arch Linux
|
||||||
gccversioncommand: *gccdumpversion
|
gccversioncommand: *gccdumpversion
|
||||||
programs:
|
programs: &archdefaultprograms
|
||||||
- name: gcc
|
- name: gcc
|
||||||
help: Please install with `sudo pacman -S gcc` and try again
|
help: Please install with `sudo pacman -S gcc` and try again
|
||||||
- name: pkgconf
|
- name: pkgconf
|
||||||
help: Please install with `sudo pacman -S pkgconf` and try again
|
help: Please install with `sudo pacman -S pkgconf` and try again
|
||||||
- name: npm
|
- name: npm
|
||||||
help: Please install with `sudo pacman -S npm` and try again
|
help: Please install with `sudo pacman -S npm` and try again
|
||||||
libraries:
|
libraries: &archdefaultlibraries
|
||||||
- name: gtk3
|
- name: gtk3
|
||||||
help: Please install with `sudo pacman -S gtk3` and try again
|
help: Please install with `sudo pacman -S gtk3` and try again
|
||||||
- name: webkit2gtk
|
- name: webkit2gtk
|
||||||
help: Please install with `sudo pacman -S webkit2gtk` and try again
|
help: Please install with `sudo pacman -S webkit2gtk` and try again
|
||||||
|
manjaro:
|
||||||
|
id: manjaro
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Manjaro Linux
|
||||||
|
gccversioncommand: *gccdumpversion
|
||||||
|
programs: *archdefaultprograms
|
||||||
|
libraries: *archdefaultlibraries
|
||||||
gentoo:
|
gentoo:
|
||||||
id: gentoo
|
id: gentoo
|
||||||
releases:
|
releases:
|
||||||
|
|||||||
@@ -191,8 +191,15 @@ func (b *PackageHelper) PackageWindows(po *ProjectOptions, cleanUp bool) error {
|
|||||||
|
|
||||||
// Build syso
|
// Build syso
|
||||||
sysofile := filepath.Join(b.fs.Cwd(), basename+"-res.syso")
|
sysofile := filepath.Join(b.fs.Cwd(), basename+"-res.syso")
|
||||||
windresCommand := []string{"windres", "-o", sysofile, tgtRCFile}
|
|
||||||
err := NewProgramHelper().RunCommandArray(windresCommand)
|
batfile, err := fs.LocalDir(".")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
windresBatFile := filepath.Join(batfile.fullPath, "windres.bat")
|
||||||
|
windresCommand := []string{windresBatFile, sysofile, tgtRCFile}
|
||||||
|
err = NewProgramHelper().RunCommandArray(windresCommand)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,6 +100,19 @@ func (p *ProgramHelper) InstallGoPackage(packageName string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InstallNPMPackage installs the given npm package
|
||||||
|
func (p *ProgramHelper) InstallNPMPackage(packageName string, save bool) error {
|
||||||
|
args := strings.Split("install "+packageName, " ")
|
||||||
|
if save {
|
||||||
|
args = append(args, "--save")
|
||||||
|
}
|
||||||
|
_, stderr, err := p.shell.Run("npm", args...)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(stderr)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// RunCommand runs the given command
|
// RunCommand runs the given command
|
||||||
func (p *ProgramHelper) RunCommand(command string) error {
|
func (p *ProgramHelper) RunCommand(command string) error {
|
||||||
args := strings.Split(command, " ")
|
args := strings.Split(command, " ")
|
||||||
@@ -115,6 +128,7 @@ func (p *ProgramHelper) RunCommandArray(args []string, dir ...string) error {
|
|||||||
fmt.Printf("ERROR: Looks like '%s' isn't installed. Please install and try again.", program)
|
fmt.Printf("ERROR: Looks like '%s' isn't installed. Please install and try again.", program)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
var stderr string
|
var stderr string
|
||||||
var stdout string
|
var stdout string
|
||||||
|
|||||||
@@ -13,6 +13,18 @@ import (
|
|||||||
"github.com/leaanthony/slicer"
|
"github.com/leaanthony/slicer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PackageManager indicates different package managers
|
||||||
|
type PackageManager int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// UNKNOWN package manager
|
||||||
|
UNKNOWN PackageManager = iota
|
||||||
|
// NPM package manager
|
||||||
|
NPM
|
||||||
|
// YARN package manager
|
||||||
|
YARN
|
||||||
|
)
|
||||||
|
|
||||||
type author struct {
|
type author struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
@@ -153,6 +165,23 @@ func (po *ProjectOptions) Defaults() {
|
|||||||
po.WailsVersion = Version
|
po.WailsVersion = Version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetNPMBinaryName returns the type of package manager used by the project
|
||||||
|
func (po *ProjectOptions) GetNPMBinaryName() (PackageManager, error) {
|
||||||
|
if po.FrontEnd == nil {
|
||||||
|
return UNKNOWN, fmt.Errorf("No frontend specified in project options")
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Index(po.FrontEnd.Install, "npm") > -1 {
|
||||||
|
return NPM, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Index(po.FrontEnd.Install, "yarn") > -1 {
|
||||||
|
return YARN, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNKNOWN, nil
|
||||||
|
}
|
||||||
|
|
||||||
// PromptForInputs asks the user to input project details
|
// PromptForInputs asks the user to input project details
|
||||||
func (po *ProjectOptions) PromptForInputs() error {
|
func (po *ProjectOptions) PromptForInputs() error {
|
||||||
|
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ func CheckDependencies(logger *Logger) (bool, error) {
|
|||||||
switch distroInfo.Distribution {
|
switch distroInfo.Distribution {
|
||||||
case Ubuntu, Debian, Zorin, Parrot, Linuxmint, Elementary, Kali, Neon:
|
case Ubuntu, Debian, Zorin, Parrot, Linuxmint, Elementary, Kali, Neon:
|
||||||
libraryChecker = DpkgInstalled
|
libraryChecker = DpkgInstalled
|
||||||
case Arch:
|
case Arch, Manjaro:
|
||||||
libraryChecker = PacmanInstalled
|
libraryChecker = PacmanInstalled
|
||||||
case CentOS, Fedora:
|
case CentOS, Fedora:
|
||||||
libraryChecker = RpmInstalled
|
libraryChecker = RpmInstalled
|
||||||
|
|||||||
@@ -9,4 +9,4 @@
|
|||||||
last 2 versions
|
last 2 versions
|
||||||
Firefox ESR
|
Firefox ESR
|
||||||
not dead
|
not dead
|
||||||
not IE 9-11 # For IE 9-11 support, remove 'not'.
|
IE 9-11 # For IE 9-11 support, remove 'not'.
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
"@angular/platform-browser-dynamic": "~8.0.1",
|
"@angular/platform-browser-dynamic": "~8.0.1",
|
||||||
"@angular/router": "~8.0.1",
|
"@angular/router": "~8.0.1",
|
||||||
"@wailsapp/runtime": "^1.0.0",
|
"@wailsapp/runtime": "^1.0.0",
|
||||||
|
"core-js": "^3.4.4",
|
||||||
"ngx-build-plus": "^8.0.3",
|
"ngx-build-plus": "^8.0.3",
|
||||||
"rxjs": "~6.4.0",
|
"rxjs": "~6.4.0",
|
||||||
"tslib": "^1.9.0",
|
"tslib": "^1.9.0",
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'core-js/stable';
|
||||||
import { enableProdMode } from '@angular/core';
|
import { enableProdMode } from '@angular/core';
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
@@ -6,7 +7,7 @@ import { environment } from './environments/environment';
|
|||||||
|
|
||||||
import 'zone.js'
|
import 'zone.js'
|
||||||
|
|
||||||
import Wails from '@wailsapp/runtime';
|
import * as Wails from '@wailsapp/runtime';
|
||||||
|
|
||||||
if (environment.production) {
|
if (environment.production) {
|
||||||
enableProdMode();
|
enableProdMode();
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
Wails Bridge (c) 2019-present Lea Anthony
|
|
||||||
|
|
||||||
This prod version is to get around having to rewrite your code
|
|
||||||
for production. When doing a release build, this file will be used
|
|
||||||
instead of the full version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default {
|
|
||||||
// The main function
|
|
||||||
// Passes the main Wails object to the callback if given.
|
|
||||||
Start: function(callback) {
|
|
||||||
if (callback) {
|
|
||||||
window.wails.events.on("wails:ready", callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"importHelpers": true,
|
"importHelpers": true,
|
||||||
"target": "es2015",
|
"target": "es5",
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
"node_modules/@types"
|
"node_modules/@types"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ func basic() string {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
js := mewn.String("./frontend/dist/my-app/main-es2015.js")
|
js := mewn.String("./frontend/dist/my-app/main.js")
|
||||||
css := mewn.String("./frontend/dist/my-app/styles.css")
|
css := mewn.String("./frontend/dist/my-app/styles.css")
|
||||||
|
|
||||||
app := wails.CreateApp(&wails.AppConfig{
|
app := wails.CreateApp(&wails.AppConfig{
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import 'core-js/stable';
|
|||||||
import './index.css';
|
import './index.css';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
|
|
||||||
import Wails from '@wailsapp/runtime';
|
import * as Wails from '@wailsapp/runtime';
|
||||||
|
|
||||||
Wails.Init(() => {
|
Wails.Init(() => {
|
||||||
ReactDOM.render(<App />, document.getElementById('app'));
|
ReactDOM.render(<App />, document.getElementById('app'));
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
Wails Bridge (c) 2019-present Lea Anthony
|
|
||||||
|
|
||||||
This prod version is to get around having to rewrite your code
|
|
||||||
for production. When doing a release build, this file will be used
|
|
||||||
instead of the full version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default {
|
|
||||||
// The main function
|
|
||||||
// Passes the main Wails object to the callback if given.
|
|
||||||
Start: function (callback) {
|
|
||||||
if (callback) {
|
|
||||||
window.wails.Events.On("wails:ready", callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -4,7 +4,7 @@ import App from './App.vue';
|
|||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
Vue.config.devtools = true;
|
Vue.config.devtools = true;
|
||||||
|
|
||||||
import Wails from '@wailsapp/runtime';
|
import * as Wails from '@wailsapp/runtime';
|
||||||
|
|
||||||
Wails.Init(() => {
|
Wails.Init(() => {
|
||||||
new Vue({
|
new Vue({
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import App from './App.vue';
|
|||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
Vue.config.devtools = true;
|
Vue.config.devtools = true;
|
||||||
|
|
||||||
import Wails from '@wailsapp/runtime';
|
import * as Wails from '@wailsapp/runtime';
|
||||||
|
|
||||||
Wails.Init(() => {
|
Wails.Init(() => {
|
||||||
new Vue({
|
new Vue({
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
// Version - Wails version
|
// Version - Wails version
|
||||||
const Version = "v0.17.15-pre"
|
const Version = "v0.19.0"
|
||||||
|
|||||||
408
cmd/wails/15_migrate.go
Normal file
408
cmd/wails/15_migrate.go
Normal file
@@ -0,0 +1,408 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Masterminds/semver"
|
||||||
|
"github.com/leaanthony/spinner"
|
||||||
|
"github.com/wailsapp/wails/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
var checkSpinner = spinner.NewSpinner()
|
||||||
|
var migrateProjectOptions = &cmd.ProjectOptions{}
|
||||||
|
var migrateFS = cmd.NewFSHelper()
|
||||||
|
var migrateGithub = cmd.NewGitHubHelper()
|
||||||
|
var programHelper = cmd.NewProgramHelper()
|
||||||
|
var lessThanV1 *semver.Constraints
|
||||||
|
|
||||||
|
// The user's go.mod
|
||||||
|
var goMod string
|
||||||
|
var goModFile string
|
||||||
|
|
||||||
|
// The user's main.js
|
||||||
|
var mainJSFile string
|
||||||
|
var mainJSContents string
|
||||||
|
|
||||||
|
// Frontend directory
|
||||||
|
var frontEndDir string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
var dryrun bool
|
||||||
|
var err error
|
||||||
|
|
||||||
|
lessThanV1, err = semver.NewConstraint("< v1.0.0")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// var forceRebuild = false
|
||||||
|
checkSpinner.SetSpinSpeed(50)
|
||||||
|
|
||||||
|
commandDescription := `EXPERIMENTAL - This command attempts to migrate projects to the latest Wails version.`
|
||||||
|
updateCmd := app.Command("migrate", "Migrate projects to latest Wails release").
|
||||||
|
LongDescription(commandDescription).
|
||||||
|
BoolFlag("dryrun", "Only display what would be done", &dryrun)
|
||||||
|
|
||||||
|
updateCmd.Action(func() error {
|
||||||
|
|
||||||
|
message := "Migrate Project"
|
||||||
|
logger.PrintSmallBanner(message)
|
||||||
|
logger.Red("WARNING: This is an experimental command. Ensure you have backups of your project!")
|
||||||
|
logger.Red("It currently only supports npm based projects.")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Check project directory
|
||||||
|
err := checkProjectDirectory()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find Wails version from go.mod
|
||||||
|
wailsVersion, err := getWailsVersion()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get latest stable version
|
||||||
|
var latestVersion *semver.Version
|
||||||
|
latestVersion, err = getLatestWailsVersion()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var canMigrate bool
|
||||||
|
canMigrate, err = canMigrateVersion(wailsVersion, latestVersion)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !canMigrate {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for wailsbridge
|
||||||
|
wailsBridge, err := checkWailsBridge()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is main.js using bridge.Init()
|
||||||
|
canUpdateMainJS, err := checkMainJS()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Check if we are using legacy js runtime
|
||||||
|
|
||||||
|
// Operations
|
||||||
|
logger.Yellow("Operations to perform:")
|
||||||
|
|
||||||
|
logger.Yellowf(" - Update to Wails v%s\n", latestVersion)
|
||||||
|
|
||||||
|
if len(wailsBridge) > 0 {
|
||||||
|
logger.Yellow(" - Delete wailsbridge.js")
|
||||||
|
}
|
||||||
|
|
||||||
|
if canUpdateMainJS {
|
||||||
|
logger.Yellow(" - Patch main.js")
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Yellow(" - Ensure '@wailsapp/runtime` module is installed")
|
||||||
|
|
||||||
|
if dryrun {
|
||||||
|
logger.White("Exiting: Dry Run")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Red("*WARNING* About to modify your project!")
|
||||||
|
logger.Red("Type 'YES' to continue: ")
|
||||||
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
|
scanner.Scan()
|
||||||
|
input := scanner.Text()
|
||||||
|
if input != "YES" {
|
||||||
|
logger.Red("ABORTED!")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Yellow("Let's do this!")
|
||||||
|
|
||||||
|
err = updateWailsVersion(wailsVersion, latestVersion)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(wailsBridge) > 0 {
|
||||||
|
err = deleteWailsBridge(wailsBridge)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if canUpdateMainJS {
|
||||||
|
err = patchMainJS()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install runtime
|
||||||
|
err = installWailsRuntime()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
logger.Yellow("Migration complete! Check project by running `wails build`.")
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkProjectDirectory() error {
|
||||||
|
// Get versions
|
||||||
|
checkSpinner.Start("Check Project Directory")
|
||||||
|
|
||||||
|
// Check we are in project directory
|
||||||
|
err := migrateProjectOptions.LoadConfig(migrateFS.Cwd())
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error()
|
||||||
|
return fmt.Errorf("Unable to find 'project.json'. Please check you are in a Wails project directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSpinner.Success()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getWailsVersion() (*semver.Version, error) {
|
||||||
|
checkSpinner.Start("Get Wails Version")
|
||||||
|
var result *semver.Version
|
||||||
|
|
||||||
|
// Load file
|
||||||
|
var err error
|
||||||
|
goModFile, err = filepath.Abs(filepath.Join(".", "go.mod"))
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error()
|
||||||
|
return nil, fmt.Errorf("Unable to load go.mod at %s", goModFile)
|
||||||
|
}
|
||||||
|
goMod, err = migrateFS.LoadAsString(goModFile)
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error()
|
||||||
|
return nil, fmt.Errorf("Unable to load go.mod")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find wails version
|
||||||
|
versionRegexp := regexp.MustCompile(`.*github.com/wailsapp/wails.*(v\d+.\d+.\d+)`)
|
||||||
|
versions := versionRegexp.FindStringSubmatch(goMod)
|
||||||
|
|
||||||
|
if len(versions) != 2 {
|
||||||
|
return nil, fmt.Errorf("Unable to determine Wails version")
|
||||||
|
}
|
||||||
|
|
||||||
|
version := versions[1]
|
||||||
|
result, err = semver.NewVersion(version)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to parse Wails version: %s", version)
|
||||||
|
}
|
||||||
|
checkSpinner.Success("Found Wails Version: " + version)
|
||||||
|
return result, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func canMigrateVersion(wailsVersion *semver.Version, latestVersion *semver.Version) (bool, error) {
|
||||||
|
checkSpinner.Start("Checking ability to Migrate")
|
||||||
|
|
||||||
|
// Check if we are at the latest version!!!!
|
||||||
|
if wailsVersion.Equal(latestVersion) || wailsVersion.GreaterThan(latestVersion) {
|
||||||
|
checkSpinner.Errorf("Checking ability to Migrate: No! (v%s >= v%s)", wailsVersion, latestVersion)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for < v1.0.0
|
||||||
|
if lessThanV1.Check(wailsVersion) {
|
||||||
|
checkSpinner.Successf("Checking ability to Migrate: Yes! (v%s < v1.0.0)", wailsVersion)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
checkSpinner.Error("Unable to migrate")
|
||||||
|
return false, fmt.Errorf("No migration rules for version %s", wailsVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkWailsBridge() (string, error) {
|
||||||
|
checkSpinner.Start("Checking if legacy Wails Bridge present")
|
||||||
|
|
||||||
|
// Check frontend dir is available
|
||||||
|
if migrateProjectOptions.FrontEnd == nil ||
|
||||||
|
len(migrateProjectOptions.FrontEnd.Dir) == 0 ||
|
||||||
|
!migrateFS.DirExists(migrateProjectOptions.FrontEnd.Dir) {
|
||||||
|
checkSpinner.Error("Unable to determine frontend directory")
|
||||||
|
return "", fmt.Errorf("Unable to determine frontend directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
frontEndDir = migrateProjectOptions.FrontEnd.Dir
|
||||||
|
|
||||||
|
wailsBridgePath, err := filepath.Abs(filepath.Join(".", frontEndDir, "src", "wailsbridge.js"))
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error(err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it doesn't exist, return blank string
|
||||||
|
if !migrateFS.FileExists(wailsBridgePath) {
|
||||||
|
checkSpinner.Success("Checking if legacy Wails Bridge present: No")
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSpinner.Success("Checking if legacy Wails Bridge present: Yes")
|
||||||
|
return wailsBridgePath, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function determines if the main.js file using wailsbridge can be auto-updated
|
||||||
|
func checkMainJS() (bool, error) {
|
||||||
|
|
||||||
|
checkSpinner.Start("Checking if main.js can be migrated")
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Check main.js is there
|
||||||
|
if migrateProjectOptions.FrontEnd == nil ||
|
||||||
|
len(migrateProjectOptions.FrontEnd.Dir) == 0 ||
|
||||||
|
!migrateFS.DirExists(migrateProjectOptions.FrontEnd.Dir) {
|
||||||
|
checkSpinner.Error("Unable to determine frontend directory")
|
||||||
|
return false, fmt.Errorf("Unable to determine frontend directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
frontEndDir = migrateProjectOptions.FrontEnd.Dir
|
||||||
|
|
||||||
|
mainJSFile, err = filepath.Abs(filepath.Join(".", frontEndDir, "src", "main.js"))
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error("Unable to find main.js")
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mainJSContents, err = migrateFS.LoadAsString(mainJSFile)
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error("Unable to load main.js")
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check we have a line like: import Bridge from "./wailsbridge";
|
||||||
|
if strings.Index(mainJSContents, `import Bridge from "./wailsbridge";`) == -1 {
|
||||||
|
checkSpinner.Success("Checking if main.js can be migrated: No - Cannot find `import Bridge`")
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check we have a line like: Bridge.Start(() => {
|
||||||
|
if strings.Index(mainJSContents, `Bridge.Start(`) == -1 {
|
||||||
|
checkSpinner.Success("Checking if main.js can be migrated: No - Cannot find `Bridge.Start`")
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
checkSpinner.Success("Checking if main.js can be migrated: Yes")
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLatestWailsVersion() (*semver.Version, error) {
|
||||||
|
checkSpinner.Start("Checking GitHub for latest Wails version")
|
||||||
|
version, err := migrateGithub.GetLatestStableRelease()
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error("Checking GitHub for latest Wails version: Failed")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSpinner.Successf("Checking GitHub for latest Wails version: v%s", version)
|
||||||
|
return version.Version, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateWailsVersion(currentVersion, latestVersion *semver.Version) error {
|
||||||
|
// Patch go.mod
|
||||||
|
checkSpinner.Start("Patching go.mod")
|
||||||
|
|
||||||
|
wailsModule := "github.com/wailsapp/wails"
|
||||||
|
old := fmt.Sprintf("%s v%s", wailsModule, currentVersion)
|
||||||
|
new := fmt.Sprintf("%s v%s", wailsModule, latestVersion)
|
||||||
|
|
||||||
|
goMod = strings.Replace(goMod, old, new, -1)
|
||||||
|
err := ioutil.WriteFile(goModFile, []byte(goMod), 0600)
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSpinner.Success()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteWailsBridge(bridgeFilename string) error {
|
||||||
|
// Patch go.mod
|
||||||
|
checkSpinner.Start("Delete legacy wailsbridge.js")
|
||||||
|
|
||||||
|
err := migrateFS.RemoveFile(bridgeFilename)
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSpinner.Success()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func patchMainJS() error {
|
||||||
|
// Patch main.js
|
||||||
|
checkSpinner.Start("Patching main.js")
|
||||||
|
|
||||||
|
// Patch import line
|
||||||
|
oldImportLine := `import Bridge from "./wailsbridge";`
|
||||||
|
newImportLine := `import * as Wails from "@wailsapp/runtime";`
|
||||||
|
mainJSContents = strings.Replace(mainJSContents, oldImportLine, newImportLine, -1)
|
||||||
|
|
||||||
|
// Patch Start line
|
||||||
|
oldStartLine := `Bridge.Start`
|
||||||
|
newStartLine := `Wails.Init`
|
||||||
|
mainJSContents = strings.Replace(mainJSContents, oldStartLine, newStartLine, -1)
|
||||||
|
|
||||||
|
err := ioutil.WriteFile(mainJSFile, []byte(mainJSContents), 0600)
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSpinner.Success()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func installWailsRuntime() error {
|
||||||
|
|
||||||
|
checkSpinner.Start("Installing @wailsapp/runtime module")
|
||||||
|
|
||||||
|
// Change to the frontend directory
|
||||||
|
err := os.Chdir(frontEndDir)
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine package manager
|
||||||
|
packageManager, err := migrateProjectOptions.GetNPMBinaryName()
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch packageManager {
|
||||||
|
case cmd.NPM:
|
||||||
|
// npm install --save @wailsapp/runtime
|
||||||
|
programHelper.InstallNPMPackage("@wailsapp/runtime", true)
|
||||||
|
default:
|
||||||
|
checkSpinner.Error()
|
||||||
|
return fmt.Errorf("Unknown package manager")
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSpinner.Success()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -80,15 +80,16 @@ To help you in this process, we will ask for some information, add Go/Wails deta
|
|||||||
npm := program.FindProgram("npm")
|
npm := program.FindProgram("npm")
|
||||||
if npm != nil {
|
if npm != nil {
|
||||||
stdout, _, _, _ := npm.Run("--version")
|
stdout, _, _, _ := npm.Run("--version")
|
||||||
nodeVersion = stdout
|
npmVersion = stdout
|
||||||
nodeVersion = nodeVersion[:len(nodeVersion)-1]
|
npmVersion = npmVersion[:len(npmVersion)-1]
|
||||||
|
npmVersion = strings.TrimSpace(npmVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
node := program.FindProgram("node")
|
node := program.FindProgram("node")
|
||||||
if node != nil {
|
if node != nil {
|
||||||
stdout, _, _, _ := node.Run("--version")
|
stdout, _, _, _ := node.Run("--version")
|
||||||
npmVersion = stdout
|
nodeVersion = stdout
|
||||||
npmVersion = npmVersion[:len(npmVersion)-1]
|
nodeVersion = nodeVersion[:len(nodeVersion)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
str.WriteString("\n| Name | Value |\n| ----- | ----- |\n")
|
str.WriteString("\n| Name | Value |\n| ----- | ----- |\n")
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/cmd"
|
"github.com/wailsapp/wails/cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,5 +18,9 @@ func main() {
|
|||||||
err := app.Run()
|
err := app.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err.Error())
|
logger.Error(err.Error())
|
||||||
|
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||||
|
os.Exit(exitErr.ExitCode())
|
||||||
|
}
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
cmd/windres.bat
Normal file
1
cmd/windres.bat
Normal file
@@ -0,0 +1 @@
|
|||||||
|
windres.exe -o %1 %2
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
package wails
|
package wails
|
||||||
|
|
||||||
import "github.com/leaanthony/mewn"
|
import (
|
||||||
|
"github.com/leaanthony/mewn"
|
||||||
|
"github.com/wailsapp/wails/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
// AppConfig is the configuration structure used when creating a Wails App object
|
// AppConfig is the configuration structure used when creating a Wails App object
|
||||||
type AppConfig struct {
|
type AppConfig struct {
|
||||||
@@ -65,7 +68,7 @@ func (a *AppConfig) merge(in *AppConfig) error {
|
|||||||
a.CSS = in.CSS
|
a.CSS = in.CSS
|
||||||
}
|
}
|
||||||
if in.Title != "" {
|
if in.Title != "" {
|
||||||
a.Title = in.Title
|
a.Title = runtime.ProcessEncoding(in.Title)
|
||||||
}
|
}
|
||||||
|
|
||||||
if in.Colour != "" {
|
if in.Colour != "" {
|
||||||
|
|||||||
3
go.mod
3
go.mod
@@ -2,6 +2,7 @@ module github.com/wailsapp/wails
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Masterminds/semver v1.4.2
|
github.com/Masterminds/semver v1.4.2
|
||||||
|
github.com/abadojack/whatlanggo v1.0.1
|
||||||
github.com/dchest/cssmin v0.0.0-20151210170030-fb8d9b44afdc // indirect
|
github.com/dchest/cssmin v0.0.0-20151210170030-fb8d9b44afdc // indirect
|
||||||
github.com/dchest/htmlmin v0.0.0-20150526090704-e254725e81ac
|
github.com/dchest/htmlmin v0.0.0-20150526090704-e254725e81ac
|
||||||
github.com/dchest/jsmin v0.0.0-20160823214000-faeced883947 // indirect
|
github.com/dchest/jsmin v0.0.0-20160823214000-faeced883947 // indirect
|
||||||
@@ -22,9 +23,11 @@ require (
|
|||||||
github.com/pkg/errors v0.8.1 // indirect
|
github.com/pkg/errors v0.8.1 // indirect
|
||||||
github.com/sirupsen/logrus v1.4.1
|
github.com/sirupsen/logrus v1.4.1
|
||||||
github.com/stretchr/testify v1.3.0 // indirect
|
github.com/stretchr/testify v1.3.0 // indirect
|
||||||
|
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 // indirect
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 // indirect
|
||||||
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 // indirect
|
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 // indirect
|
||||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862
|
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862
|
||||||
|
golang.org/x/text v0.3.0
|
||||||
gopkg.in/AlecAivazis/survey.v1 v1.8.4
|
gopkg.in/AlecAivazis/survey.v1 v1.8.4
|
||||||
gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22
|
gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22
|
||||||
)
|
)
|
||||||
|
|||||||
5
go.sum
5
go.sum
@@ -2,6 +2,8 @@ github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITg
|
|||||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
|
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
|
||||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
|
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
|
||||||
|
github.com/abadojack/whatlanggo v1.0.1 h1:19N6YogDnf71CTHm3Mp2qhYfkRdyvbgwWdd2EPxJRG4=
|
||||||
|
github.com/abadojack/whatlanggo v1.0.1/go.mod h1:66WiQbSbJBIlOZMsvbKe5m6pzQovxCH9B/K8tQB2uoc=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@@ -68,6 +70,8 @@ github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
|||||||
github.com/stretchr/testify v1.2.2/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=
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba h1:2DHfQOxcpWdGf5q5IzCUFPNvRX9Icf+09RvQK2VnJq0=
|
||||||
|
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba/go.mod h1:iLnlXG2Pakcii2CU0cbY07DRCSvpWNa7nFxtevhOChk=
|
||||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
|
||||||
@@ -83,6 +87,7 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862 h1:rM0ROo5vb9AdYJi1110yjWGMej9ITfKddS89P3Fkhug=
|
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862 h1:rM0ROo5vb9AdYJi1110yjWGMej9ITfKddS89P3Fkhug=
|
||||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
gopkg.in/AlecAivazis/survey.v1 v1.8.4 h1:10xXXN3wgIhPheb5NI58zFgZv32Ana7P3Tl4shW+0Qc=
|
gopkg.in/AlecAivazis/survey.v1 v1.8.4 h1:10xXXN3wgIhPheb5NI58zFgZv32Ana7P3Tl4shW+0Qc=
|
||||||
gopkg.in/AlecAivazis/survey.v1 v1.8.4/go.mod h1:iBNOmqKz/NUbZx3bA+4hAGLRC7fSK7tgtVDT4tB22XA=
|
gopkg.in/AlecAivazis/survey.v1 v1.8.4/go.mod h1:iBNOmqKz/NUbZx3bA+4hAGLRC7fSK7tgtVDT4tB22XA=
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ type Manager struct {
|
|||||||
functions map[string]*boundFunction
|
functions map[string]*boundFunction
|
||||||
internalMethods *internalMethods
|
internalMethods *internalMethods
|
||||||
initMethods []*boundMethod
|
initMethods []*boundMethod
|
||||||
|
shutdownMethods []*boundMethod
|
||||||
log *logger.CustomLogger
|
log *logger.CustomLogger
|
||||||
renderer interfaces.Renderer
|
renderer interfaces.Renderer
|
||||||
runtime interfaces.Runtime // The runtime object to pass to bound structs
|
runtime interfaces.Runtime // The runtime object to pass to bound structs
|
||||||
@@ -127,6 +128,9 @@ func (b *Manager) bindMethod(object interface{}) error {
|
|||||||
if newMethod.isWailsInit {
|
if newMethod.isWailsInit {
|
||||||
b.log.Debugf("Detected WailsInit function: %s", fullMethodName)
|
b.log.Debugf("Detected WailsInit function: %s", fullMethodName)
|
||||||
b.initMethods = append(b.initMethods, newMethod)
|
b.initMethods = append(b.initMethods, newMethod)
|
||||||
|
} else if newMethod.isWailsShutdown {
|
||||||
|
b.log.Debugf("Detected WailsShutdown function: %s", fullMethodName)
|
||||||
|
b.shutdownMethods = append(b.shutdownMethods, newMethod)
|
||||||
} else {
|
} else {
|
||||||
// Save boundMethod
|
// Save boundMethod
|
||||||
b.log.Infof("Bound Method: %s()", fullMethodName)
|
b.log.Infof("Bound Method: %s()", fullMethodName)
|
||||||
@@ -292,3 +296,13 @@ func (b *Manager) callWailsInitMethods() error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shutdown the binding manager
|
||||||
|
func (b *Manager) Shutdown() {
|
||||||
|
b.log.Debug("Shutdown called")
|
||||||
|
for _, method := range b.shutdownMethods {
|
||||||
|
b.log.Debugf("Calling Shutdown for method: %s", method.fullName)
|
||||||
|
method.call("[]")
|
||||||
|
}
|
||||||
|
b.log.Debug("Shutdown complete")
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ type boundMethod struct {
|
|||||||
log *logger.CustomLogger
|
log *logger.CustomLogger
|
||||||
hasErrorReturnType bool // Indicates if there is an error return type
|
hasErrorReturnType bool // Indicates if there is an error return type
|
||||||
isWailsInit bool
|
isWailsInit bool
|
||||||
|
isWailsShutdown bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new bound method based on the given method + type
|
// Creates a new bound method based on the given method + type
|
||||||
@@ -39,6 +40,11 @@ func newBoundMethod(name string, fullName string, method reflect.Value, objectTy
|
|||||||
err = result.processWailsInit()
|
err = result.processWailsInit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Are we a WailsShutdown method?
|
||||||
|
if result.Name == "WailsShutdown" {
|
||||||
|
err = result.processWailsShutdown()
|
||||||
|
}
|
||||||
|
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,3 +217,20 @@ func (b *boundMethod) processWailsInit() error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *boundMethod) processWailsShutdown() error {
|
||||||
|
// We must have only 1 input, it must be *wails.Runtime
|
||||||
|
if len(b.inputs) != 0 {
|
||||||
|
return fmt.Errorf("Invalid WailsShutdown() definition. Expected 0 inputs, but got %d", len(b.inputs))
|
||||||
|
}
|
||||||
|
|
||||||
|
// We must have only 1 output, it must be error
|
||||||
|
if len(b.returnTypes) != 0 {
|
||||||
|
return fmt.Errorf("Invalid WailsShutdown() definition. Expected 0 return types, but got %d", len(b.returnTypes))
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are indeed a wails Shutdown method
|
||||||
|
b.isWailsShutdown = true
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,18 +3,21 @@ package event
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/wailsapp/wails/lib/interfaces"
|
||||||
"github.com/wailsapp/wails/lib/logger"
|
"github.com/wailsapp/wails/lib/logger"
|
||||||
"github.com/wailsapp/wails/lib/messages"
|
"github.com/wailsapp/wails/lib/messages"
|
||||||
"github.com/wailsapp/wails/lib/interfaces"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Manager handles and processes events
|
// Manager handles and processes events
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
incomingEvents chan *messages.EventData
|
incomingEvents chan *messages.EventData
|
||||||
listeners map[string][]*eventListener
|
listeners map[string][]*eventListener
|
||||||
exit bool
|
running bool
|
||||||
log *logger.CustomLogger
|
log *logger.CustomLogger
|
||||||
renderer interfaces.Renderer // Messages will be dispatched to the frontend
|
renderer interfaces.Renderer // Messages will be dispatched to the frontend
|
||||||
|
wg sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewManager creates a new event manager with a 100 event buffer
|
// NewManager creates a new event manager with a 100 event buffer
|
||||||
@@ -22,7 +25,7 @@ func NewManager() interfaces.EventManager {
|
|||||||
return &Manager{
|
return &Manager{
|
||||||
incomingEvents: make(chan *messages.EventData, 100),
|
incomingEvents: make(chan *messages.EventData, 100),
|
||||||
listeners: make(map[string][]*eventListener),
|
listeners: make(map[string][]*eventListener),
|
||||||
exit: false,
|
running: false,
|
||||||
log: logger.NewCustomLogger("Events"),
|
log: logger.NewCustomLogger("Events"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,15 +90,14 @@ func (e *Manager) Start(renderer interfaces.Renderer) {
|
|||||||
// Store renderer
|
// Store renderer
|
||||||
e.renderer = renderer
|
e.renderer = renderer
|
||||||
|
|
||||||
// Set up waitgroup so we can wait for goroutine to start
|
// Set up waitgroup so we can wait for goroutine to quit
|
||||||
var wg sync.WaitGroup
|
e.running = true
|
||||||
wg.Add(1)
|
e.wg.Add(1)
|
||||||
|
|
||||||
// Run main loop in separate goroutine
|
// Run main loop in separate goroutine
|
||||||
go func() {
|
go func() {
|
||||||
wg.Done()
|
|
||||||
e.log.Info("Listening")
|
e.log.Info("Listening")
|
||||||
for e.exit == false {
|
for e.running {
|
||||||
// TODO: Listen for application exit
|
// TODO: Listen for application exit
|
||||||
select {
|
select {
|
||||||
case event := <-e.incomingEvents:
|
case event := <-e.incomingEvents:
|
||||||
@@ -139,14 +141,18 @@ func (e *Manager) Start(renderer interfaces.Renderer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
time.Sleep(1 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
e.wg.Done()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Wait for goroutine to start
|
|
||||||
wg.Wait()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Manager) stop() {
|
// Shutdown is called when exiting the Application
|
||||||
e.exit = true
|
func (e *Manager) Shutdown() {
|
||||||
|
e.log.Debug("Shutting Down")
|
||||||
|
e.running = false
|
||||||
|
e.log.Debug("Waiting for main loop to exit")
|
||||||
|
e.wg.Wait()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ type BindingManager interface {
|
|||||||
Bind(object interface{})
|
Bind(object interface{})
|
||||||
Start(renderer Renderer, runtime Runtime) error
|
Start(renderer Renderer, runtime Runtime) error
|
||||||
ProcessCall(callData *messages.CallData) (result interface{}, err error)
|
ProcessCall(callData *messages.CallData) (result interface{}, err error)
|
||||||
|
Shutdown()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ type EventManager interface {
|
|||||||
Emit(eventName string, optionalData ...interface{})
|
Emit(eventName string, optionalData ...interface{})
|
||||||
On(eventName string, callback func(...interface{}))
|
On(eventName string, callback func(...interface{}))
|
||||||
Start(Renderer)
|
Start(Renderer)
|
||||||
|
Shutdown()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ type IPCManager interface {
|
|||||||
BindRenderer(Renderer)
|
BindRenderer(Renderer)
|
||||||
Dispatch(message string)
|
Dispatch(message string)
|
||||||
Start(eventManager EventManager, bindingManager BindingManager)
|
Start(eventManager EventManager, bindingManager BindingManager)
|
||||||
|
Shutdown()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package ipc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/lib/interfaces"
|
"github.com/wailsapp/wails/lib/interfaces"
|
||||||
"github.com/wailsapp/wails/lib/logger"
|
"github.com/wailsapp/wails/lib/logger"
|
||||||
@@ -12,18 +14,20 @@ import (
|
|||||||
type Manager struct {
|
type Manager struct {
|
||||||
renderer interfaces.Renderer // The renderer
|
renderer interfaces.Renderer // The renderer
|
||||||
messageQueue chan *ipcMessage
|
messageQueue chan *ipcMessage
|
||||||
// quitChannel chan struct{}
|
quitChannel chan struct{}
|
||||||
// signals chan os.Signal
|
// signals chan os.Signal
|
||||||
log *logger.CustomLogger
|
log *logger.CustomLogger
|
||||||
eventManager interfaces.EventManager
|
eventManager interfaces.EventManager
|
||||||
bindingManager interfaces.BindingManager
|
bindingManager interfaces.BindingManager
|
||||||
|
running bool
|
||||||
|
wg sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewManager creates a new IPC Manager
|
// NewManager creates a new IPC Manager
|
||||||
func NewManager() interfaces.IPCManager {
|
func NewManager() interfaces.IPCManager {
|
||||||
result := &Manager{
|
result := &Manager{
|
||||||
messageQueue: make(chan *ipcMessage, 100),
|
messageQueue: make(chan *ipcMessage, 100),
|
||||||
// quitChannel: make(chan struct{}),
|
quitChannel: make(chan struct{}),
|
||||||
// signals: make(chan os.Signal, 1),
|
// signals: make(chan os.Signal, 1),
|
||||||
log: logger.NewCustomLogger("IPC"),
|
log: logger.NewCustomLogger("IPC"),
|
||||||
}
|
}
|
||||||
@@ -44,9 +48,12 @@ func (i *Manager) Start(eventManager interfaces.EventManager, bindingManager int
|
|||||||
|
|
||||||
i.log.Info("Starting")
|
i.log.Info("Starting")
|
||||||
// signal.Notify(manager.signals, os.Interrupt)
|
// signal.Notify(manager.signals, os.Interrupt)
|
||||||
|
i.running = true
|
||||||
|
|
||||||
|
// Keep track of this goroutine
|
||||||
|
i.wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
running := true
|
for i.running {
|
||||||
for running {
|
|
||||||
select {
|
select {
|
||||||
case incomingMessage := <-i.messageQueue:
|
case incomingMessage := <-i.messageQueue:
|
||||||
i.log.DebugFields("Processing message", logger.Fields{
|
i.log.DebugFields("Processing message", logger.Fields{
|
||||||
@@ -117,15 +124,12 @@ func (i *Manager) Start(eventManager interfaces.EventManager, bindingManager int
|
|||||||
i.log.DebugFields("Finished processing message", logger.Fields{
|
i.log.DebugFields("Finished processing message", logger.Fields{
|
||||||
"1D": &incomingMessage,
|
"1D": &incomingMessage,
|
||||||
})
|
})
|
||||||
// case <-manager.quitChannel:
|
default:
|
||||||
// Debug("[MessageQueue] Quit caught")
|
time.Sleep(1 * time.Millisecond)
|
||||||
// running = false
|
|
||||||
// case <-manager.signals:
|
|
||||||
// Debug("[MessageQueue] Signal caught")
|
|
||||||
// running = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i.log.Debug("Stopping")
|
i.log.Debug("Stopping")
|
||||||
|
i.wg.Done()
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,3 +171,11 @@ func (i *Manager) SendResponse(response *ipcResponse) error {
|
|||||||
// Call back to the front end
|
// Call back to the front end
|
||||||
return i.renderer.Callback(data)
|
return i.renderer.Callback(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shutdown is called when exiting the Application
|
||||||
|
func (i *Manager) Shutdown() {
|
||||||
|
i.log.Debug("Shutdown called")
|
||||||
|
i.running = false
|
||||||
|
i.log.Debug("Waiting of main loop shutdown")
|
||||||
|
i.wg.Wait()
|
||||||
|
}
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ func (h *Bridge) Run() error {
|
|||||||
h.log.Info("The frontend will connect automatically.")
|
h.log.Info("The frontend will connect automatically.")
|
||||||
|
|
||||||
err := h.server.ListenAndServe()
|
err := h.server.ListenAndServe()
|
||||||
if err != nil {
|
if err != nil && err != http.ErrServerClosed {
|
||||||
h.log.Fatal(err.Error())
|
h.log.Fatal(err.Error())
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@@ -250,5 +250,9 @@ func (h *Bridge) SetTitle(title string) {
|
|||||||
// Close is unsupported for Bridge but required
|
// Close is unsupported for Bridge but required
|
||||||
// for the Renderer interface
|
// for the Renderer interface
|
||||||
func (h *Bridge) Close() {
|
func (h *Bridge) Close() {
|
||||||
h.log.Warn("Close() unsupported in bridge mode")
|
h.log.Debug("Shutting down")
|
||||||
|
err := h.server.Close()
|
||||||
|
if err != nil {
|
||||||
|
h.log.Errorf(err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,5 @@
|
|||||||
// Package wails implements Go bindings to https://github.com/zserge/webview C library.
|
// Package webview implements Go bindings to https://github.com/zserge/webview C library.
|
||||||
// It is a modified version of webview.go from that repository
|
// It is a modified version of webview.go from that repository
|
||||||
|
|
||||||
// Bindings closely repeat the C APIs and include both, a simplified
|
// Bindings closely repeat the C APIs and include both, a simplified
|
||||||
// single-function API to just open a full-screen webview window, and a more
|
// single-function API to just open a full-screen webview window, and a more
|
||||||
// advanced and featureful set of APIs, including Go-to-JavaScript bindings.
|
// advanced and featureful set of APIs, including Go-to-JavaScript bindings.
|
||||||
@@ -11,10 +10,10 @@
|
|||||||
package webview
|
package webview
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#cgo linux openbsd freebsd CFLAGS: -DWEBVIEW_GTK=1
|
#cgo linux openbsd freebsd CFLAGS: -DWEBVIEW_GTK=1 -Wno-deprecated-declarations
|
||||||
#cgo linux openbsd freebsd pkg-config: gtk+-3.0 webkit2gtk-4.0
|
#cgo linux openbsd freebsd pkg-config: gtk+-3.0 webkit2gtk-4.0
|
||||||
|
|
||||||
#cgo windows CFLAGS: -DWEBVIEW_WINAPI=1
|
#cgo windows CFLAGS: -DWEBVIEW_WINAPI=1 -std=c99
|
||||||
#cgo windows LDFLAGS: -lole32 -lcomctl32 -loleaut32 -luuid -lgdi32
|
#cgo windows LDFLAGS: -lole32 -lcomctl32 -loleaut32 -luuid -lgdi32
|
||||||
|
|
||||||
#cgo darwin CFLAGS: -DWEBVIEW_COCOA=1 -x objective-c
|
#cgo darwin CFLAGS: -DWEBVIEW_COCOA=1 -x objective-c
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ struct webview_priv
|
|||||||
NSAutoreleasePool *pool;
|
NSAutoreleasePool *pool;
|
||||||
NSWindow *window;
|
NSWindow *window;
|
||||||
WebView *webview;
|
WebView *webview;
|
||||||
id windowDelegate;
|
id delegate;
|
||||||
int should_exit;
|
int should_exit;
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
@@ -1038,7 +1038,7 @@ struct webview_priv
|
|||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TCHAR *classname = "WebView";
|
static const TCHAR *classname = TEXT("WebView");
|
||||||
static const SAFEARRAYBOUND ArrayBound = {1, 0};
|
static const SAFEARRAYBOUND ArrayBound = {1, 0};
|
||||||
|
|
||||||
static IOleClientSiteVtbl MyIOleClientSiteTable = {
|
static IOleClientSiteVtbl MyIOleClientSiteTable = {
|
||||||
@@ -1227,7 +1227,7 @@ struct webview_priv
|
|||||||
}
|
}
|
||||||
VariantInit(&myURL);
|
VariantInit(&myURL);
|
||||||
myURL.vt = VT_BSTR;
|
myURL.vt = VT_BSTR;
|
||||||
#ifndef UNICODE
|
// #ifndef UNICODE
|
||||||
{
|
{
|
||||||
wchar_t *buffer = webview_to_utf16(webPageName);
|
wchar_t *buffer = webview_to_utf16(webPageName);
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
@@ -1237,9 +1237,9 @@ struct webview_priv
|
|||||||
myURL.bstrVal = SysAllocString(buffer);
|
myURL.bstrVal = SysAllocString(buffer);
|
||||||
GlobalFree(buffer);
|
GlobalFree(buffer);
|
||||||
}
|
}
|
||||||
#else
|
// #else
|
||||||
myURL.bstrVal = SysAllocString(webPageName);
|
// myURL.bstrVal = SysAllocString(webPageName);
|
||||||
#endif
|
// #endif
|
||||||
if (!myURL.bstrVal)
|
if (!myURL.bstrVal)
|
||||||
{
|
{
|
||||||
badalloc:
|
badalloc:
|
||||||
@@ -1277,7 +1277,7 @@ struct webview_priv
|
|||||||
if (!SafeArrayAccessData(sfArray, (void **)&pVar))
|
if (!SafeArrayAccessData(sfArray, (void **)&pVar))
|
||||||
{
|
{
|
||||||
pVar->vt = VT_BSTR;
|
pVar->vt = VT_BSTR;
|
||||||
#ifndef UNICODE
|
// #ifndef UNICODE
|
||||||
{
|
{
|
||||||
wchar_t *buffer = webview_to_utf16(url);
|
wchar_t *buffer = webview_to_utf16(url);
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
@@ -1287,9 +1287,9 @@ struct webview_priv
|
|||||||
bstr = SysAllocString(buffer);
|
bstr = SysAllocString(buffer);
|
||||||
GlobalFree(buffer);
|
GlobalFree(buffer);
|
||||||
}
|
}
|
||||||
#else
|
// #else
|
||||||
bstr = SysAllocString(string);
|
// bstr = SysAllocString(url);
|
||||||
#endif
|
// #endif
|
||||||
if ((pVar->bstrVal = bstr))
|
if ((pVar->bstrVal = bstr))
|
||||||
{
|
{
|
||||||
htmlDoc2->lpVtbl->write(htmlDoc2, sfArray);
|
htmlDoc2->lpVtbl->write(htmlDoc2, sfArray);
|
||||||
@@ -1404,6 +1404,7 @@ struct webview_priv
|
|||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZeroMemory(&wc, sizeof(WNDCLASSEX));
|
ZeroMemory(&wc, sizeof(WNDCLASSEX));
|
||||||
wc.cbSize = sizeof(WNDCLASSEX);
|
wc.cbSize = sizeof(WNDCLASSEX);
|
||||||
wc.hInstance = hInstance;
|
wc.hInstance = hInstance;
|
||||||
@@ -1431,10 +1432,24 @@ struct webview_priv
|
|||||||
rect.bottom = rect.bottom - rect.top + top;
|
rect.bottom = rect.bottom - rect.top + top;
|
||||||
rect.top = top;
|
rect.top = top;
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
wchar_t *u16title = webview_to_utf16(w->title);
|
||||||
|
if (u16title == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
w->priv.hwnd =
|
w->priv.hwnd =
|
||||||
|
CreateWindowEx(0, classname, u16title, style, rect.left, rect.top,
|
||||||
|
rect.right - rect.left, rect.bottom - rect.top,
|
||||||
|
HWND_DESKTOP, NULL, hInstance, (void *)w);
|
||||||
|
#else
|
||||||
|
w->priv.hwnd =
|
||||||
CreateWindowEx(0, classname, w->title, style, rect.left, rect.top,
|
CreateWindowEx(0, classname, w->title, style, rect.left, rect.top,
|
||||||
rect.right - rect.left, rect.bottom - rect.top,
|
rect.right - rect.left, rect.bottom - rect.top,
|
||||||
HWND_DESKTOP, NULL, hInstance, (void *)w);
|
HWND_DESKTOP, NULL, hInstance, (void *)w);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (w->priv.hwnd == 0)
|
if (w->priv.hwnd == 0)
|
||||||
{
|
{
|
||||||
OleUninitialize();
|
OleUninitialize();
|
||||||
@@ -1445,7 +1460,14 @@ struct webview_priv
|
|||||||
|
|
||||||
DisplayHTMLPage(w);
|
DisplayHTMLPage(w);
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
SetWindowText(w->priv.hwnd, u16title);
|
||||||
|
GlobalFree(u16title);
|
||||||
|
#else
|
||||||
SetWindowText(w->priv.hwnd, w->title);
|
SetWindowText(w->priv.hwnd, w->title);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ShowWindow(w->priv.hwnd, SW_SHOWDEFAULT);
|
ShowWindow(w->priv.hwnd, SW_SHOWDEFAULT);
|
||||||
UpdateWindow(w->priv.hwnd);
|
UpdateWindow(w->priv.hwnd);
|
||||||
SetFocus(w->priv.hwnd);
|
SetFocus(w->priv.hwnd);
|
||||||
@@ -1581,9 +1603,20 @@ struct webview_priv
|
|||||||
|
|
||||||
WEBVIEW_API void webview_set_title(struct webview *w, const char *title)
|
WEBVIEW_API void webview_set_title(struct webview *w, const char *title)
|
||||||
{
|
{
|
||||||
|
#ifdef UNICODE
|
||||||
|
wchar_t *u16title = webview_to_utf16(title);
|
||||||
|
if (u16title == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SetWindowText(w->priv.hwnd, u16title);
|
||||||
|
GlobalFree(u16title);
|
||||||
|
#else
|
||||||
SetWindowText(w->priv.hwnd, title);
|
SetWindowText(w->priv.hwnd, title);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WEBVIEW_API void webview_set_fullscreen(struct webview *w, int fullscreen)
|
WEBVIEW_API void webview_set_fullscreen(struct webview *w, int fullscreen)
|
||||||
{
|
{
|
||||||
if (w->priv.is_fullscreen == !!fullscreen)
|
if (w->priv.is_fullscreen == !!fullscreen)
|
||||||
@@ -1894,6 +1927,22 @@ struct webview_priv
|
|||||||
[script setValue:self forKey:@"external"];
|
[script setValue:self forKey:@"external"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void webview_run_input_open_panel(id self, SEL cmd, id webview,
|
||||||
|
id listener, BOOL allowMultiple) {
|
||||||
|
char filename[256] = "";
|
||||||
|
struct webview *w =
|
||||||
|
(struct webview *)objc_getAssociatedObject(self, "webview");
|
||||||
|
|
||||||
|
webview_dialog(w, WEBVIEW_DIALOG_TYPE_OPEN, WEBVIEW_DIALOG_FLAG_FILE, "", "",
|
||||||
|
filename, 255);
|
||||||
|
if (strlen(filename)) {
|
||||||
|
[listener chooseFilename:[NSString stringWithUTF8String:filename]];
|
||||||
|
} else {
|
||||||
|
[listener cancel];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void webview_external_invoke(id self, SEL cmd, id arg)
|
static void webview_external_invoke(id self, SEL cmd, id arg)
|
||||||
{
|
{
|
||||||
struct webview *w =
|
struct webview *w =
|
||||||
@@ -1927,12 +1976,17 @@ struct webview_priv
|
|||||||
class_addMethod(webViewDelegateClass,
|
class_addMethod(webViewDelegateClass,
|
||||||
sel_registerName("webView:didClearWindowObject:forFrame:"),
|
sel_registerName("webView:didClearWindowObject:forFrame:"),
|
||||||
(IMP)webview_did_clear_window_object, "v@:@@@");
|
(IMP)webview_did_clear_window_object, "v@:@@@");
|
||||||
|
class_addMethod(
|
||||||
|
webViewDelegateClass,
|
||||||
|
sel_registerName("webView:runOpenPanelForFileButtonWithResultListener:"
|
||||||
|
"allowMultipleFiles:"),
|
||||||
|
(IMP)webview_run_input_open_panel, "v@:@@c");
|
||||||
class_addMethod(webViewDelegateClass, sel_registerName("invoke:"),
|
class_addMethod(webViewDelegateClass, sel_registerName("invoke:"),
|
||||||
(IMP)webview_external_invoke, "v@:@");
|
(IMP)webview_external_invoke, "v@:@");
|
||||||
objc_registerClassPair(webViewDelegateClass);
|
objc_registerClassPair(webViewDelegateClass);
|
||||||
|
|
||||||
w->priv.windowDelegate = [[webViewDelegateClass alloc] init];
|
w->priv.delegate = [[webViewDelegateClass alloc] init];
|
||||||
objc_setAssociatedObject(w->priv.windowDelegate, "webview", (id)(w),
|
objc_setAssociatedObject(w->priv.delegate, "webview", (id)(w),
|
||||||
OBJC_ASSOCIATION_ASSIGN);
|
OBJC_ASSOCIATION_ASSIGN);
|
||||||
|
|
||||||
NSRect r = NSMakeRect(0, 0, w->width, w->height);
|
NSRect r = NSMakeRect(0, 0, w->width, w->height);
|
||||||
@@ -1960,7 +2014,7 @@ struct webview_priv
|
|||||||
NSString *nsTitle = [NSString stringWithUTF8String:w->title];
|
NSString *nsTitle = [NSString stringWithUTF8String:w->title];
|
||||||
[w->priv.window setTitle:nsTitle];
|
[w->priv.window setTitle:nsTitle];
|
||||||
|
|
||||||
[w->priv.window setDelegate:w->priv.windowDelegate];
|
[w->priv.window setDelegate:w->priv.delegate];
|
||||||
[w->priv.window center];
|
[w->priv.window center];
|
||||||
|
|
||||||
// NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"wat"];
|
// NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"wat"];
|
||||||
@@ -1989,7 +2043,8 @@ struct webview_priv
|
|||||||
[w->priv.webview setAutoresizesSubviews:YES];
|
[w->priv.webview setAutoresizesSubviews:YES];
|
||||||
[w->priv.webview
|
[w->priv.webview
|
||||||
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||||
w->priv.webview.frameLoadDelegate = w->priv.windowDelegate;
|
w->priv.webview.frameLoadDelegate = w->priv.delegate;
|
||||||
|
w->priv.webview.UIDelegate = w->priv.delegate;
|
||||||
[[w->priv.window contentView] addSubview:w->priv.webview];
|
[[w->priv.window contentView] addSubview:w->priv.webview];
|
||||||
[w->priv.window orderFrontRegardless];
|
[w->priv.window orderFrontRegardless];
|
||||||
|
|
||||||
|
|||||||
@@ -95,13 +95,6 @@ function startBridge() {
|
|||||||
window.wailsbridge.reconnectOverlay.style.display = 'none';
|
window.wailsbridge.reconnectOverlay.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bridge external.invoke
|
|
||||||
window.external = {
|
|
||||||
invoke: function (msg) {
|
|
||||||
window.wailsbridge.websocket.send(msg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Adds a script to the Dom.
|
// Adds a script to the Dom.
|
||||||
// Removes it if second parameter is true.
|
// Removes it if second parameter is true.
|
||||||
function addScript(script, remove) {
|
function addScript(script, remove) {
|
||||||
@@ -214,4 +207,4 @@ function Init(callback) {
|
|||||||
start(callback);
|
start(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { Init };
|
module.exports = Init;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -15,10 +15,7 @@
|
|||||||
"error",
|
"error",
|
||||||
"tab"
|
"tab"
|
||||||
],
|
],
|
||||||
"linebreak-style": [
|
"linebreak-style": 0,
|
||||||
"error",
|
|
||||||
"unix"
|
|
||||||
],
|
|
||||||
"quotes": [
|
"quotes": [
|
||||||
"error",
|
"error",
|
||||||
"single"
|
"single"
|
||||||
|
|||||||
@@ -15,7 +15,11 @@ The lightweight framework for web-like apps
|
|||||||
* @param {string} message
|
* @param {string} message
|
||||||
*/
|
*/
|
||||||
function Invoke(message) {
|
function Invoke(message) {
|
||||||
window.external.invoke(message);
|
if ( window.wailsbridge ) {
|
||||||
|
window.wailsbridge.websocket.send(message);
|
||||||
|
} else {
|
||||||
|
window.external.invoke(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ The lightweight framework for web-like apps
|
|||||||
/* jshint esversion: 6 */
|
/* jshint esversion: 6 */
|
||||||
import * as Log from './log';
|
import * as Log from './log';
|
||||||
import * as Browser from './browser';
|
import * as Browser from './browser';
|
||||||
import { On, Emit, Notify, Heartbeat, Acknowledge } from './events';
|
import { On, OnMultiple, Emit, Notify, Heartbeat, Acknowledge } from './events';
|
||||||
import { NewBinding } from './bindings';
|
import { NewBinding } from './bindings';
|
||||||
import { Callback } from './calls';
|
import { Callback } from './calls';
|
||||||
import { AddScript, InjectCSS } from './utils';
|
import { AddScript, InjectCSS } from './utils';
|
||||||
@@ -35,6 +35,7 @@ var runtime = {
|
|||||||
Browser,
|
Browser,
|
||||||
Events: {
|
Events: {
|
||||||
On,
|
On,
|
||||||
|
OnMultiple,
|
||||||
Emit,
|
Emit,
|
||||||
Heartbeat,
|
Heartbeat,
|
||||||
Acknowledge,
|
Acknowledge,
|
||||||
@@ -45,6 +46,16 @@ var runtime = {
|
|||||||
// Augment global
|
// Augment global
|
||||||
Object.assign(window.wails, runtime);
|
Object.assign(window.wails, runtime);
|
||||||
|
|
||||||
|
// Setup global error handler
|
||||||
|
window.onerror = function (msg, url, lineNo, columnNo, error) {
|
||||||
|
window.wails.Log.Error('**** Caught Unhandled Error ****');
|
||||||
|
window.wails.Log.Error('Message: ' + msg);
|
||||||
|
window.wails.Log.Error('URL: ' + url);
|
||||||
|
window.wails.Log.Error('Line No: ' + lineNo);
|
||||||
|
window.wails.Log.Error('Column No: ' + columnNo);
|
||||||
|
window.wails.Log.Error('error: ' + error);
|
||||||
|
};
|
||||||
|
|
||||||
// Emit loaded event
|
// Emit loaded event
|
||||||
Emit('wails:loaded');
|
Emit('wails:loaded');
|
||||||
|
|
||||||
|
|||||||
83
runtime/js/package-lock.json
generated
83
runtime/js/package-lock.json
generated
@@ -56,13 +56,15 @@
|
|||||||
"version": "0.3.2",
|
"version": "0.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
|
||||||
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
|
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"braces": {
|
"braces": {
|
||||||
"version": "2.3.2",
|
"version": "2.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
|
||||||
"integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
|
"integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"arr-flatten": "^1.1.0",
|
"arr-flatten": "^1.1.0",
|
||||||
"array-unique": "^0.3.2",
|
"array-unique": "^0.3.2",
|
||||||
@@ -81,6 +83,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"is-extendable": "^0.1.0"
|
"is-extendable": "^0.1.0"
|
||||||
}
|
}
|
||||||
@@ -253,6 +256,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
||||||
"integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
|
"integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"extend-shallow": "^2.0.1",
|
"extend-shallow": "^2.0.1",
|
||||||
"is-number": "^3.0.0",
|
"is-number": "^3.0.0",
|
||||||
@@ -265,6 +269,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"is-extendable": "^0.1.0"
|
"is-extendable": "^0.1.0"
|
||||||
}
|
}
|
||||||
@@ -330,7 +335,8 @@
|
|||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
|
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"is-glob": {
|
"is-glob": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
@@ -347,6 +353,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
|
||||||
"integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
|
"integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"kind-of": "^3.0.2"
|
"kind-of": "^3.0.2"
|
||||||
},
|
},
|
||||||
@@ -356,6 +363,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"is-buffer": "^1.1.5"
|
"is-buffer": "^1.1.5"
|
||||||
}
|
}
|
||||||
@@ -366,13 +374,15 @@
|
|||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
|
||||||
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
|
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"kind-of": {
|
"kind-of": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
|
||||||
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
|
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"micromatch": {
|
"micromatch": {
|
||||||
"version": "3.1.10",
|
"version": "3.1.10",
|
||||||
@@ -2881,9 +2891,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"eslint": {
|
"eslint": {
|
||||||
"version": "6.2.2",
|
"version": "6.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.5.1.tgz",
|
||||||
"integrity": "sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw==",
|
"integrity": "sha512-32h99BoLYStT1iq1v2P9uwpyznQ4M2jRiFB6acitKz52Gqn+vPaMDUTB1bYi1WN4Nquj2w+t+bimYUG83DC55A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/code-frame": "^7.0.0",
|
"@babel/code-frame": "^7.0.0",
|
||||||
@@ -3001,9 +3011,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": {
|
"acorn": {
|
||||||
"version": "7.0.0",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
|
||||||
"integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==",
|
"integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3577,7 +3587,8 @@
|
|||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"aproba": {
|
"aproba": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
@@ -3598,12 +3609,14 @@
|
|||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@@ -3618,17 +3631,20 @@
|
|||||||
"code-point-at": {
|
"code-point-at": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"console-control-strings": {
|
"console-control-strings": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@@ -3745,7 +3761,8 @@
|
|||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"ini": {
|
"ini": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
@@ -3757,6 +3774,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"number-is-nan": "^1.0.0"
|
"number-is-nan": "^1.0.0"
|
||||||
}
|
}
|
||||||
@@ -3771,6 +3789,7 @@
|
|||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
}
|
}
|
||||||
@@ -3778,12 +3797,14 @@
|
|||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "0.0.8",
|
"version": "0.0.8",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "2.3.5",
|
"version": "2.3.5",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "^5.1.2",
|
"safe-buffer": "^5.1.2",
|
||||||
"yallist": "^3.0.0"
|
"yallist": "^3.0.0"
|
||||||
@@ -3802,6 +3823,7 @@
|
|||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"minimist": "0.0.8"
|
"minimist": "0.0.8"
|
||||||
}
|
}
|
||||||
@@ -3882,7 +3904,8 @@
|
|||||||
"number-is-nan": {
|
"number-is-nan": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
@@ -3894,6 +3917,7 @@
|
|||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
@@ -3979,7 +4003,8 @@
|
|||||||
"safe-buffer": {
|
"safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"safer-buffer": {
|
"safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
@@ -4015,6 +4040,7 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"code-point-at": "^1.0.0",
|
"code-point-at": "^1.0.0",
|
||||||
"is-fullwidth-code-point": "^1.0.0",
|
"is-fullwidth-code-point": "^1.0.0",
|
||||||
@@ -4034,6 +4060,7 @@
|
|||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-regex": "^2.0.0"
|
"ansi-regex": "^2.0.0"
|
||||||
}
|
}
|
||||||
@@ -4077,12 +4104,14 @@
|
|||||||
"wrappy": {
|
"wrappy": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -4134,9 +4163,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"glob-parent": {
|
"glob-parent": {
|
||||||
"version": "5.0.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
|
||||||
"integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==",
|
"integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"is-glob": "^4.0.1"
|
"is-glob": "^4.0.1"
|
||||||
@@ -5972,9 +6001,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rxjs": {
|
"rxjs": {
|
||||||
"version": "6.5.2",
|
"version": "6.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz",
|
||||||
"integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==",
|
"integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"tslib": "^1.9.0"
|
"tslib": "^1.9.0"
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
"description": "The Javascript Wails Runtime",
|
"description": "The Javascript Wails Runtime",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "eslint core/ && npm run build:prod",
|
"build": "./node_modules/.bin/eslint core/ && npm run build:prod",
|
||||||
"build:prod": "webpack --env prod --colors",
|
"build:prod": "./node_modules/.bin/webpack --env prod --colors",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
"babel-loader": "^8.0.6",
|
"babel-loader": "^8.0.6",
|
||||||
"babel-preset-minify": "^0.5.0",
|
"babel-preset-minify": "^0.5.0",
|
||||||
"core-js": "^3.1.4",
|
"core-js": "^3.1.4",
|
||||||
"eslint": "^6.2.2",
|
"eslint": "^6.5.1",
|
||||||
"webpack": "^4.35.3",
|
"webpack": "^4.35.3",
|
||||||
"webpack-cli": "^3.3.5"
|
"webpack-cli": "^3.3.5"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,6 @@ function OpenFile(filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
OpenURL,
|
OpenURL: OpenURL,
|
||||||
OpenFile
|
OpenFile: OpenFile
|
||||||
};
|
};
|
||||||
@@ -61,9 +61,9 @@ function Emit(eventName) {
|
|||||||
* the event is acknowledged via `Event.Acknowledge`. Once this happens, `callback` is invoked ONCE
|
* the event is acknowledged via `Event.Acknowledge`. Once this happens, `callback` is invoked ONCE
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
* @param {*} eventName
|
* @param {string} eventName
|
||||||
* @param {*} timeInMilliseconds
|
* @param {number} timeInMilliseconds
|
||||||
* @param {*} callback
|
* @param {function} callback
|
||||||
*/
|
*/
|
||||||
function Heartbeat(eventName, timeInMilliseconds, callback) {
|
function Heartbeat(eventName, timeInMilliseconds, callback) {
|
||||||
window.wails.Events.Heartbeat(eventName, timeInMilliseconds, callback);
|
window.wails.Events.Heartbeat(eventName, timeInMilliseconds, callback);
|
||||||
@@ -80,10 +80,10 @@ function Acknowledge(eventName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
OnMultiple,
|
OnMultiple: OnMultiple,
|
||||||
On,
|
On: On,
|
||||||
Once,
|
Once: Once,
|
||||||
Emit,
|
Emit: Emit,
|
||||||
Heartbeat,
|
Heartbeat: Heartbeat,
|
||||||
Acknowledge
|
Acknowledge: Acknowledge
|
||||||
};
|
};
|
||||||
@@ -18,6 +18,4 @@ function Init(callback) {
|
|||||||
window.wails._.Init(callback);
|
window.wails._.Init(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = Init;
|
||||||
Init
|
|
||||||
};
|
|
||||||
@@ -62,9 +62,9 @@ function Fatal(message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
Debug,
|
Debug: Debug,
|
||||||
Info,
|
Info: Info,
|
||||||
Warning,
|
Warning: Warning,
|
||||||
Error,
|
Error: Error,
|
||||||
Fatal
|
Fatal: Fatal
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ const Events = require('./events');
|
|||||||
const Init = require('./init');
|
const Init = require('./init');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
Log,
|
Log: Log,
|
||||||
Browser,
|
Browser: Browser,
|
||||||
Events,
|
Events: Events,
|
||||||
Init
|
Init: Init
|
||||||
};
|
};
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "@wailsapp/runtime",
|
"name": "@wailsapp/runtime",
|
||||||
"version": "1.0.2",
|
"version": "1.0.9",
|
||||||
"description": "Wails Javascript runtime library",
|
"description": "Wails Javascript runtime library",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
|
"types": "runtime.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
@@ -20,5 +21,8 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/wailsapp/wails/issues"
|
"url": "https://github.com/wailsapp/wails/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/wailsapp/wails#readme"
|
"homepage": "https://github.com/wailsapp/wails#readme",
|
||||||
|
"devDependencies": {
|
||||||
|
"dts-gen": "^0.5.8"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
26
runtime/js/runtime/runtime.d.ts
vendored
Normal file
26
runtime/js/runtime/runtime.d.ts
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
export = wailsapp__runtime;
|
||||||
|
|
||||||
|
declare const wailsapp__runtime: {
|
||||||
|
Browser: {
|
||||||
|
OpenFile(filename: string): Promise<any>;
|
||||||
|
OpenURL(url: string): Promise<any>;
|
||||||
|
};
|
||||||
|
Events: {
|
||||||
|
Acknowledge(eventName: string): void;
|
||||||
|
Emit(eventName: string): void;
|
||||||
|
Heartbeat(eventName: string, timeInMilliseconds: number, callback: () => void): void;
|
||||||
|
On(eventName: string, callback: () => void): void;
|
||||||
|
OnMultiple(eventName: string, callback: () => void, maxCallbacks: number): void;
|
||||||
|
Once(eventName: string, callback: () => void): void;
|
||||||
|
};
|
||||||
|
Init(callback: () => void): void;
|
||||||
|
Log: {
|
||||||
|
Debug(message: string): void;
|
||||||
|
Error(message: string): void;
|
||||||
|
Fatal(message: string): void;
|
||||||
|
Info(message: string): void;
|
||||||
|
Warning(message: string): void;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1,6 +1,54 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "github.com/wailsapp/wails/lib/interfaces"
|
import (
|
||||||
|
"bytes"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/abadojack/whatlanggo"
|
||||||
|
"github.com/wailsapp/wails/lib/interfaces"
|
||||||
|
"golang.org/x/text/encoding"
|
||||||
|
"golang.org/x/text/encoding/japanese"
|
||||||
|
"golang.org/x/text/encoding/korean"
|
||||||
|
"golang.org/x/text/encoding/simplifiedchinese"
|
||||||
|
"golang.org/x/text/transform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func detectEncoding(text string) (encoding.Encoding, string) {
|
||||||
|
// korean
|
||||||
|
var enc encoding.Encoding
|
||||||
|
info := whatlanggo.Detect(text)
|
||||||
|
//fmt.Println("Language:", info.Lang.String(), " Script:", whatlanggo.Scripts[info.Script], " Confidence: ", info.Confidence)
|
||||||
|
switch info.Lang.String() {
|
||||||
|
case "Korean":
|
||||||
|
enc = korean.EUCKR
|
||||||
|
case "Mandarin":
|
||||||
|
enc = simplifiedchinese.GBK
|
||||||
|
case "Japanese":
|
||||||
|
enc = japanese.EUCJP
|
||||||
|
}
|
||||||
|
return enc, info.Lang.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcessEncoding attempts to convert CKJ strings to UTF-8
|
||||||
|
func ProcessEncoding(text string) string {
|
||||||
|
if runtime.GOOS != "windows" {
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
|
encoding, _ := detectEncoding(text)
|
||||||
|
if encoding != nil {
|
||||||
|
var bufs bytes.Buffer
|
||||||
|
wr := transform.NewWriter(&bufs, encoding.NewEncoder())
|
||||||
|
_, err := wr.Write([]byte(text))
|
||||||
|
defer wr.Close()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return bufs.String()
|
||||||
|
}
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
// Window exposes an interface for manipulating the window
|
// Window exposes an interface for manipulating the window
|
||||||
type Window struct {
|
type Window struct {
|
||||||
@@ -31,6 +79,7 @@ func (r *Window) UnFullscreen() {
|
|||||||
|
|
||||||
// SetTitle sets the the window title
|
// SetTitle sets the the window title
|
||||||
func (r *Window) SetTitle(title string) {
|
func (r *Window) SetTitle(title string) {
|
||||||
|
title = ProcessEncoding(title)
|
||||||
r.renderer.SetTitle(title)
|
r.renderer.SetTitle(title)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
84
scripts/build.go
Normal file
84
scripts/build.go
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Default target to run when none is specified
|
||||||
|
// If not set, running mage will list available targets
|
||||||
|
// var Default = Build
|
||||||
|
|
||||||
|
/*
|
||||||
|
# Build runtime
|
||||||
|
echo "**** Building Runtime ****"
|
||||||
|
cd runtime/js
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
|
cd ../..
|
||||||
|
|
||||||
|
echo "**** Packing Assets ****"
|
||||||
|
cd cmd
|
||||||
|
mewn
|
||||||
|
cd ..
|
||||||
|
cd lib/renderer
|
||||||
|
mewn
|
||||||
|
cd ../..
|
||||||
|
|
||||||
|
echo "**** Installing Wails locally ****"
|
||||||
|
cd cmd/wails
|
||||||
|
go install
|
||||||
|
cd ../..
|
||||||
|
|
||||||
|
echo "**** Tidying the mods! ****"
|
||||||
|
go mod tidy
|
||||||
|
|
||||||
|
echo "**** WE ARE DONE! ****"
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func runCommand(command string, args ...string) {
|
||||||
|
cmd := exec.Command(command, args...)
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(string(output))
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
cmd.Run()
|
||||||
|
fmt.Println(string(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
// A build step that requires additional params, or platform specific steps for example
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
dir, _ := os.Getwd()
|
||||||
|
|
||||||
|
// Build Runtime
|
||||||
|
fmt.Println("**** Building Runtime ****")
|
||||||
|
runtimeDir, _ := filepath.Abs(filepath.Join(dir, "..", "runtime", "js"))
|
||||||
|
os.Chdir(runtimeDir)
|
||||||
|
runCommand("npm", "install")
|
||||||
|
runCommand("npm", "run", "build")
|
||||||
|
|
||||||
|
// Pack assets
|
||||||
|
fmt.Println("**** Packing Assets ****")
|
||||||
|
rendererDir, _ := filepath.Abs(filepath.Join(dir, "..", "lib", "renderer"))
|
||||||
|
os.Chdir(rendererDir)
|
||||||
|
runCommand("mewn")
|
||||||
|
cmdDir, _ := filepath.Abs(filepath.Join(dir, "..", "cmd"))
|
||||||
|
os.Chdir(cmdDir)
|
||||||
|
runCommand("mewn")
|
||||||
|
|
||||||
|
// Install Wails
|
||||||
|
fmt.Println("**** Installing Wails locally ****")
|
||||||
|
execDir, _ := filepath.Abs(filepath.Join(dir, "..", "cmd", "wails"))
|
||||||
|
os.Chdir(execDir)
|
||||||
|
runCommand("go", "install")
|
||||||
|
|
||||||
|
baseDir, _ := filepath.Abs(filepath.Join(dir, ".."))
|
||||||
|
os.Chdir(baseDir)
|
||||||
|
runCommand("go", "mod", "tidy")
|
||||||
|
}
|
||||||
@@ -3,11 +3,17 @@
|
|||||||
# Build runtime
|
# Build runtime
|
||||||
echo "**** Building Runtime ****"
|
echo "**** Building Runtime ****"
|
||||||
cd runtime/js
|
cd runtime/js
|
||||||
|
npm install
|
||||||
npm run build
|
npm run build
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|
||||||
echo "**** Packing Assets ****"
|
echo "**** Packing Assets ****"
|
||||||
|
cd cmd
|
||||||
mewn
|
mewn
|
||||||
|
cd ..
|
||||||
|
cd lib/renderer
|
||||||
|
mewn
|
||||||
|
cd ../..
|
||||||
|
|
||||||
echo "**** Installing Wails locally ****"
|
echo "**** Installing Wails locally ****"
|
||||||
cd cmd/wails
|
cd cmd/wails
|
||||||
|
|||||||
Reference in New Issue
Block a user