Basic integration of the assetserver

This commit is contained in:
stffabi 2023-01-10 20:30:32 +01:00
commit b4d64678b5
11 changed files with 165 additions and 2 deletions

View file

@ -3,6 +3,7 @@ package main
import (
_ "embed"
"log"
"net/http"
"github.com/wailsapp/wails/exp/pkg/options"
@ -20,13 +21,20 @@ func main() {
// Create window
app.NewWebviewWindowWithOptions(&options.WebviewWindow{
Title: "Plain Bundle",
HTML: `<html><head><title>Plain Bundle</title></head><body><div class="main"><h1>Plain Bundle</h1><p>This is a plain bundle. It has no frontend code.</p></div></body></html>`,
CSS: `body { background-color: rgba(255, 255, 255, 0); } .main { color: white; margin: 20%; }`,
Mac: options.MacWindow{
InvisibleTitleBarHeight: 50,
Backdrop: options.MacBackdropTranslucent,
TitleBar: options.TitleBarHiddenInset,
},
URL: "/",
Assets: options.Assets{
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`<html><head><title>Plain Bundle</title></head><body><div class="main"><h1>Plain Bundle</h1><p>This is a plain bundle. It has no frontend code but this was Served by the AssetServer's Handler</p></div></body></html>`))
}),
},
})
err := app.Run()

View file

@ -22,7 +22,9 @@ require (
github.com/fatih/color v1.13.0 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/gookit/color v1.5.2 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/joho/godotenv v1.4.0 // indirect
github.com/leaanthony/slicer v1.5.0 // indirect
github.com/lithammer/fuzzysearch v1.1.5 // indirect
github.com/mattn/go-colorable v0.1.11 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
@ -35,10 +37,13 @@ require (
github.com/radovskyb/watcher v1.0.7 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/sajari/fuzzy v1.0.0 // indirect
github.com/wailsapp/mimetype v1.4.1 // indirect
github.com/wailsapp/wails/v2 v2.3.2-0.20230117193915-45c3a501d9e6 // indirect
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 // indirect
golang.org/x/image v0.0.0-20201208152932-35266b937fa6 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/term v0.3.0 // indirect

View file

@ -28,6 +28,8 @@ github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQ
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/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/jackmordaunt/icns/v2 v2.2.1 h1:MGklwYP2yohKn2Bw7XxlF69LZe98S1vUfl5OvAulPwg=
github.com/jackmordaunt/icns/v2 v2.2.1/go.mod h1:6aYIB9eSzyfHHMKqDf17Xrs1zetQPReAkiUSHzdw4cI=
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
@ -45,6 +47,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/leaanthony/clir v1.0.4/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0=
github.com/leaanthony/clir v1.3.0 h1:L9nPDWrmc/qU9UWZZvRaFajWYuO0np9V5p+5gxyYno0=
github.com/leaanthony/clir v1.3.0/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0=
github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0HtY=
github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
github.com/leaanthony/winicon v1.0.0 h1:ZNt5U5dY71oEoKZ97UVwJRT4e+5xo5o/ieKuHuk8NqQ=
github.com/leaanthony/winicon v1.0.0/go.mod h1:en5xhijl92aphrJdmRPlh4NI1L6wq3gEm0LpXAPghjU=
github.com/lithammer/fuzzysearch v1.1.5 h1:Ag7aKU08wp0R9QCfF4GoGST9HbmAIeLP7xwMrOBEp1c=
@ -105,8 +109,12 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/tc-hib/winres v0.1.6 h1:qgsYHze+BxQPEYilxIz/KCQGaClvI2+yLBAZs+3+0B8=
github.com/tc-hib/winres v0.1.6/go.mod h1:pe6dOR40VOrGz8PkzreVKNvEKnlE8t4yR8A8naL+t7A=
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
github.com/wailsapp/task/v3 v3.19.1 h1:syDKYaPBXgrXKKSJVEWcOEoSFtZzpvxqlHf90YRukRc=
github.com/wailsapp/task/v3 v3.19.1/go.mod h1:y7rWakbLR5gFElGgo6rA2dyr6vU/zNIDVfn3S4Of6OI=
github.com/wailsapp/wails/v2 v2.3.2-0.20230117193915-45c3a501d9e6 h1:Wn+nhnS+VytzE0PegUzSh4T3hXJCtggKGD/4U5H9+wQ=
github.com/wailsapp/wails/v2 v2.3.2-0.20230117193915-45c3a501d9e6/go.mod h1:zlNLI0E2c2qA6miiuAHtp0Bac8FaGH0tlhA19OssR/8=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@ -119,6 +127,9 @@ golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+o
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -128,6 +139,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -135,6 +147,7 @@ golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -155,6 +168,7 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8X
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View file

@ -0,0 +1,26 @@
//go:build production
package runtime
var RuntimeAssetsBundle = &RuntimeAssets{
desktopIPC: DesktopIPC,
runtimeDesktopJS: DesktopRuntime,
}
type RuntimeAssets struct {
desktopIPC []byte
websocketIPC []byte
runtimeDesktopJS []byte
}
func (r *RuntimeAssets) DesktopIPC() []byte {
return r.desktopIPC
}
func (r *RuntimeAssets) WebsocketIPC() []byte {
return r.websocketIPC
}
func (r *RuntimeAssets) RuntimeDesktopJS() []byte {
return r.runtimeDesktopJS
}

View file

@ -0,0 +1,27 @@
//go:build !production
package runtime
var RuntimeAssetsBundle = &RuntimeAssets{
desktopIPC: DesktopIPC,
websocketIPC: WebsocketIPC,
runtimeDesktopJS: DesktopRuntime,
}
type RuntimeAssets struct {
desktopIPC []byte
websocketIPC []byte
runtimeDesktopJS []byte
}
func (r *RuntimeAssets) DesktopIPC() []byte {
return r.desktopIPC
}
func (r *RuntimeAssets) WebsocketIPC() []byte {
return r.websocketIPC
}
func (r *RuntimeAssets) RuntimeDesktopJS() []byte {
return r.runtimeDesktopJS
}

View file

@ -8,6 +8,8 @@ import (
"github.com/wailsapp/wails/exp/pkg/events"
"github.com/wailsapp/wails/exp/pkg/options"
"github.com/wailsapp/wails/v2/pkg/assetserver/webview"
)
var globalApplication *App
@ -65,6 +67,13 @@ type windowMessage struct {
var windowMessageBuffer = make(chan *windowMessage)
type webViewAssetRequest struct {
windowId uint
request webview.Request
}
var webviewRequests = make(chan *webViewAssetRequest)
type App struct {
options options.Application
applicationEventListeners map[uint][]func()
@ -178,6 +187,13 @@ func (a *App) Run() error {
a.handleWindowEvent(event)
}
}()
go func() {
for {
event := <-webviewRequests
a.handleWebViewRequest(event)
event.request.Release()
}
}()
go func() {
for {
event := <-windowMessageBuffer
@ -236,6 +252,19 @@ func (a *App) handleWindowMessage(event *windowMessage) {
window.handleMessage(event.message)
}
func (a *App) handleWebViewRequest(event *webViewAssetRequest) {
// Get window from window map
a.windowsLock.Lock()
window, ok := a.windows[event.windowId]
a.windowsLock.Unlock()
if !ok {
log.Printf("WebviewWindow #%d not found", event.windowId)
return
}
// Get callback from window
window.handleWebViewRequest(event.request)
}
func (a *App) handleWindowEvent(event *WindowEvent) {
// Get window from window map
a.windowsLock.Lock()

View file

@ -119,6 +119,7 @@ import (
"unsafe"
"github.com/wailsapp/wails/exp/pkg/events"
"github.com/wailsapp/wails/v2/pkg/assetserver/webview"
)
type macosApp struct {
@ -203,6 +204,14 @@ func processMessage(windowID C.uint, message *C.char) {
}
}
//export processURLRequest
func processURLRequest(windowID C.uint, wkUrlSchemeTask unsafe.Pointer) {
webviewRequests <- &webViewAssetRequest{
windowId: uint(windowID),
request: webview.NewRequest(wkUrlSchemeTask),
}
}
//export processMenuItemClick
func processMenuItemClick(menuID C.uint) {
menuItemClicked <- uint(menuID)

View file

@ -4,8 +4,12 @@ import (
"fmt"
"sync"
"github.com/wailsapp/wails/exp/internal/runtime"
"github.com/wailsapp/wails/exp/pkg/events"
"github.com/wailsapp/wails/exp/pkg/options"
"github.com/wailsapp/wails/v2/pkg/assetserver"
"github.com/wailsapp/wails/v2/pkg/assetserver/webview"
assetserveroptions "github.com/wailsapp/wails/v2/pkg/options/assetserver"
)
type (
@ -63,6 +67,8 @@ type WebviewWindow struct {
implLock sync.RWMutex
id uint
assets *assetserver.AssetServer
eventListeners map[uint][]func()
eventListenersLock sync.RWMutex
}
@ -84,10 +90,21 @@ func NewWindow(options *options.WebviewWindow) *WebviewWindow {
if options.Height == 0 {
options.Height = 600
}
opts := assetserveroptions.Options{Assets: options.Assets.FS, Handler: options.Assets.Handler, Middleware: options.Assets.Middleware}
// TODO Bindings, Logger, ServingFrom disk?
srv, err := assetserver.NewAssetServer("", opts, false, nil, runtime.RuntimeAssetsBundle)
if err != nil {
// TODO handle errors
panic(err)
}
return &WebviewWindow{
id: getWindowID(),
options: options,
eventListeners: make(map[uint][]func()),
assets: srv,
}
}
@ -326,6 +343,12 @@ func (w *WebviewWindow) handleMessage(message string) {
}
}
func (w *WebviewWindow) handleWebViewRequest(request webview.Request) {
url, _ := request.URL()
fmt.Printf("[window %d] Request %s\n", w.id, url)
w.assets.ServeWebViewRequest(request)
}
func (w *WebviewWindow) Center() {
if w.impl == nil {
return

View file

@ -16,7 +16,7 @@
@end
@interface WebviewWindowDelegate : NSObject <NSWindowDelegate, WKScriptMessageHandler, WKNavigationDelegate>
@interface WebviewWindowDelegate : NSObject <NSWindowDelegate, WKScriptMessageHandler, WKNavigationDelegate, WKURLSchemeHandler>
@property bool hideOnClose;
@property (retain) WKWebView* webView;

View file

@ -6,6 +6,7 @@
#import "../events/events.h"
extern void processMessage(unsigned int, const char*);
extern void processURLRequest(unsigned int, void *);
extern bool hasListeners(unsigned int);
@implementation WebviewWindow
@ -82,6 +83,21 @@ extern bool hasListeners(unsigned int);
- (void)handleLeftMouseUp:(NSWindow *)window {
self.leftMouseEvent = nil;
}
- (void)webView:(nonnull WKWebView *)webView startURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
processURLRequest(self.windowId, urlSchemeTask);
}
- (void)webView:(nonnull WKWebView *)webView stopURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
NSInputStream *stream = urlSchemeTask.request.HTTPBodyStream;
if (stream) {
NSStreamStatus status = stream.streamStatus;
if (status != NSStreamStatusClosed && status != NSStreamStatusNotOpen) {
[stream close];
}
}
}
// GENERATED EVENTS START
- (void)windowDidBecomeKey:(NSNotification *)notification {
if( hasListeners(EventWindowDidBecomeKey) ) {

View file

@ -48,6 +48,7 @@ void* windowNew(unsigned int id, int width, int height, bool fraudulentWebsiteWa
WKWebViewConfiguration* config = [[WKWebViewConfiguration alloc] init];
config.suppressesIncrementalRendering = true;
config.applicationNameForUserAgent = @"wails.io";
[config setURLSchemeHandler:delegate forURLScheme:@"wails"];
if (@available(macOS 10.15, *)) {
config.preferences.fraudulentWebsiteWarningEnabled = fraudulentWebsiteWarningEnabled;
}
@ -913,6 +914,11 @@ func (w *macosWebviewWindow) execJS(js string) {
}
func (w *macosWebviewWindow) setURL(url string) {
if url == "/" {
// TODO handle this in a central location and handle all urls without scheme and host. This might be platform
// dependant
url = "wails://wails/"
}
C.navigationLoadURL(w.nsWindow, C.CString(url))
}