5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-02 11:10:47 +08:00

Initial implementation of runtime over http

This commit is contained in:
Lea Anthony 2023-01-27 21:05:53 +11:00
parent 8534b32a9f
commit 14b201bb65
No known key found for this signature in database
GPG Key ID: 33DAF7BB90A58405
22 changed files with 629 additions and 262 deletions

6
go.work Normal file
View File

@ -0,0 +1,6 @@
go 1.19
use (
v2
v3
)

View File

@ -6,16 +6,19 @@ github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keL
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/klauspost/cpuid/v2 v2.2.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc= github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=

View File

@ -14,6 +14,7 @@ import (
const ( const (
runtimeJSPath = "/wails/runtime.js" runtimeJSPath = "/wails/runtime.js"
ipcJSPath = "/wails/ipc.js" ipcJSPath = "/wails/ipc.js"
runtimePath = "/wails/runtime"
) )
type RuntimeAssets interface { type RuntimeAssets interface {
@ -22,6 +23,10 @@ type RuntimeAssets interface {
RuntimeDesktopJS() []byte RuntimeDesktopJS() []byte
} }
type RuntimeHandler interface {
HandleRuntimeCall(w http.ResponseWriter, r *http.Request)
}
type AssetServer struct { type AssetServer struct {
handler http.Handler handler http.Handler
wsHandler http.Handler wsHandler http.Handler
@ -34,6 +39,9 @@ type AssetServer struct {
servingFromDisk bool servingFromDisk bool
appendSpinnerToBody bool appendSpinnerToBody bool
// Use http based runtime
runtimeHandler RuntimeHandler
assetServerWebView assetServerWebView
} }
@ -77,6 +85,10 @@ func NewAssetServerWithHandler(handler http.Handler, bindingsJSON string, servin
return result, nil return result, nil
} }
func (d *AssetServer) UseRuntimeHandler(handler RuntimeHandler) {
d.runtimeHandler = handler
}
func (d *AssetServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) { func (d *AssetServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if isWebSocket(req) { if isWebSocket(req) {
// Forward WebSockets to the distinct websocket handler if it exists // Forward WebSockets to the distinct websocket handler if it exists
@ -122,6 +134,13 @@ func (d *AssetServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
case runtimeJSPath: case runtimeJSPath:
d.writeBlob(rw, path, d.runtimeJS) d.writeBlob(rw, path, d.runtimeJS)
case runtimePath:
if d.runtimeHandler != nil {
d.runtimeHandler.HandleRuntimeCall(rw, req)
} else {
d.handler.ServeHTTP(rw, req)
}
case ipcJSPath: case ipcJSPath:
content := d.runtime.DesktopIPC() content := d.runtime.DesktopIPC()
if d.ipcJS != nil { if d.ipcJS != nil {

View File

@ -5,6 +5,7 @@ go 1.19
require ( require (
github.com/go-task/task/v3 v3.20.0 github.com/go-task/task/v3 v3.20.0
github.com/jackmordaunt/icns/v2 v2.2.1 github.com/jackmordaunt/icns/v2 v2.2.1
github.com/json-iterator/go v1.1.12
github.com/leaanthony/clir v1.6.0 github.com/leaanthony/clir v1.6.0
github.com/leaanthony/gosod v1.0.3 github.com/leaanthony/gosod v1.0.3
github.com/leaanthony/winicon v1.0.0 github.com/leaanthony/winicon v1.0.0
@ -33,6 +34,8 @@ require (
github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mattn/go-zglob v0.0.4 // indirect github.com/mattn/go-zglob v0.0.4 // indirect
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect

View File

@ -26,6 +26,7 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg78
github.com/go-task/task/v3 v3.20.0 h1:pTavuhP+AiEpKLzh5I6Lja9Ux7ypYO5QMsEPTbhYEDc= github.com/go-task/task/v3 v3.20.0 h1:pTavuhP+AiEpKLzh5I6Lja9Ux7ypYO5QMsEPTbhYEDc=
github.com/go-task/task/v3 v3.20.0/go.mod h1:y7rWakbLR5gFElGgo6rA2dyr6vU/zNIDVfn3S4Of6OI= github.com/go-task/task/v3 v3.20.0/go.mod h1:y7rWakbLR5gFElGgo6rA2dyr6vU/zNIDVfn3S4Of6OI=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI= github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI=
@ -36,6 +37,8 @@ github.com/jackmordaunt/icns/v2 v2.2.1 h1:MGklwYP2yohKn2Bw7XxlF69LZe98S1vUfl5OvA
github.com/jackmordaunt/icns/v2 v2.2.1/go.mod h1:6aYIB9eSzyfHHMKqDf17Xrs1zetQPReAkiUSHzdw4cI= github.com/jackmordaunt/icns/v2 v2.2.1/go.mod h1:6aYIB9eSzyfHHMKqDf17Xrs1zetQPReAkiUSHzdw4cI=
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
@ -74,6 +77,10 @@ github.com/mattn/go-zglob v0.0.4 h1:LQi2iOm0/fGgu80AioIJ/1j9w9Oh+9DZ39J4VAGzHQM=
github.com/mattn/go-zglob v0.0.4/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY= github.com/mattn/go-zglob v0.0.4/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY=
github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
@ -107,6 +114,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=

View File

@ -10,46 +10,61 @@ The electron alternative for Go
/* jshint esversion: 9 */ /* jshint esversion: 9 */
const runtimeURL = window.location.origin + "/wails/runtime";
import {Call} from "./calls"; function runtimeCall(method, args) {
import {invoke} from "./ipc"; let url = new URL(runtimeURL);
url.searchParams.append("method", method);
if (args) {
for (let key in args) {
url.searchParams.append(key, args[key]);
}
}
return new Promise((resolve, reject) => {
fetch(url)
.then(response => {
if (response.ok) {
return response.json();
}
reject(Error(response.statusText));
})
.then(data => resolve(data))
.catch(error => reject(error));
});
}
export function newWindow(id) { export function newWindow(id) {
let call = function(method, args) {
if (id !== -1) {
args["windowID"] = id;
}
return runtimeCall("window." + method, args);
}
return { return {
// Reload: () => invoke('WR', id), // Reload: () => call('WR'),
// ReloadApp: () => invoke('WR', id), // ReloadApp: () => call('WR'),
// SetSystemDefaultTheme: () => invoke('WASDT', id), // SetSystemDefaultTheme: () => call('WASDT'),
// SetLightTheme: () => invoke('WALT', id), // SetLightTheme: () => call('WALT'),
// SetDarkTheme: () => invoke('WADT', id), // SetDarkTheme: () => call('WADT'),
Center: () => invoke('Wc', id), Center: () => call('Center'),
SetTitle: (title) => invoke('WT' + title, id), SetTitle: (title) => call('SetTitle', {title}),
Fullscreen: () => invoke('WF', id), Fullscreen: () => call('Fullscreen'),
UnFullscreen: () => invoke('Wf', id), UnFullscreen: () => call('UnFullscreen'),
SetSize: (width, height) => invoke('WS' + width + ',' + height, id), SetSize: (width, height) => call('SetSize', {width,height}),
GetSize: () => { GetSize: () => { return call('GetSize') },
return Call(":wails:WindowGetSize") SetMaxSize: (width, height) => call('SetMaxSize', {width,height}),
}, SetMinSize: (width, height) => call('SetMinSize', {width,height}),
SetMaxSize: (width, height) => invoke('WZ:' + width + ':' + height, id), SetAlwaysOnTop: (b) => call('SetAlwaysOnTop', {alwaysOnTop:b}),
SetMinSize: (width, height) => invoke('Wz:' + width + ':' + height, id), SetPosition: (x, y) => call('SetPosition', {x,y}),
SetAlwaysOnTop: (b) => invoke('WATP:' + (b ? '1' : '0'), id), GetPosition: () => { return call('GetPosition') },
SetPosition: (x, y) => invoke('Wp:' + x + ':' + y, id), Hide: () => call('Hide'),
GetPosition: () => { Maximise: () => call('Maximise'),
return Call(":wails:WindowGetPos") Show: () => call('Show'),
}, ToggleMaximise: () => call('ToggleMaximise'),
Hide: () => invoke('WH', id), UnMaximise: () => call('UnMaximise'),
Maximise: () => invoke('WM', id), Minimise: () => call('Minimise'),
Show: () => invoke('WS', id), UnMinimise: () => call('UnMinimise'),
ToggleMaximise: () => invoke('Wt', id), SetBackgroundColour: (r, g, b, a) => call('SetBackgroundColour', {R, G, B, A}),
UnMaximise: () => invoke('WU', id),
Minimise: () => invoke('Wm', id),
UnMinimise: () => invoke('Wu', id),
SetBackgroundColour: (R, G, B, A) =>
invoke('Wr:' + JSON.stringify({
r: R || 0,
g: G || 0,
b: B || 0,
a: A || 255}, id)
),
} }
} }

View File

@ -1 +1 @@
(()=>{var o=null;(function(){let s=function(e){for(var n=window[e.shift()];n&&e.length;)n=n[e.shift()];return n},t=s(["chrome","webview","postMessage"]),i=s(["webkit","messageHandlers","external","postMessage"]);if(!t&&!i){console.error("Unsupported Platform");return}t&&(o=e=>window.chrome.webview.postMessage(e)),i&&(o=e=>window.webkit.messageHandlers.external.postMessage(e))})();function r(s,t){o(t&&t!==-1?"WINDOWID:"+t+":"+s:s)}})(); (()=>{var o=null;(function(){let s=function(e){let n=window[e.shift()];for(;n&&e.length;)n=n[e.shift()];return n},t=s(["chrome","webview","postMessage"]),i=s(["webkit","messageHandlers","external","postMessage"]);if(!t&&!i){console.error("Unsupported Platform");return}t&&(o=e=>window.chrome.webview.postMessage(e)),i&&(o=e=>window.webkit.messageHandlers.external.postMessage(e))})();function l(s,t){o(t&&t!==-1?"WINDOWID:"+t+":"+s:s)}})();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
(()=>{var u=null;(function(){let e=function(n){for(var r=window[n.shift()];r&&n.length;)r=r[n.shift()];return r},t=e(["chrome","webview","postMessage"]),o=e(["webkit","messageHandlers","external","postMessage"]);if(!t&&!o){console.error("Unsupported Platform");return}t&&(u=n=>window.chrome.webview.postMessage(n)),o&&(u=n=>window.webkit.messageHandlers.external.postMessage(n))})();function i(e,t){u(t&&t!==-1?"WINDOWID:"+t+":"+e:e)}var c={};function y(){var e=new Uint32Array(1);return window.crypto.getRandomValues(e)[0]}function W(){return Math.random()*9007199254740991}var d;window.crypto?d=y:d=W;function f(e,t,o){o==null&&(o=0);let n=window.wails.window.ID();return new Promise(function(r,l){var s;do s=e+"-"+d();while(c[s]);var w;o>0&&(w=setTimeout(function(){l(Error("Call to "+e+" timed out. Request ID: "+s))},o)),c[s]={timeoutHandle:w,reject:l,resolve:r};try{let m={name:e,args:t,callbackID:s,windowID:n};window.WailsInvoke("C"+JSON.stringify(m))}catch(m){console.error(m)}})}window.ObfuscatedCall=(e,t,o)=>(o==null&&(o=0),new Promise(function(n,r){var l;do l=e+"-"+d();while(c[l]);var s;o>0&&(s=setTimeout(function(){r(Error("Call to method "+e+" timed out. Request ID: "+l))},o)),c[l]={timeoutHandle:s,reject:r,resolve:n};try{let w={id:e,args:t,callbackID:l,windowID:window.wails.window.ID()};window.WailsInvoke("c"+JSON.stringify(w))}catch(w){console.error(w)}}));function p(e){let t;try{t=JSON.parse(e)}catch(r){let l=`Invalid JSON passed to callback: ${r.message}. Message: ${e}`;throw runtime.LogDebug(l),new Error(l)}let o=t.callbackid,n=c[o];if(!n){let r=`Callback '${o}' not registered!!!`;throw console.error(r),new Error(r)}clearTimeout(n.timeoutHandle),delete c[o],t.error?n.reject(t.error):n.resolve(t.result)}var a={};function b(e){let t=e.name;if(a[t]){let o=a[t].slice();for(let n=0;n<a[t].length;n+=1){let r=a[t][n],l=e.data;r.Callback(l)&&o.splice(n,1)}o.length===0?S(t):a[t]=o}}function h(e){let t;try{t=JSON.parse(e)}catch{let n="Invalid JSON passed to Notify: "+e;throw new Error(n)}b(t)}function S(e){delete a[e],window.WailsInvoke("EX"+e)}window.go={};function v(e){try{e=JSON.parse(e)}catch(t){console.error(t)}window.go=window.go||{},Object.keys(e).forEach(t=>{window.go[t]=window.go[t]||{},Object.keys(e[t]).forEach(o=>{window.go[t][o]=window.go[t][o]||{},Object.keys(e[t][o]).forEach(n=>{window.go[t][o][n]=function(){let r=0;function l(){let s=[].slice.call(arguments);return f([t,o,n].join("."),s,r)}return l.setTimeout=function(s){r=s},l.getTimeout=function(){return r},l}()})})})}function g(e){return{Center:()=>i("Wc",e),SetTitle:t=>i("WT"+t,e),Fullscreen:()=>i("WF",e),UnFullscreen:()=>i("Wf",e),SetSize:(t,o)=>i("WS"+t+","+o,e),GetSize:()=>f(":wails:WindowGetSize"),SetMaxSize:(t,o)=>i("WZ:"+t+":"+o,e),SetMinSize:(t,o)=>i("Wz:"+t+":"+o,e),SetAlwaysOnTop:t=>i("WATP:"+(t?"1":"0"),e),SetPosition:(t,o)=>i("Wp:"+t+":"+o,e),GetPosition:()=>f(":wails:WindowGetPos"),Hide:()=>i("WH",e),Maximise:()=>i("WM",e),Show:()=>i("WS",e),ToggleMaximise:()=>i("Wt",e),UnMaximise:()=>i("WU",e),Minimise:()=>i("Wm",e),UnMinimise:()=>i("Wu",e),SetBackgroundColour:(t,o,n,r)=>i("Wr:"+JSON.stringify({r:t||0,g:o||0,b:n||0,a:r||255},e))}}window.wails={Callback:p,callbacks:c,EventsNotify:h,eventListeners:a,SetBindings:v};function x(e){return{Window:g(e),Show:()=>i("S"),Hide:()=>i("H"),Quit:()=>i("Q")}}window.runtime=x(-1);console.log("Wails v3.0.0 Debug Mode Enabled");})(); (()=>{var w=null;(function(){let o=function(n){let r=window[n.shift()];for(;r&&n.length;)r=r[n.shift()];return r},e=o(["chrome","webview","postMessage"]),t=o(["webkit","messageHandlers","external","postMessage"]);if(!e&&!t){console.error("Unsupported Platform");return}e&&(w=n=>window.chrome.webview.postMessage(n)),t&&(w=n=>window.webkit.messageHandlers.external.postMessage(n))})();function u(o,e){w(e&&e!==-1?"WINDOWID:"+e+":"+o:o)}var s={};function x(){let o=new Uint32Array(1);return window.crypto.getRandomValues(o)[0]}function g(){return Math.random()*9007199254740991}var f;window.crypto?f=x:f=g;function m(o,e,t){t==null&&(t=0);let n=window.wails.window.ID();return new Promise(function(r,i){let l;do l=o+"-"+f();while(s[l]);let a;t>0&&(a=setTimeout(function(){i(Error("Call to "+o+" timed out. Request ID: "+l))},t)),s[l]={timeoutHandle:a,reject:i,resolve:r};try{let d={name:o,args:e,callbackID:l,windowID:n};window.WailsInvoke("C"+JSON.stringify(d))}catch(d){console.error(d)}})}window.ObfuscatedCall=(o,e,t)=>(t==null&&(t=0),new Promise(function(n,r){let i;do i=o+"-"+f();while(s[i]);let l;t>0&&(l=setTimeout(function(){r(Error("Call to method "+o+" timed out. Request ID: "+i))},t)),s[i]={timeoutHandle:l,reject:r,resolve:n};try{let a={id:o,args:e,callbackID:i,windowID:window.wails.window.ID()};window.WailsInvoke("c"+JSON.stringify(a))}catch(a){console.error(a)}}));function h(o){let e;try{e=JSON.parse(o)}catch(r){let i=`Invalid JSON passed to callback: ${r.message}. Message: ${o}`;throw runtime.LogDebug(i),new Error(i)}let t=e.callbackid,n=s[t];if(!n){let r=`Callback '${t}' not registered!!!`;throw console.error(r),new Error(r)}clearTimeout(n.timeoutHandle),delete s[t],e.error?n.reject(e.error):n.resolve(e.result)}var c={};function b(o){let e=o.name;if(c[e]){let t=c[e].slice();for(let n=0;n<c[e].length;n+=1){let r=c[e][n],i=o.data;r.Callback(i)&&t.splice(n,1)}t.length===0?k(e):c[e]=t}}function p(o){let e;try{e=JSON.parse(o)}catch{let n="Invalid JSON passed to Notify: "+o;throw new Error(n)}b(e)}function k(o){delete c[o],window.WailsInvoke("EX"+o)}window.go={};function S(o){try{o=JSON.parse(o)}catch(e){console.error(e)}window.go=window.go||{},Object.keys(o).forEach(e=>{window.go[e]=window.go[e]||{},Object.keys(o[e]).forEach(t=>{window.go[e][t]=window.go[e][t]||{},Object.keys(o[e][t]).forEach(n=>{window.go[e][t][n]=function(){let r=0;function i(){let l=[].slice.call(arguments);return m([e,t,n].join("."),l,r)}return i.setTimeout=function(l){r=l},i.getTimeout=function(){return r},i}()})})})}var v=window.location.origin+"/wails/runtime";function E(o,e){let t=new URL(v);if(t.searchParams.append("method",o),e)for(let n in e)t.searchParams.append(n,e[n]);return new Promise((n,r)=>{fetch(t).then(i=>{if(i.ok)return i.json();r(Error(i.statusText))}).then(i=>n(i)).catch(i=>r(i))})}function y(o){let e=function(t,n){return o!==-1&&(n.windowID=o),E("window."+t,n)};return{Center:()=>e("Center"),SetTitle:t=>e("SetTitle",{title:t}),Fullscreen:()=>e("Fullscreen"),UnFullscreen:()=>e("UnFullscreen"),SetSize:(t,n)=>e("SetSize",{width:t,height:n}),GetSize:()=>e("GetSize"),SetMaxSize:(t,n)=>e("SetMaxSize",{width:t,height:n}),SetMinSize:(t,n)=>e("SetMinSize",{width:t,height:n}),SetAlwaysOnTop:t=>e("SetAlwaysOnTop",{alwaysOnTop:t}),SetPosition:(t,n)=>e("SetPosition",{x:t,y:n}),GetPosition:()=>e("GetPosition"),Hide:()=>e("Hide"),Maximise:()=>e("Maximise"),Show:()=>e("Show"),ToggleMaximise:()=>e("ToggleMaximise"),UnMaximise:()=>e("UnMaximise"),Minimise:()=>e("Minimise"),UnMinimise:()=>e("UnMinimise"),SetBackgroundColour:(t,n,r,i)=>e("SetBackgroundColour",{R,G,B,A})}}window.wails={Callback:h,callbacks:s,EventsNotify:p,eventListeners:c,SetBindings:S};function O(o){return{Window:y(o),Show:()=>u("S"),Hide:()=>u("H"),Quit:()=>u("Q")}}window.runtime=O(-1);console.log("Wails v3.0.0 Debug Mode Enabled");})();

View File

@ -1 +1 @@
(()=>{var u=null;(function(){let e=function(n){for(var r=window[n.shift()];r&&n.length;)r=r[n.shift()];return r},t=e(["chrome","webview","postMessage"]),o=e(["webkit","messageHandlers","external","postMessage"]);if(!t&&!o){console.error("Unsupported Platform");return}t&&(u=n=>window.chrome.webview.postMessage(n)),o&&(u=n=>window.webkit.messageHandlers.external.postMessage(n))})();function i(e,t){u(t&&t!==-1?"WINDOWID:"+t+":"+e:e)}var c={};function y(){var e=new Uint32Array(1);return window.crypto.getRandomValues(e)[0]}function W(){return Math.random()*9007199254740991}var d;window.crypto?d=y:d=W;function f(e,t,o){o==null&&(o=0);let n=window.wails.window.ID();return new Promise(function(r,l){var s;do s=e+"-"+d();while(c[s]);var w;o>0&&(w=setTimeout(function(){l(Error("Call to "+e+" timed out. Request ID: "+s))},o)),c[s]={timeoutHandle:w,reject:l,resolve:r};try{let m={name:e,args:t,callbackID:s,windowID:n};window.WailsInvoke("C"+JSON.stringify(m))}catch(m){console.error(m)}})}window.ObfuscatedCall=(e,t,o)=>(o==null&&(o=0),new Promise(function(n,r){var l;do l=e+"-"+d();while(c[l]);var s;o>0&&(s=setTimeout(function(){r(Error("Call to method "+e+" timed out. Request ID: "+l))},o)),c[l]={timeoutHandle:s,reject:r,resolve:n};try{let w={id:e,args:t,callbackID:l,windowID:window.wails.window.ID()};window.WailsInvoke("c"+JSON.stringify(w))}catch(w){console.error(w)}}));function p(e){let t;try{t=JSON.parse(e)}catch(r){let l=`Invalid JSON passed to callback: ${r.message}. Message: ${e}`;throw runtime.LogDebug(l),new Error(l)}let o=t.callbackid,n=c[o];if(!n){let r=`Callback '${o}' not registered!!!`;throw console.error(r),new Error(r)}clearTimeout(n.timeoutHandle),delete c[o],t.error?n.reject(t.error):n.resolve(t.result)}var a={};function b(e){let t=e.name;if(a[t]){let o=a[t].slice();for(let n=0;n<a[t].length;n+=1){let r=a[t][n],l=e.data;r.Callback(l)&&o.splice(n,1)}o.length===0?S(t):a[t]=o}}function h(e){let t;try{t=JSON.parse(e)}catch{let n="Invalid JSON passed to Notify: "+e;throw new Error(n)}b(t)}function S(e){delete a[e],window.WailsInvoke("EX"+e)}window.go={};function v(e){try{e=JSON.parse(e)}catch(t){console.error(t)}window.go=window.go||{},Object.keys(e).forEach(t=>{window.go[t]=window.go[t]||{},Object.keys(e[t]).forEach(o=>{window.go[t][o]=window.go[t][o]||{},Object.keys(e[t][o]).forEach(n=>{window.go[t][o][n]=function(){let r=0;function l(){let s=[].slice.call(arguments);return f([t,o,n].join("."),s,r)}return l.setTimeout=function(s){r=s},l.getTimeout=function(){return r},l}()})})})}function g(e){return{Center:()=>i("Wc",e),SetTitle:t=>i("WT"+t,e),Fullscreen:()=>i("WF",e),UnFullscreen:()=>i("Wf",e),SetSize:(t,o)=>i("WS"+t+","+o,e),GetSize:()=>f(":wails:WindowGetSize"),SetMaxSize:(t,o)=>i("WZ:"+t+":"+o,e),SetMinSize:(t,o)=>i("Wz:"+t+":"+o,e),SetAlwaysOnTop:t=>i("WATP:"+(t?"1":"0"),e),SetPosition:(t,o)=>i("Wp:"+t+":"+o,e),GetPosition:()=>f(":wails:WindowGetPos"),Hide:()=>i("WH",e),Maximise:()=>i("WM",e),Show:()=>i("WS",e),ToggleMaximise:()=>i("Wt",e),UnMaximise:()=>i("WU",e),Minimise:()=>i("Wm",e),UnMinimise:()=>i("Wu",e),SetBackgroundColour:(t,o,n,r)=>i("Wr:"+JSON.stringify({r:t||0,g:o||0,b:n||0,a:r||255},e))}}window.wails={Callback:p,callbacks:c,EventsNotify:h,eventListeners:a,SetBindings:v};function x(e){return{Window:g(e),Show:()=>i("S"),Hide:()=>i("H"),Quit:()=>i("Q")}}window.runtime=x(-1);console.log("Wails v3.0.0 Debug Mode Enabled");})(); (()=>{var w=null;(function(){let o=function(n){let r=window[n.shift()];for(;r&&n.length;)r=r[n.shift()];return r},e=o(["chrome","webview","postMessage"]),t=o(["webkit","messageHandlers","external","postMessage"]);if(!e&&!t){console.error("Unsupported Platform");return}e&&(w=n=>window.chrome.webview.postMessage(n)),t&&(w=n=>window.webkit.messageHandlers.external.postMessage(n))})();function u(o,e){w(e&&e!==-1?"WINDOWID:"+e+":"+o:o)}var s={};function x(){let o=new Uint32Array(1);return window.crypto.getRandomValues(o)[0]}function g(){return Math.random()*9007199254740991}var f;window.crypto?f=x:f=g;function m(o,e,t){t==null&&(t=0);let n=window.wails.window.ID();return new Promise(function(r,i){let l;do l=o+"-"+f();while(s[l]);let a;t>0&&(a=setTimeout(function(){i(Error("Call to "+o+" timed out. Request ID: "+l))},t)),s[l]={timeoutHandle:a,reject:i,resolve:r};try{let d={name:o,args:e,callbackID:l,windowID:n};window.WailsInvoke("C"+JSON.stringify(d))}catch(d){console.error(d)}})}window.ObfuscatedCall=(o,e,t)=>(t==null&&(t=0),new Promise(function(n,r){let i;do i=o+"-"+f();while(s[i]);let l;t>0&&(l=setTimeout(function(){r(Error("Call to method "+o+" timed out. Request ID: "+i))},t)),s[i]={timeoutHandle:l,reject:r,resolve:n};try{let a={id:o,args:e,callbackID:i,windowID:window.wails.window.ID()};window.WailsInvoke("c"+JSON.stringify(a))}catch(a){console.error(a)}}));function h(o){let e;try{e=JSON.parse(o)}catch(r){let i=`Invalid JSON passed to callback: ${r.message}. Message: ${o}`;throw runtime.LogDebug(i),new Error(i)}let t=e.callbackid,n=s[t];if(!n){let r=`Callback '${t}' not registered!!!`;throw console.error(r),new Error(r)}clearTimeout(n.timeoutHandle),delete s[t],e.error?n.reject(e.error):n.resolve(e.result)}var c={};function b(o){let e=o.name;if(c[e]){let t=c[e].slice();for(let n=0;n<c[e].length;n+=1){let r=c[e][n],i=o.data;r.Callback(i)&&t.splice(n,1)}t.length===0?k(e):c[e]=t}}function p(o){let e;try{e=JSON.parse(o)}catch{let n="Invalid JSON passed to Notify: "+o;throw new Error(n)}b(e)}function k(o){delete c[o],window.WailsInvoke("EX"+o)}window.go={};function S(o){try{o=JSON.parse(o)}catch(e){console.error(e)}window.go=window.go||{},Object.keys(o).forEach(e=>{window.go[e]=window.go[e]||{},Object.keys(o[e]).forEach(t=>{window.go[e][t]=window.go[e][t]||{},Object.keys(o[e][t]).forEach(n=>{window.go[e][t][n]=function(){let r=0;function i(){let l=[].slice.call(arguments);return m([e,t,n].join("."),l,r)}return i.setTimeout=function(l){r=l},i.getTimeout=function(){return r},i}()})})})}var v=window.location.origin+"/wails/runtime";function E(o,e){let t=new URL(v);if(t.searchParams.append("method",o),e)for(let n in e)t.searchParams.append(n,e[n]);return new Promise((n,r)=>{fetch(t).then(i=>{if(i.ok)return i.json();r(Error(i.statusText))}).then(i=>n(i)).catch(i=>r(i))})}function y(o){let e=function(t,n){return o!==-1&&(n.windowID=o),E("window."+t,n)};return{Center:()=>e("Center"),SetTitle:t=>e("SetTitle",{title:t}),Fullscreen:()=>e("Fullscreen"),UnFullscreen:()=>e("UnFullscreen"),SetSize:(t,n)=>e("SetSize",{width:t,height:n}),GetSize:()=>e("GetSize"),SetMaxSize:(t,n)=>e("SetMaxSize",{width:t,height:n}),SetMinSize:(t,n)=>e("SetMinSize",{width:t,height:n}),SetAlwaysOnTop:t=>e("SetAlwaysOnTop",{alwaysOnTop:t}),SetPosition:(t,n)=>e("SetPosition",{x:t,y:n}),GetPosition:()=>e("GetPosition"),Hide:()=>e("Hide"),Maximise:()=>e("Maximise"),Show:()=>e("Show"),ToggleMaximise:()=>e("ToggleMaximise"),UnMaximise:()=>e("UnMaximise"),Minimise:()=>e("Minimise"),UnMinimise:()=>e("UnMinimise"),SetBackgroundColour:(t,n,r,i)=>e("SetBackgroundColour",{R,G,B,A})}}window.wails={Callback:h,callbacks:s,EventsNotify:p,eventListeners:c,SetBindings:S};function O(o){return{Window:y(o),Show:()=>u("S"),Hide:()=>u("H"),Quit:()=>u("Q")}}window.runtime=O(-1);console.log("Wails v3.0.0 Debug Mode Enabled");})();

View File

@ -1 +1 @@
(()=>{var u=null;(function(){let e=function(n){for(var r=window[n.shift()];r&&n.length;)r=r[n.shift()];return r},t=e(["chrome","webview","postMessage"]),o=e(["webkit","messageHandlers","external","postMessage"]);if(!t&&!o){console.error("Unsupported Platform");return}t&&(u=n=>window.chrome.webview.postMessage(n)),o&&(u=n=>window.webkit.messageHandlers.external.postMessage(n))})();function i(e,t){u(t&&t!==-1?"WINDOWID:"+t+":"+e:e)}var c={};function y(){var e=new Uint32Array(1);return window.crypto.getRandomValues(e)[0]}function W(){return Math.random()*9007199254740991}var d;window.crypto?d=y:d=W;function f(e,t,o){o==null&&(o=0);let n=window.wails.window.ID();return new Promise(function(r,l){var s;do s=e+"-"+d();while(c[s]);var w;o>0&&(w=setTimeout(function(){l(Error("Call to "+e+" timed out. Request ID: "+s))},o)),c[s]={timeoutHandle:w,reject:l,resolve:r};try{let m={name:e,args:t,callbackID:s,windowID:n};window.WailsInvoke("C"+JSON.stringify(m))}catch(m){console.error(m)}})}window.ObfuscatedCall=(e,t,o)=>(o==null&&(o=0),new Promise(function(n,r){var l;do l=e+"-"+d();while(c[l]);var s;o>0&&(s=setTimeout(function(){r(Error("Call to method "+e+" timed out. Request ID: "+l))},o)),c[l]={timeoutHandle:s,reject:r,resolve:n};try{let w={id:e,args:t,callbackID:l,windowID:window.wails.window.ID()};window.WailsInvoke("c"+JSON.stringify(w))}catch(w){console.error(w)}}));function p(e){let t;try{t=JSON.parse(e)}catch(r){let l=`Invalid JSON passed to callback: ${r.message}. Message: ${e}`;throw runtime.LogDebug(l),new Error(l)}let o=t.callbackid,n=c[o];if(!n){let r=`Callback '${o}' not registered!!!`;throw console.error(r),new Error(r)}clearTimeout(n.timeoutHandle),delete c[o],t.error?n.reject(t.error):n.resolve(t.result)}var a={};function b(e){let t=e.name;if(a[t]){let o=a[t].slice();for(let n=0;n<a[t].length;n+=1){let r=a[t][n],l=e.data;r.Callback(l)&&o.splice(n,1)}o.length===0?S(t):a[t]=o}}function h(e){let t;try{t=JSON.parse(e)}catch{let n="Invalid JSON passed to Notify: "+e;throw new Error(n)}b(t)}function S(e){delete a[e],window.WailsInvoke("EX"+e)}window.go={};function v(e){try{e=JSON.parse(e)}catch(t){console.error(t)}window.go=window.go||{},Object.keys(e).forEach(t=>{window.go[t]=window.go[t]||{},Object.keys(e[t]).forEach(o=>{window.go[t][o]=window.go[t][o]||{},Object.keys(e[t][o]).forEach(n=>{window.go[t][o][n]=function(){let r=0;function l(){let s=[].slice.call(arguments);return f([t,o,n].join("."),s,r)}return l.setTimeout=function(s){r=s},l.getTimeout=function(){return r},l}()})})})}function g(e){return{Center:()=>i("Wc",e),SetTitle:t=>i("WT"+t,e),Fullscreen:()=>i("WF",e),UnFullscreen:()=>i("Wf",e),SetSize:(t,o)=>i("WS"+t+","+o,e),GetSize:()=>f(":wails:WindowGetSize"),SetMaxSize:(t,o)=>i("WZ:"+t+":"+o,e),SetMinSize:(t,o)=>i("Wz:"+t+":"+o,e),SetAlwaysOnTop:t=>i("WATP:"+(t?"1":"0"),e),SetPosition:(t,o)=>i("Wp:"+t+":"+o,e),GetPosition:()=>f(":wails:WindowGetPos"),Hide:()=>i("WH",e),Maximise:()=>i("WM",e),Show:()=>i("WS",e),ToggleMaximise:()=>i("Wt",e),UnMaximise:()=>i("WU",e),Minimise:()=>i("Wm",e),UnMinimise:()=>i("Wu",e),SetBackgroundColour:(t,o,n,r)=>i("Wr:"+JSON.stringify({r:t||0,g:o||0,b:n||0,a:r||255},e))}}window.wails={Callback:p,callbacks:c,EventsNotify:h,eventListeners:a,SetBindings:v};function x(e){return{Window:g(e),Show:()=>i("S"),Hide:()=>i("H"),Quit:()=>i("Q")}}window.runtime=x(-1);console.log("Wails v3.0.0 Debug Mode Enabled");})(); (()=>{var w=null;(function(){let o=function(n){let r=window[n.shift()];for(;r&&n.length;)r=r[n.shift()];return r},e=o(["chrome","webview","postMessage"]),t=o(["webkit","messageHandlers","external","postMessage"]);if(!e&&!t){console.error("Unsupported Platform");return}e&&(w=n=>window.chrome.webview.postMessage(n)),t&&(w=n=>window.webkit.messageHandlers.external.postMessage(n))})();function u(o,e){w(e&&e!==-1?"WINDOWID:"+e+":"+o:o)}var s={};function x(){let o=new Uint32Array(1);return window.crypto.getRandomValues(o)[0]}function g(){return Math.random()*9007199254740991}var f;window.crypto?f=x:f=g;function m(o,e,t){t==null&&(t=0);let n=window.wails.window.ID();return new Promise(function(r,i){let l;do l=o+"-"+f();while(s[l]);let a;t>0&&(a=setTimeout(function(){i(Error("Call to "+o+" timed out. Request ID: "+l))},t)),s[l]={timeoutHandle:a,reject:i,resolve:r};try{let d={name:o,args:e,callbackID:l,windowID:n};window.WailsInvoke("C"+JSON.stringify(d))}catch(d){console.error(d)}})}window.ObfuscatedCall=(o,e,t)=>(t==null&&(t=0),new Promise(function(n,r){let i;do i=o+"-"+f();while(s[i]);let l;t>0&&(l=setTimeout(function(){r(Error("Call to method "+o+" timed out. Request ID: "+i))},t)),s[i]={timeoutHandle:l,reject:r,resolve:n};try{let a={id:o,args:e,callbackID:i,windowID:window.wails.window.ID()};window.WailsInvoke("c"+JSON.stringify(a))}catch(a){console.error(a)}}));function h(o){let e;try{e=JSON.parse(o)}catch(r){let i=`Invalid JSON passed to callback: ${r.message}. Message: ${o}`;throw runtime.LogDebug(i),new Error(i)}let t=e.callbackid,n=s[t];if(!n){let r=`Callback '${t}' not registered!!!`;throw console.error(r),new Error(r)}clearTimeout(n.timeoutHandle),delete s[t],e.error?n.reject(e.error):n.resolve(e.result)}var c={};function b(o){let e=o.name;if(c[e]){let t=c[e].slice();for(let n=0;n<c[e].length;n+=1){let r=c[e][n],i=o.data;r.Callback(i)&&t.splice(n,1)}t.length===0?k(e):c[e]=t}}function p(o){let e;try{e=JSON.parse(o)}catch{let n="Invalid JSON passed to Notify: "+o;throw new Error(n)}b(e)}function k(o){delete c[o],window.WailsInvoke("EX"+o)}window.go={};function S(o){try{o=JSON.parse(o)}catch(e){console.error(e)}window.go=window.go||{},Object.keys(o).forEach(e=>{window.go[e]=window.go[e]||{},Object.keys(o[e]).forEach(t=>{window.go[e][t]=window.go[e][t]||{},Object.keys(o[e][t]).forEach(n=>{window.go[e][t][n]=function(){let r=0;function i(){let l=[].slice.call(arguments);return m([e,t,n].join("."),l,r)}return i.setTimeout=function(l){r=l},i.getTimeout=function(){return r},i}()})})})}var v=window.location.origin+"/wails/runtime";function E(o,e){let t=new URL(v);if(t.searchParams.append("method",o),e)for(let n in e)t.searchParams.append(n,e[n]);return new Promise((n,r)=>{fetch(t).then(i=>{if(i.ok)return i.json();r(Error(i.statusText))}).then(i=>n(i)).catch(i=>r(i))})}function y(o){let e=function(t,n){return o!==-1&&(n.windowID=o),E("window."+t,n)};return{Center:()=>e("Center"),SetTitle:t=>e("SetTitle",{title:t}),Fullscreen:()=>e("Fullscreen"),UnFullscreen:()=>e("UnFullscreen"),SetSize:(t,n)=>e("SetSize",{width:t,height:n}),GetSize:()=>e("GetSize"),SetMaxSize:(t,n)=>e("SetMaxSize",{width:t,height:n}),SetMinSize:(t,n)=>e("SetMinSize",{width:t,height:n}),SetAlwaysOnTop:t=>e("SetAlwaysOnTop",{alwaysOnTop:t}),SetPosition:(t,n)=>e("SetPosition",{x:t,y:n}),GetPosition:()=>e("GetPosition"),Hide:()=>e("Hide"),Maximise:()=>e("Maximise"),Show:()=>e("Show"),ToggleMaximise:()=>e("ToggleMaximise"),UnMaximise:()=>e("UnMaximise"),Minimise:()=>e("Minimise"),UnMinimise:()=>e("UnMinimise"),SetBackgroundColour:(t,n,r,i)=>e("SetBackgroundColour",{R,G,B,A})}}window.wails={Callback:h,callbacks:s,EventsNotify:p,eventListeners:c,SetBindings:S};function O(o){return{Window:y(o),Show:()=>u("S"),Hide:()=>u("H"),Quit:()=>u("Q")}}window.runtime=O(-1);console.log("Wails v3.0.0 Debug Mode Enabled");})();

View File

@ -114,6 +114,13 @@ func (a *App) getSystemTrayID() uint {
a.systemTrayID++ a.systemTrayID++
return a.systemTrayID return a.systemTrayID
} }
func (a *App) getWindowForID(id uint) *WebviewWindow {
a.windowsLock.Lock()
defer a.windowsLock.Unlock()
return a.windows[id]
}
func (a *App) On(eventType events.ApplicationEventType, callback func()) { func (a *App) On(eventType events.ApplicationEventType, callback func()) {
eventID := uint(eventType) eventID := uint(eventType)
a.applicationEventListenersLock.Lock() a.applicationEventListenersLock.Lock()

View File

@ -163,7 +163,7 @@ func newRole(role Role) *MenuItem {
case ToggleDevTools: case ToggleDevTools:
return newToggleDevToolsMenuItem() return newToggleDevToolsMenuItem()
case ResetZoom: case ResetZoom:
return newResetZoomMenuItem() return newZoomResetMenuItem()
case ZoomIn: case ZoomIn:
return newZoomInMenuItem() return newZoomInMenuItem()
case ZoomOut: case ZoomOut:

View File

@ -564,14 +564,14 @@ func newToggleDevToolsMenuItem() *MenuItem {
}) })
} }
func newResetZoomMenuItem() *MenuItem { func newZoomResetMenuItem() *MenuItem {
// reset zoom menu item // reset zoom menu item
return newMenuItem("Actual Size"). return newMenuItem("Actual Size").
SetAccelerator("CmdOrCtrl+0"). SetAccelerator("CmdOrCtrl+0").
OnClick(func(ctx *Context) { OnClick(func(ctx *Context) {
currentWindow := globalApplication.CurrentWindow() currentWindow := globalApplication.CurrentWindow()
if currentWindow != nil { if currentWindow != nil {
currentWindow.ResetZoom() currentWindow.ZoomReset()
} }
}) })
} }

View File

@ -2,7 +2,10 @@ package application
import ( import (
"fmt" "fmt"
"net/http"
"strings" "strings"
jsoniter "github.com/json-iterator/go"
) )
type MessageProcessor struct { type MessageProcessor struct {
@ -15,46 +18,41 @@ func NewMessageProcessor(w *WebviewWindow) *MessageProcessor {
} }
} }
func (m *MessageProcessor) ProcessMessage(message string) { func (m *MessageProcessor) httpError(rw http.ResponseWriter, message string, args ...any) {
m.Error(message, args...)
rw.WriteHeader(http.StatusBadRequest)
rw.Write([]byte(message))
}
// TODO: Implement calls to other windows func (m *MessageProcessor) HandleRuntimeCall(rw http.ResponseWriter, r *http.Request) {
// Check for prefix "WINDOWID" m.Info("Processing runtime call")
// If prefix exists, get window ID by parsing: "WINDOWID:12:MESSAGE" // Read "method" from query string
method := r.URL.Query().Get("method")
if strings.HasPrefix(message, "WINDOWID") { if method == "" {
m.Error("Window ID prefix not yet implemented") m.httpError(rw, "No method specified")
return return
} }
splitMethod := strings.Split(method, ".")
window := m.window if len(splitMethod) != 2 {
m.httpError(rw, "Invalid method format")
if message == "" {
m.Error("Blank message received")
return return
} }
m.Info("Processing message: %s", message) // Get the object
switch message[0] { object := splitMethod[0]
//case 'L': // Get the method
// m.processLogMessage(message) method = splitMethod[1]
//case 'E':
// return m.processEventMessage(message) switch object {
//case 'C': case "window":
// return m.processCallMessage(message) m.processWindowMethod(method, rw, r)
//case 'c':
// return m.processSecureCallMessage(message)
case 'W':
m.processWindowMessage(message, window)
//case 'B':
// return m.processBrowserMessage(message)
case 'Q':
globalApplication.Quit()
case 'S':
//globalApplication.Show()
case 'H':
//globalApplication.Hide()
default: default:
m.Error("Unknown message from front end:", message) m.httpError(rw, "Unknown runtime call: %s", object)
} }
}
func (m *MessageProcessor) ProcessMessage(message string) {
m.Info("ProcessMessage from front end:", message)
} }
func (m *MessageProcessor) Error(message string, args ...any) { func (m *MessageProcessor) Error(message string, args ...any) {
@ -64,3 +62,23 @@ func (m *MessageProcessor) Error(message string, args ...any) {
func (m *MessageProcessor) Info(message string, args ...any) { func (m *MessageProcessor) Info(message string, args ...any) {
fmt.Printf("[MessageProcessor] Info: "+message, args...) fmt.Printf("[MessageProcessor] Info: "+message, args...)
} }
func (m *MessageProcessor) json(rw http.ResponseWriter, data any) {
// convert data to json
var jsonPayload = []byte("{}")
var err error
if data != nil {
jsonPayload, err = jsoniter.Marshal(data)
if err != nil {
m.Error("Unable to convert data to JSON. Please report this to the Wails team! Error: %s", err)
return
}
}
_, err = rw.Write(jsonPayload)
if err != nil {
m.Error("Unable to write json payload. Please report this to the Wails team! Error: %s", err)
return
}
rw.WriteHeader(http.StatusOK)
rw.Header().Set("Content-Type", "application/json")
}

View File

@ -0,0 +1,95 @@
package application
import "strconv"
type QueryParams map[string][]string
func (qp QueryParams) String(key string) *string {
if qp == nil {
return nil
}
values := qp[key]
if len(values) == 0 {
return nil
}
return &values[0]
}
func (qp QueryParams) Int(key string) *int {
val := qp.String(key)
if val == nil {
return nil
}
result, err := strconv.Atoi(*val)
if err != nil {
return nil
}
return &result
}
func (qp QueryParams) UInt8(key string) *uint8 {
val := qp.String(key)
if val == nil {
return nil
}
intResult, err := strconv.Atoi(*val)
if err != nil {
return nil
}
if intResult < 0 {
intResult = 0
}
if intResult > 255 {
intResult = 255
}
var result = uint8(intResult)
return &result
}
func (qp QueryParams) UInt(key string) *uint {
val := qp.String(key)
if val == nil {
return nil
}
intResult, err := strconv.Atoi(*val)
if err != nil {
return nil
}
if intResult < 0 {
intResult = 0
}
if intResult > 255 {
intResult = 255
}
var result = uint(intResult)
return &result
}
func (qp QueryParams) Bool(key string) *bool {
val := qp.String(key)
if val == nil {
return nil
}
result, err := strconv.ParseBool(*val)
if err != nil {
return nil
}
return &result
}
func (qp QueryParams) Float64(key string) *float64 {
val := qp.String(key)
if val == nil {
return nil
}
result, err := strconv.ParseFloat(*val, 64)
if err != nil {
return nil
}
return &result
}

View File

@ -1,95 +1,191 @@
package application package application
import ( import (
"encoding/json" "net/http"
"strconv"
"strings"
"github.com/wailsapp/wails/v3/pkg/options" "github.com/wailsapp/wails/v3/pkg/options"
) )
func (m *MessageProcessor) mustAtoI(input string) int { func (m *MessageProcessor) processWindowMethod(method string, rw http.ResponseWriter, r *http.Request) {
result, err := strconv.Atoi(input)
if err != nil {
m.Error("cannot convert %s to integer!", input)
}
return result
}
func (m *MessageProcessor) processWindowMessage(message string, window *WebviewWindow) { params := QueryParams(r.URL.Query())
if len(message) < 2 {
m.Error("Invalid Window Message: " + message) var targetWindow = m.window
windowID := params.UInt("windowID")
if windowID != nil {
// Get window for ID
targetWindow = globalApplication.getWindowForID(*windowID)
if targetWindow == nil {
m.Error("Window ID %s not found", *windowID)
return
}
} }
switch message[1] { switch method {
case 'A': case "SetTitle":
switch message[2:] { title := params.String("title")
//case "SDT": if title == nil {
// go window.WindowSetSystemDefaultTheme() m.Error("SetTitle: title is required")
//case "LT": return
// go window.SetLightTheme()
//case "DT":
// go window.SetDarkTheme()
case "TP:0", "TP:1":
if message[2:] == "TP:0" {
go window.SetAlwaysOnTop(false)
} else if message[2:] == "TP:1" {
go window.SetAlwaysOnTop(true)
}
} }
case 'c': targetWindow.SetTitle(*title)
go window.Center() m.json(rw, nil)
case 'T': case "SetSize":
title := message[2:] width := params.Int("width")
go window.SetTitle(title) height := params.Int("height")
case 'F': if width == nil || height == nil {
go window.Fullscreen() m.Error("Invalid SetSize message")
case 'f': return
go window.UnFullscreen()
case 's':
parts := strings.Split(message[3:], ":")
w := m.mustAtoI(parts[0])
h := m.mustAtoI(parts[1])
go window.SetSize(w, h)
case 'p':
parts := strings.Split(message[3:], ":")
x := m.mustAtoI(parts[0])
y := m.mustAtoI(parts[1])
go window.SetPosition(x, y)
case 'H':
go window.Hide()
case 'S':
go window.Show()
//case 'R':
// go window.ReloadApp()
case 'r':
var rgba options.RGBA
err := json.Unmarshal([]byte(message[3:]), &rgba)
if err != nil {
m.Error("Invalid RGBA Message: %s", err.Error())
} }
go window.SetBackgroundColour(&rgba) targetWindow.SetSize(*width, *height)
case 'M': m.json(rw, nil)
go window.Maximise() case "SetPosition":
//case 't': x := params.Int("x")
// go window.ToggleMaximise() y := params.Int("y")
case 'U': if x == nil || y == nil {
go window.UnMaximise() m.Error("Invalid SetPosition message")
case 'm': return
go window.Minimise() }
case 'u': targetWindow.SetPosition(*x, *y)
go window.UnMinimise() m.json(rw, nil)
case 'Z': case "Fullscreen":
parts := strings.Split(message[3:], ":") targetWindow.Fullscreen()
w := m.mustAtoI(parts[0]) m.json(rw, nil)
h := m.mustAtoI(parts[1]) case "UnFullscreen":
go window.SetMaxSize(w, h) targetWindow.UnFullscreen()
case 'z': m.json(rw, nil)
parts := strings.Split(message[3:], ":") case "Minimise":
w := m.mustAtoI(parts[0]) targetWindow.Minimize()
h := m.mustAtoI(parts[1]) m.json(rw, nil)
go window.SetMinSize(w, h) case "UnMinimise":
targetWindow.UnMinimise()
m.json(rw, nil)
case "Maximise":
targetWindow.Maximise()
m.json(rw, nil)
case "UnMaximise":
targetWindow.UnMaximise()
m.json(rw, nil)
case "Show":
targetWindow.Show()
m.json(rw, nil)
case "Hide":
targetWindow.Hide()
m.json(rw, nil)
case "Close":
targetWindow.Close()
m.json(rw, nil)
case "Center":
targetWindow.Center()
m.json(rw, nil)
case "Size":
width, height := targetWindow.Size()
m.json(rw, map[string]interface{}{
"width": width,
"height": height,
})
case "Position":
x, y := targetWindow.Position()
m.json(rw, map[string]interface{}{
"x": x,
"y": y,
})
case "SetBackgroundColour":
r := params.UInt8("r")
if r == nil {
m.Error("Invalid SetBackgroundColour message: 'r' value required")
return
}
g := params.UInt8("g")
if g == nil {
m.Error("Invalid SetBackgroundColour message: 'g' value required")
return
}
b := params.UInt8("b")
if b == nil {
m.Error("Invalid SetBackgroundColour message: 'b' value required")
return
}
a := params.UInt8("a")
if a == nil {
m.Error("Invalid SetBackgroundColour message: 'a' value required")
return
}
targetWindow.SetBackgroundColour(&options.RGBA{
Red: *r,
Green: *g,
Blue: *b,
Alpha: *a,
})
m.json(rw, nil)
case "SetAlwaysOnTop":
alwaysOnTop := params.Bool("alwaysOnTop")
if alwaysOnTop == nil {
m.Error("Invalid SetAlwaysOnTop message: 'alwaysOnTop' value required")
return
}
targetWindow.SetAlwaysOnTop(*alwaysOnTop)
m.json(rw, nil)
case "SetResizable":
resizable := params.Bool("resizable")
if resizable == nil {
m.Error("Invalid SetResizable message: 'resizable' value required")
return
}
targetWindow.SetResizable(*resizable)
m.json(rw, nil)
case "SetMinSize":
width := params.Int("width")
height := params.Int("height")
if width == nil || height == nil {
m.Error("Invalid SetMinSize message")
return
}
targetWindow.SetMinSize(*width, *height)
m.json(rw, nil)
case "SetMaxSize":
width := params.Int("width")
height := params.Int("height")
if width == nil || height == nil {
m.Error("Invalid SetMaxSize message")
return
}
targetWindow.SetMaxSize(*width, *height)
m.json(rw, nil)
case "Width":
width := targetWindow.Width()
m.json(rw, map[string]interface{}{
"width": width,
})
case "Height":
height := targetWindow.Height()
m.json(rw, map[string]interface{}{
"height": height,
})
case "ZoomIn":
targetWindow.ZoomIn()
m.json(rw, nil)
case "ZoomOut":
targetWindow.ZoomOut()
m.json(rw, nil)
case "ZoomReset":
targetWindow.ZoomReset()
m.json(rw, nil)
case "GetZoom":
zoomLevel := targetWindow.GetZoom()
m.json(rw, map[string]interface{}{
"zoomLevel": zoomLevel,
})
case "SetZoom":
zoomLevel := params.Float64("zoomLevel")
if zoomLevel == nil {
m.Error("Invalid SetZoom message: invalid 'zoomLevel' value")
return
}
targetWindow.SetZoom(*zoomLevel)
m.json(rw, nil)
default: default:
m.Error("unknown Window message: %s", message) m.httpError(rw, "Unknown window method: %s", method)
} }
} }

View File

@ -34,9 +34,11 @@ type (
reload() reload()
forceReload() forceReload()
toggleDevTools() toggleDevTools()
resetZoom() zoomReset()
zoomIn() zoomIn()
zoomOut() zoomOut()
getZoom() float64
setZoom(zoom float64)
close() close()
zoom() zoom()
minimize() minimize()
@ -112,6 +114,7 @@ func NewWindow(options *options.WebviewWindow) *WebviewWindow {
} }
result.messageProcessor = NewMessageProcessor(result) result.messageProcessor = NewMessageProcessor(result)
srv.UseRuntimeHandler(result.messageProcessor)
return result return result
} }
@ -211,6 +214,21 @@ func (w *WebviewWindow) SetURL(s string) *WebviewWindow {
return w return w
} }
func (w *WebviewWindow) SetZoom(magnification float64) *WebviewWindow {
w.options.Zoom = magnification
if w.impl != nil {
w.impl.setZoom(magnification)
}
return w
}
func (w *WebviewWindow) GetZoom() float64 {
if w.impl != nil {
return w.impl.getZoom()
}
return 1
}
func (w *WebviewWindow) SetResizable(b bool) *WebviewWindow { func (w *WebviewWindow) SetResizable(b bool) *WebviewWindow {
w.options.DisableResize = !b w.options.DisableResize = !b
if w.impl != nil { if w.impl != nil {
@ -449,9 +467,9 @@ func (w *WebviewWindow) ToggleDevTools() {
w.impl.toggleDevTools() w.impl.toggleDevTools()
} }
func (w *WebviewWindow) ResetZoom() *WebviewWindow { func (w *WebviewWindow) ZoomReset() *WebviewWindow {
if w.impl != nil { if w.impl != nil {
w.impl.resetZoom() w.impl.zoomReset()
} }
return w return w

View File

@ -251,8 +251,8 @@ void windowEnableDevTools(void* nsWindow) {
}); });
} }
// windowResetZoom // windowZoomReset
void windowResetZoom(void* nsWindow) { void windowZoomReset(void* nsWindow) {
// Reset zoom on main thread // Reset zoom on main thread
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
// Get window delegate // Get window delegate
@ -262,6 +262,24 @@ void windowResetZoom(void* nsWindow) {
}); });
} }
// windowZoomSet
void windowZoomSet(void* nsWindow, double zoom) {
// Reset zoom on main thread
dispatch_async(dispatch_get_main_queue(), ^{
// Get window delegate
WebviewWindowDelegate* delegate = (WebviewWindowDelegate*)[(WebviewWindow*)nsWindow delegate];
// Reset zoom
[delegate.webView setMagnification:zoom];
});
}
// windowZoomGet
float windowZoomGet(void* nsWindow) {
// Get zoom
WebviewWindowDelegate* delegate = (WebviewWindowDelegate*)[(WebviewWindow*)nsWindow delegate];
return [delegate.webView magnification];
}
// windowZoomIn // windowZoomIn
void windowZoomIn(void* nsWindow) { void windowZoomIn(void* nsWindow) {
// Zoom in on main thread // Zoom in on main thread
@ -762,6 +780,14 @@ type macosWebviewWindow struct {
parent *WebviewWindow parent *WebviewWindow
} }
func (w *macosWebviewWindow) getZoom() float64 {
return float64(C.windowZoomGet(w.nsWindow))
}
func (w *macosWebviewWindow) setZoom(zoom float64) {
C.windowZoomSet(w.nsWindow, C.double(zoom))
}
func (w *macosWebviewWindow) setFrameless(frameless bool) { func (w *macosWebviewWindow) setFrameless(frameless bool) {
C.windowSetFrameless(w.nsWindow, C.bool(frameless)) C.windowSetFrameless(w.nsWindow, C.bool(frameless))
if frameless { if frameless {
@ -848,8 +874,8 @@ func (w *macosWebviewWindow) zoomOut() {
C.windowZoomOut(w.nsWindow) C.windowZoomOut(w.nsWindow)
} }
func (w *macosWebviewWindow) resetZoom() { func (w *macosWebviewWindow) zoomReset() {
C.windowResetZoom(w.nsWindow) C.windowZoomReset(w.nsWindow)
} }
func (w *macosWebviewWindow) toggleDevTools() { func (w *macosWebviewWindow) toggleDevTools() {
@ -1017,6 +1043,7 @@ func (w *macosWebviewWindow) run() {
if w.parent.options.MaxWidth != 0 || w.parent.options.MaxHeight != 0 { if w.parent.options.MaxWidth != 0 || w.parent.options.MaxHeight != 0 {
w.setMaxSize(w.parent.options.MaxWidth, w.parent.options.MaxHeight) w.setMaxSize(w.parent.options.MaxWidth, w.parent.options.MaxHeight)
} }
//w.setZoom(w.parent.options.Zoom)
w.enableDevTools() w.enableDevTools()
w.setBackgroundColour(w.parent.options.BackgroundColour) w.setBackgroundColour(w.parent.options.BackgroundColour)

View File

@ -39,6 +39,7 @@ type WebviewWindow struct {
FullscreenButtonEnabled bool FullscreenButtonEnabled bool
Hidden bool Hidden bool
EnableFraudulentWebsiteWarnings bool EnableFraudulentWebsiteWarnings bool
Zoom float64
} }
var WindowDefaults = &WebviewWindow{ var WindowDefaults = &WebviewWindow{