mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 06:32:10 +08:00
support bridge mode
streamline some messaging
This commit is contained in:
parent
717e598330
commit
683ba7dc59
File diff suppressed because one or more lines are too long
214
assets/bridge/wailsbridge.js
Normal file
214
assets/bridge/wailsbridge.js
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
Wails Bridge (c) 2019-present Lea Anthony
|
||||
|
||||
This library creates a bridge between your application
|
||||
and the frontend, allowing you to develop your app using
|
||||
standard tooling (browser extensions, live reload, etc).
|
||||
|
||||
Usage:
|
||||
```
|
||||
import Bridge from "./wailsbridge";
|
||||
Bridge.Start(startApp);
|
||||
```
|
||||
|
||||
The given callback (startApp in the example) will be called
|
||||
when the bridge has successfully initialised. It passes the
|
||||
window.wails object back, in case it is not accessible directly.
|
||||
*/
|
||||
|
||||
// Bridge object
|
||||
window.wailsbridge = {
|
||||
reconnectOverlay: null,
|
||||
reconnectTimer: 300,
|
||||
wsURL: "ws://localhost:34115/bridge",
|
||||
connectionState: null,
|
||||
config: {},
|
||||
websocket: null,
|
||||
callback: null,
|
||||
overlayHTML:
|
||||
'<div class="wails-reconnect-overlay"><div class="wails-reconnect-overlay-content"><div class="wails-reconnect-overlay-title">Wails Bridge</div><br><div class="wails-reconnect-overlay-loadingspinner"></div><br><div id="wails-reconnect-overlay-message">Waiting for backend</div></div></div>',
|
||||
overlayCSS:
|
||||
".wails-reconnect-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.6);font-family:sans-serif;display:none;z-index:999999}.wails-reconnect-overlay-content{padding:20px 30px;text-align:center;width:20em;position:relative;height:14em;border-radius:1em;margin:5% auto 0;background-color:#fff;box-shadow:1px 1px 20px 3px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC8AAAAuCAMAAACPpbA7AAAAqFBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAAAAAAAAEBAQAAAAAAAAAAAAEBAQEBAQDAwMBAQEAAAABAQEAAAAAAAAAAAABAQEAAAAAAAACAgICAgIBAQEAAAAAAAAAAAAAAAAAAAAAAAABAQEAAAACAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQWKCj6oAAAAN3RSTlMALiIqDhkGBAswJjP0GxP6NR4W9/ztjRDMhWU50G9g5eHXvbZ9XEI9xZTcqZl2aldKo55QwoCvZUgzhAAAAs9JREFUSMeNleeWqjAUhU0BCaH3Itiw9zKT93+zG02QK1hm/5HF+jzZJ6fQe6cyXE+jg9X7o9wxuylIIf4Tv2V3+bOrEXnf8dwQ/KQIGDN2/S+4OmVCVXL/ScBnfibxURqIByP/hONE8r8T+bDMlQ98KSl7Y8hzjpS8v1qtDh8u5f8KQpGpfnPPhqG8JeogN37Hq9eaN2xRhIwAaGnvws8F1ShxqK5ob2twYi1FAMD4rXsYtnC/JEiRbl4cUrCWhnMCLRFemXezXbb59QK4WASOsm6n2W1+4CBT2JmtzQ6fsrbGubR/NFbd2g5Y179+5w/GEHaKsHjYCet7CgrXU3txarNC7YxOVJtIj4/ERzMdZfzc31hp+8cD6eGILgarZY9uZ12hAs03vfBD9C171gS5Omz7OcvxALQIn4u8RRBBBcsi9WW2woO9ipLgfzpYlggg3ZRdROUC8KT7QLqq3W9KB5BbdFVg4929kdwp6+qaZnMCCNBdj+NyN1W885Ry/AL3D4AQbsVV4noCiM/C83kyYq80XlDAYQtralOiDzoRAHlotWl8q2tjvYlOgcg1A8jEApZa+C06TBdAz2Qv0wu11I/zZOyJQ6EwGez2P2b8PIQr1hwwnAZsAxwA4UAYOyXUxM/xp6tHAn4GUmPGM9R28oVxgC0e/zQJJI6DyhyZ1r7uzRQhpcW7x7vTaWSzKSG6aep77kroTEl3U81uSVaUTtgEINfC8epx+Q4F9SpplHG84Ek6m4RAq9/TLkOBrxyeuddZhHvGIp1XXfFy3Z3vtwNblKGiDn+J+92vwwABHghj7HnzlS1H5kB49AZvdGCFgiBPq69qfXPr3y++yilF0ON4R8eR7spAsLpZ95NqAW5tab1c4vkZm6aleajchMwYTdILQQTwE2OV411ZM9WztDjPql12caBi6gDpUKmDd4U1XNdQxZ4LIXQ5/Tr4P7I9tYcFrDK3AAAAAElFTkSuQmCC);background-repeat:no-repeat;background-position:center}.wails-reconnect-overlay-title{font-size:2em}.wails-reconnect-overlay-message{font-size:1.3em}.wails-reconnect-overlay-loadingspinner{pointer-events:none;width:2.5em;height:2.5em;border:.4em solid transparent;border-color:#3E67EC #eee #eee;border-radius:50%;animation:loadingspin 1s linear infinite;margin:auto;padding:2.5em}@keyframes loadingspin{100%{transform:rotate(360deg)}}",
|
||||
log: function (message) {
|
||||
console.log(
|
||||
"%c wails bridge %c " + message + " ",
|
||||
"background: #aa0000; color: #fff; border-radius: 3px 0px 0px 3px; padding: 1px; font-size: 0.7rem",
|
||||
"background: #009900; color: #fff; border-radius: 0px 3px 3px 0px; padding: 1px; font-size: 0.7rem"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// Adapted from webview - thanks zserge!
|
||||
function injectCSS(css) {
|
||||
var elem = document.createElement("style");
|
||||
elem.setAttribute("type", "text/css");
|
||||
if (elem.styleSheet) {
|
||||
elem.styleSheet.cssText = css;
|
||||
} else {
|
||||
elem.appendChild(document.createTextNode(css));
|
||||
}
|
||||
var head = document.head || document.getElementsByTagName("head")[0];
|
||||
head.appendChild(elem);
|
||||
}
|
||||
|
||||
// Creates a node in the Dom
|
||||
function createNode(parent, elementType, id, className, content) {
|
||||
var d = document.createElement(elementType);
|
||||
if (id) {
|
||||
d.id = id;
|
||||
}
|
||||
if (className) {
|
||||
d.className = className;
|
||||
}
|
||||
if (content) {
|
||||
d.innerHTML = content;
|
||||
}
|
||||
parent.appendChild(d);
|
||||
return d;
|
||||
}
|
||||
|
||||
// Sets up the overlay
|
||||
function setupOverlay() {
|
||||
var body = document.body;
|
||||
var wailsBridgeNode = createNode(body, "div", "wails-bridge");
|
||||
wailsBridgeNode.innerHTML = window.wailsbridge.overlayHTML;
|
||||
|
||||
// Inject the overlay CSS
|
||||
injectCSS(window.wailsbridge.overlayCSS);
|
||||
}
|
||||
|
||||
// Start the Wails Bridge
|
||||
function startBridge() {
|
||||
// Setup the overlay
|
||||
setupOverlay();
|
||||
|
||||
window.wailsbridge.websocket = null;
|
||||
window.wailsbridge.connectTimer = null;
|
||||
window.wailsbridge.reconnectOverlay = document.querySelector(
|
||||
".wails-reconnect-overlay"
|
||||
);
|
||||
window.wailsbridge.connectionState = "disconnected";
|
||||
|
||||
// Shows the overlay
|
||||
function showReconnectOverlay() {
|
||||
window.wailsbridge.reconnectOverlay.style.display = "block";
|
||||
}
|
||||
|
||||
// Hides the overlay
|
||||
function hideReconnectOverlay() {
|
||||
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.
|
||||
// Removes it if second parameter is true.
|
||||
function addScript(script, remove) {
|
||||
var s = document.createElement("script");
|
||||
s.textContent = script;
|
||||
document.head.appendChild(s);
|
||||
|
||||
// Remove internal messages from the DOM
|
||||
if (remove) {
|
||||
s.parentNode.removeChild(s);
|
||||
}
|
||||
}
|
||||
|
||||
// Handles incoming websocket connections
|
||||
function handleConnect() {
|
||||
window.wailsbridge.log("Connected to backend");
|
||||
hideReconnectOverlay();
|
||||
clearInterval(window.wailsbridge.connectTimer);
|
||||
window.wailsbridge.websocket.onclose = handleDisconnect;
|
||||
window.wailsbridge.websocket.onmessage = handleMessage;
|
||||
window.wailsbridge.connectionState = "connected";
|
||||
}
|
||||
|
||||
// Handles websocket disconnects
|
||||
function handleDisconnect() {
|
||||
window.wailsbridge.log("Disconnected from backend");
|
||||
window.wailsbridge.websocket = null;
|
||||
window.wailsbridge.connectionState = "disconnected";
|
||||
showReconnectOverlay();
|
||||
connect();
|
||||
}
|
||||
|
||||
// Try to connect to the backend every 300ms (default value).
|
||||
// Change this value in the main wailsbridge object.
|
||||
function connect() {
|
||||
window.wailsbridge.connectTimer = setInterval(function () {
|
||||
if (window.wailsbridge.websocket == null) {
|
||||
window.wailsbridge.websocket = new WebSocket(window.wailsbridge.wsURL);
|
||||
window.wailsbridge.websocket.onopen = handleConnect;
|
||||
window.wailsbridge.websocket.onerror = function (e) {
|
||||
e.stopImmediatePropagation();
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
window.wailsbridge.websocket = null;
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}, window.wailsbridge.reconnectTimer);
|
||||
}
|
||||
|
||||
function handleMessage(message) {
|
||||
// As a bridge we ignore js and css injections
|
||||
|
||||
switch (message.data[0]) {
|
||||
// Wails library - inject!
|
||||
case "w":
|
||||
addScript(message.data.slice(1));
|
||||
|
||||
// Now wails runtime is loaded, wails for the ready event
|
||||
// and callback to the main app
|
||||
window.wails.events.on("wails:loaded", function () {
|
||||
window.wailsbridge.log("Wails Ready");
|
||||
if (window.wailsbridge.callback) {
|
||||
window.wailsbridge.log("Notifying application");
|
||||
window.wailsbridge.callback(window.wails);
|
||||
}
|
||||
});
|
||||
window.wailsbridge.log("Loaded Wails Runtime");
|
||||
break;
|
||||
// Notifications
|
||||
case "n":
|
||||
addScript(message.data.slice(1), true);
|
||||
break;
|
||||
// Binding
|
||||
case "b":
|
||||
var binding = message.data.slice(1)
|
||||
//log("Binding: " + binding)
|
||||
window.wails._.newBinding(binding);
|
||||
break;
|
||||
// Call back
|
||||
case "c":
|
||||
var callbackData = message.data.slice(1);
|
||||
log("Callback = " + callbackData);
|
||||
window.wails._.callback(callbackData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Start by showing the overlay...
|
||||
showReconnectOverlay();
|
||||
|
||||
// ...and attempt to connect
|
||||
connect();
|
||||
}
|
||||
|
||||
export default {
|
||||
// The main function
|
||||
// Passes the main Wails object to the callback if given.
|
||||
Start: function (callback) {
|
||||
// Save the callback
|
||||
window.wailsbridge.callback = callback;
|
||||
|
||||
// Start Bridge
|
||||
startBridge();
|
||||
}
|
||||
};
|
@ -94,22 +94,34 @@
|
||||
}
|
||||
};
|
||||
|
||||
function addScript(script, id) {
|
||||
var s = document.createElement("script")
|
||||
if (id) {
|
||||
s.id = id;
|
||||
}
|
||||
// Adds a script to the Dom.
|
||||
// Removes it if second parameter is true.
|
||||
function addScript(script, remove) {
|
||||
var s = document.createElement("script");
|
||||
s.textContent = script;
|
||||
document.head.appendChild(s)
|
||||
if (script.indexOf("window.wails._.") == 0) {
|
||||
var elem = document.querySelector('#' + id);
|
||||
elem.parentNode.removeChild(elem);
|
||||
document.head.appendChild(s);
|
||||
|
||||
// Remove internal messages from the DOM
|
||||
if (remove) {
|
||||
s.parentNode.removeChild(s);
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from webview - thanks zserge!
|
||||
function injectCSS(css) {
|
||||
var elem = document.createElement("style");
|
||||
elem.setAttribute("type", "text/css");
|
||||
if (elem.styleSheet) {
|
||||
elem.styleSheet.cssText = css;
|
||||
} else {
|
||||
elem.appendChild(document.createTextNode(css));
|
||||
}
|
||||
var head = document.head || document.getElementsByTagName("head")[0];
|
||||
head.appendChild(elem);
|
||||
}
|
||||
|
||||
function handleConnect() {
|
||||
console.log("[Wails] Connected to backend");
|
||||
addKeyListener();
|
||||
log("Connected to backend");
|
||||
hideReconnectOverlay();
|
||||
clearInterval(connectTimer);
|
||||
websocket.onclose = handleDisconnect;
|
||||
@ -119,9 +131,8 @@
|
||||
}
|
||||
|
||||
function handleDisconnect() {
|
||||
console.log("[Wails] Disconnected from backend");
|
||||
log("Disconnected from backend");
|
||||
websocket = null;
|
||||
removeKeyListener();
|
||||
connectionState = "disconnected";
|
||||
showReconnectOverlay();
|
||||
connect();
|
||||
@ -142,40 +153,71 @@
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
|
||||
let idcounter = 0
|
||||
function generateID() {
|
||||
return "wails-" + idcounter++;
|
||||
function log(message) {
|
||||
console.log(
|
||||
"%c wails headless %c " + message + " ",
|
||||
"background: #aa0000; color: #fff; border-radius: 3px 0px 0px 3px; padding: 1px; font-size: 0.7rem",
|
||||
"background: #009900; color: #fff; border-radius: 0px 3px 3px 0px; padding: 1px; font-size: 0.7rem"
|
||||
);
|
||||
}
|
||||
|
||||
function handleMessage(e) {
|
||||
addScript(e.data, generateID());
|
||||
}
|
||||
function handleMessage(message) {
|
||||
// As a bridge we ignore js and css injections
|
||||
debugger;
|
||||
|
||||
// Key listener
|
||||
var delta = 300;
|
||||
var lastKeypressTime = 0;
|
||||
function KeyHandler(event) {
|
||||
if (event.key === "`") {
|
||||
var thisKeypressTime = new Date();
|
||||
if (thisKeypressTime - lastKeypressTime <= delta) {
|
||||
console.log("Double tap!")
|
||||
// optional - if we'd rather not detect a triple-press
|
||||
// as a second double-press, reset the timestamp
|
||||
thisKeypressTime = 0;
|
||||
}
|
||||
lastKeypressTime = thisKeypressTime;
|
||||
switch (message.data[0]) {
|
||||
// Wails library - inject!
|
||||
case "w":
|
||||
addScript(message.data.slice(1));
|
||||
|
||||
// Now wails runtime is loaded, wails for the ready event
|
||||
// and callback to the main app
|
||||
window.wails.events.on("wails:loaded", function () {
|
||||
log("Wails Ready");
|
||||
});
|
||||
log("Loaded Wails Runtime");
|
||||
break;
|
||||
|
||||
// Notification
|
||||
case "n":
|
||||
log("Notification: " + message.data.slice(1))
|
||||
addScript(message.data.slice(1), true);
|
||||
break;
|
||||
|
||||
// Binding
|
||||
case "b":
|
||||
var binding = message.data.slice(1)
|
||||
//log("Binding: " + binding)
|
||||
window.wails._.newBinding(binding);
|
||||
break;
|
||||
|
||||
// Call back
|
||||
case "c":
|
||||
var callbackData = message.data.slice(1);
|
||||
log("Callback = " + callbackData);
|
||||
window.wails._.callback(callbackData);
|
||||
break;
|
||||
|
||||
// CSS
|
||||
case "s":
|
||||
addScript(message.data.slice(1), true);
|
||||
break;
|
||||
|
||||
// JS
|
||||
case "j":
|
||||
addScript(message.data.slice(1));
|
||||
break;
|
||||
|
||||
// HTML
|
||||
case "h":
|
||||
addScript(message.data.slice(1), true);
|
||||
break;
|
||||
|
||||
default:
|
||||
log("Ignored message: " + message.data.slice(0, 100))
|
||||
}
|
||||
}
|
||||
|
||||
function addKeyListener() {
|
||||
document.body.addEventListener('keydown', KeyHandler);
|
||||
}
|
||||
|
||||
function removeKeyListener() {
|
||||
document.body.removeEventListener('keydown', KeyHandler);
|
||||
}
|
||||
|
||||
connect();
|
||||
|
||||
}());
|
||||
|
@ -14,6 +14,22 @@ import (
|
||||
var headlessAssets = packr.NewBox("./assets/headless")
|
||||
var defaultAssets = packr.NewBox("./assets/default")
|
||||
|
||||
type messageType int
|
||||
|
||||
const (
|
||||
jsMessage messageType = iota
|
||||
cssMessage
|
||||
htmlMessage
|
||||
notifyMessage
|
||||
bindingMessage
|
||||
callbackMessage
|
||||
wailsRuntimeMessage
|
||||
)
|
||||
|
||||
func (m messageType) toString() string {
|
||||
return [...]string{"j", "s", "h", "n", "b", "c", "w"}[m]
|
||||
}
|
||||
|
||||
// Headless is a backend that opens a local web server
|
||||
// and renders the files over a websocket
|
||||
type Headless struct {
|
||||
@ -32,6 +48,8 @@ type Headless struct {
|
||||
initialisationJS []string
|
||||
server *http.Server
|
||||
theConnection *websocket.Conn
|
||||
bridgeMode bool
|
||||
connectionType string
|
||||
}
|
||||
|
||||
// Initialise the Headless Renderer
|
||||
@ -39,16 +57,23 @@ func (h *Headless) Initialise(appConfig *AppConfig, ipcManager *ipcManager, even
|
||||
h.ipcManager = ipcManager
|
||||
h.appConfig = appConfig
|
||||
h.eventManager = eventManager
|
||||
h.bridgeMode = false
|
||||
h.connectionType = "Websocket"
|
||||
|
||||
ipcManager.bindRenderer(h)
|
||||
h.log = newCustomLogger("Headless")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Headless) evalJS(js string) error {
|
||||
func (h *Headless) evalJS(js string, mtype messageType) error {
|
||||
|
||||
message := mtype.toString() + js
|
||||
|
||||
if h.theConnection == nil {
|
||||
h.initialisationJS = append(h.initialisationJS, js)
|
||||
h.initialisationJS = append(h.initialisationJS, message)
|
||||
} else {
|
||||
h.sendMessage(h.theConnection, js)
|
||||
// Prepend message type to message
|
||||
h.sendMessage(h.theConnection, message)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -67,7 +92,7 @@ func (h *Headless) injectCSS(css string) {
|
||||
minifiedCSS = strings.Replace(minifiedCSS, "'", "\\'", -1)
|
||||
minifiedCSS = strings.Replace(minifiedCSS, "\n", " ", -1)
|
||||
inject := fmt.Sprintf("wails._.injectCSS('%s')", minifiedCSS)
|
||||
h.evalJS(inject)
|
||||
h.evalJS(inject, cssMessage)
|
||||
}
|
||||
|
||||
func (h *Headless) rootHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@ -75,15 +100,21 @@ func (h *Headless) rootHandler(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "%s", indexHTML)
|
||||
}
|
||||
|
||||
func (h *Headless) wsBridgeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
h.bridgeMode = true
|
||||
h.connectionType = "Bridge"
|
||||
h.wsHandler(w, r)
|
||||
}
|
||||
|
||||
func (h *Headless) wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
conn, err := websocket.Upgrade(w, r, w.Header(), 1024, 1024)
|
||||
if err != nil {
|
||||
http.Error(w, "Could not open websocket connection", http.StatusBadRequest)
|
||||
}
|
||||
h.theConnection = conn
|
||||
h.log.Infof("Connection %p accepted.", h.theConnection)
|
||||
h.log.Infof("%s connection accepted [%p].", h.connectionType, h.theConnection)
|
||||
conn.SetCloseHandler(func(int, string) error {
|
||||
h.log.Infof("Connection %p dropped.", h.theConnection)
|
||||
h.log.Infof("%s connection dropped [%p].", h.connectionType, h.theConnection)
|
||||
h.theConnection = nil
|
||||
return nil
|
||||
})
|
||||
@ -100,75 +131,84 @@ func (h *Headless) start(conn *websocket.Conn) {
|
||||
|
||||
// set external.invoke
|
||||
h.log.Infof("Connected to frontend.")
|
||||
h.log.Infof("Mode = %s", h.connectionType)
|
||||
|
||||
wailsRuntime := BoxString(&defaultAssets, "wails.js")
|
||||
h.evalJS(wailsRuntime)
|
||||
h.evalJS(wailsRuntime, wailsRuntimeMessage)
|
||||
|
||||
// Inject jquery
|
||||
jquery := BoxString(&defaultAssets, "jquery.3.3.1.min.js")
|
||||
h.evalJS(jquery)
|
||||
if !h.bridgeMode {
|
||||
// Inject jquery
|
||||
jquery := BoxString(&defaultAssets, "jquery.3.3.1.min.js")
|
||||
h.evalJS(jquery, jsMessage)
|
||||
}
|
||||
|
||||
// Inject the initial JS
|
||||
for _, js := range h.initialisationJS {
|
||||
h.sendMessage(conn, js)
|
||||
h.sendMessage(h.theConnection, js)
|
||||
}
|
||||
|
||||
// Inject bindings
|
||||
for _, binding := range h.bindingCache {
|
||||
h.evalJS(binding)
|
||||
h.evalJS(binding, bindingMessage)
|
||||
}
|
||||
|
||||
// Inject Framework
|
||||
if h.frameworkJS != "" {
|
||||
h.evalJS(h.frameworkJS)
|
||||
}
|
||||
if h.frameworkCSS != "" {
|
||||
h.injectCSS(h.frameworkCSS)
|
||||
}
|
||||
|
||||
var injectHTML string
|
||||
if h.appConfig.isHTMLFragment {
|
||||
injectHTML = fmt.Sprintf("$('#app').html('%s')", h.appConfig.HTML)
|
||||
}
|
||||
|
||||
h.evalJS(injectHTML)
|
||||
|
||||
// Inject user CSS
|
||||
if h.appConfig.CSS != "" {
|
||||
outputCSS := fmt.Sprintf("%.45s", h.appConfig.CSS)
|
||||
if len(outputCSS) > 45 {
|
||||
outputCSS += "..."
|
||||
// In Bridge mode, we only send the wails runtime and bindings
|
||||
// so ignore this whole section
|
||||
if !h.bridgeMode {
|
||||
// Inject Framework
|
||||
if h.frameworkJS != "" {
|
||||
h.evalJS(h.frameworkJS, jsMessage)
|
||||
}
|
||||
h.log.DebugFields("Inject User CSS", Fields{"css": outputCSS})
|
||||
h.injectCSS(h.appConfig.CSS)
|
||||
} else {
|
||||
// Use default wails css
|
||||
h.log.Debug("Injecting Default Wails CSS")
|
||||
defaultCSS := BoxString(&defaultAssets, "wails.css")
|
||||
|
||||
h.injectCSS(defaultCSS)
|
||||
}
|
||||
|
||||
// Inject all the CSS files that have been added
|
||||
for _, css := range h.cssCache {
|
||||
h.injectCSS(css)
|
||||
}
|
||||
|
||||
// Inject all the JS files that have been added
|
||||
for _, js := range h.jsCache {
|
||||
h.evalJS(js)
|
||||
}
|
||||
|
||||
// Inject user JS
|
||||
if h.appConfig.JS != "" {
|
||||
outputJS := fmt.Sprintf("%.45s", h.appConfig.JS)
|
||||
if len(outputJS) > 45 {
|
||||
outputJS += "..."
|
||||
if h.frameworkCSS != "" {
|
||||
h.injectCSS(h.frameworkCSS)
|
||||
}
|
||||
|
||||
// Inject user CSS
|
||||
if h.appConfig.CSS != "" {
|
||||
outputCSS := fmt.Sprintf("%.45s", h.appConfig.CSS)
|
||||
if len(outputCSS) > 45 {
|
||||
outputCSS += "..."
|
||||
}
|
||||
h.log.DebugFields("Inject User CSS", Fields{"css": outputCSS})
|
||||
h.injectCSS(h.appConfig.CSS)
|
||||
} else {
|
||||
// Use default wails css
|
||||
h.log.Debug("Injecting Default Wails CSS")
|
||||
defaultCSS := BoxString(&defaultAssets, "wails.css")
|
||||
|
||||
h.injectCSS(defaultCSS)
|
||||
}
|
||||
|
||||
// Inject all the CSS files that have been added
|
||||
for _, css := range h.cssCache {
|
||||
h.injectCSS(css)
|
||||
}
|
||||
|
||||
// Inject all the JS files that have been added
|
||||
for _, js := range h.jsCache {
|
||||
h.evalJS(js, jsMessage)
|
||||
}
|
||||
|
||||
// Inject user JS
|
||||
if h.appConfig.JS != "" {
|
||||
outputJS := fmt.Sprintf("%.45s", h.appConfig.JS)
|
||||
if len(outputJS) > 45 {
|
||||
outputJS += "..."
|
||||
}
|
||||
h.log.DebugFields("Inject User JS", Fields{"js": outputJS})
|
||||
h.evalJS(h.appConfig.JS, jsMessage)
|
||||
}
|
||||
|
||||
var injectHTML string
|
||||
if h.appConfig.isHTMLFragment {
|
||||
injectHTML = fmt.Sprintf("$('#app').html('%s')", h.appConfig.HTML)
|
||||
h.evalJS(injectHTML, htmlMessage)
|
||||
}
|
||||
h.log.DebugFields("Inject User JS", Fields{"js": outputJS})
|
||||
h.evalJS(h.appConfig.JS)
|
||||
}
|
||||
|
||||
// Emit that everything is loaded and ready
|
||||
h.eventManager.Emit("wails:ready")
|
||||
|
||||
for {
|
||||
messageType, buffer, err := conn.ReadMessage()
|
||||
if messageType == -1 {
|
||||
@ -189,10 +229,12 @@ func (h *Headless) start(conn *websocket.Conn) {
|
||||
func (h *Headless) Run() error {
|
||||
h.server = &http.Server{Addr: ":34115"}
|
||||
http.HandleFunc("/ws", h.wsHandler)
|
||||
http.HandleFunc("/bridge", h.wsBridgeHandler)
|
||||
http.HandleFunc("/", h.rootHandler)
|
||||
|
||||
h.log.Info("Started on port 34115")
|
||||
h.log.Info("Application running at http://localhost:34115")
|
||||
h.log.Info("Headless mode started.")
|
||||
h.log.Info("If using the Wails bridge, it will connect automatically.")
|
||||
h.log.Info("You may also connect manually by browsing to http://localhost:34115")
|
||||
|
||||
err := h.server.ListenAndServe()
|
||||
if err != nil {
|
||||
@ -203,8 +245,7 @@ func (h *Headless) Run() error {
|
||||
|
||||
// NewBinding creates a new binding with the frontend
|
||||
func (h *Headless) NewBinding(methodName string) error {
|
||||
objectCode := fmt.Sprintf("window.wails._.newBinding(`%s`);", methodName)
|
||||
h.bindingCache = append(h.bindingCache, objectCode)
|
||||
h.bindingCache = append(h.bindingCache, methodName)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -250,8 +291,7 @@ func (h *Headless) AddCSSList(cssCache []string) {
|
||||
|
||||
// Callback sends a callback to the frontend
|
||||
func (h *Headless) Callback(data string) error {
|
||||
callbackCMD := fmt.Sprintf("window.wails._.callback('%s');", data)
|
||||
return h.evalJS(callbackCMD)
|
||||
return h.evalJS(data, callbackMessage)
|
||||
}
|
||||
|
||||
// NotifyEvent notifies the frontend of an event
|
||||
@ -279,7 +319,7 @@ func (h *Headless) NotifyEvent(event *eventData) error {
|
||||
}
|
||||
|
||||
message := fmt.Sprintf("window.wails._.notify('%s','%s')", event.Name, data)
|
||||
return h.evalJS(message)
|
||||
return h.evalJS(message, notifyMessage)
|
||||
}
|
||||
|
||||
// SetColour is unsupported for Headless but required
|
||||
|
Loading…
Reference in New Issue
Block a user