forked from mbk-lab/rui_orig
Updated wasm support
This commit is contained in:
parent
b4032b31e0
commit
b26525e892
|
@ -200,7 +200,7 @@ func (app *application) startSession(params DataObject, events chan DataObject,
|
||||||
|
|
||||||
session := newSession(app, app.nextSessionID(), "", params)
|
session := newSession(app, app.nextSessionID(), "", params)
|
||||||
session.setBrige(events, brige)
|
session.setBrige(events, brige)
|
||||||
if !session.setContent(app.createContentFunc(session), session) {
|
if !session.setContent(app.createContentFunc(session)) {
|
||||||
return nil, ""
|
return nil, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
280
appWasm.go
280
appWasm.go
|
@ -4,6 +4,7 @@ package rui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
|
"strings"
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,35 +16,88 @@ type wasmApp struct {
|
||||||
createContentFunc func(Session) SessionContent
|
createContentFunc func(Session) SessionContent
|
||||||
session Session
|
session Session
|
||||||
brige webBrige
|
brige webBrige
|
||||||
|
close chan DataObject
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *wasmApp) Finish() {
|
func (app *wasmApp) Finish() {
|
||||||
app.session.close()
|
app.session.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *wasmApp) startSession(this js.Value, args []js.Value) interface{} {
|
func wasmLog(text string) {
|
||||||
if app.createContentFunc == nil || len(args) == 1 {
|
js.Global().Call("log", text)
|
||||||
return nil
|
}
|
||||||
}
|
|
||||||
|
|
||||||
params := ParseDataText(args[0].String())
|
func (app *wasmApp) handleMessage(this js.Value, args []js.Value) any {
|
||||||
session := newSession(app, 0, "", params)
|
if len(args) > 0 {
|
||||||
session.setBrige(make(chan DataObject), app.brige)
|
if obj := ParseDataText(args[0].String()); obj != nil {
|
||||||
if !session.setContent(app.createContentFunc(session), session) {
|
switch command := obj.Tag(); command {
|
||||||
return nil
|
/*
|
||||||
}
|
case "startSession":
|
||||||
|
answer := ""
|
||||||
|
if session, answer = app.startSession(obj, events, brige); session != nil {
|
||||||
|
if !brige.writeMessage(answer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
session.onStart()
|
||||||
|
go sessionEventHandler(session, events, brige)
|
||||||
|
}
|
||||||
|
|
||||||
app.session = session
|
case "reconnect":
|
||||||
|
if sessionText, ok := obj.PropertyValue("session"); ok {
|
||||||
|
if sessionID, err := strconv.Atoi(sessionText); err == nil {
|
||||||
|
if session = app.sessions[sessionID]; session != nil {
|
||||||
|
session.setBrige(events, brige)
|
||||||
|
answer := allocStringBuilder()
|
||||||
|
defer freeStringBuilder(answer)
|
||||||
|
|
||||||
answer := allocStringBuilder()
|
session.writeInitScript(answer)
|
||||||
defer freeStringBuilder(answer)
|
if !brige.writeMessage(answer.String()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
session.onReconnect()
|
||||||
|
go sessionEventHandler(session, events, brige)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
DebugLogF("Session #%d not exists", sessionID)
|
||||||
|
} else {
|
||||||
|
ErrorLog(`strconv.Atoi(sessionText) error: ` + err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ErrorLog(`"session" key not found`)
|
||||||
|
}
|
||||||
|
|
||||||
session.writeInitScript(answer)
|
answer := ""
|
||||||
answerText := answer.String()
|
if session, answer = app.startSession(obj, events, brige); session != nil {
|
||||||
|
if !brige.writeMessage(answer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
session.onStart()
|
||||||
|
go sessionEventHandler(session, events, brige)
|
||||||
|
}
|
||||||
|
|
||||||
if ProtocolInDebugLog {
|
case "disconnect":
|
||||||
DebugLog("Start session:")
|
session.onDisconnect()
|
||||||
DebugLog(answerText)
|
return
|
||||||
|
|
||||||
|
case "session-close":
|
||||||
|
session.onFinish()
|
||||||
|
session.App().removeSession(session.ID())
|
||||||
|
brige.close()
|
||||||
|
|
||||||
|
*/
|
||||||
|
case "answer":
|
||||||
|
app.session.handleAnswer(obj)
|
||||||
|
|
||||||
|
case "imageLoaded":
|
||||||
|
app.session.imageManager().imageLoaded(obj, app.session)
|
||||||
|
|
||||||
|
case "imageError":
|
||||||
|
app.session.imageManager().imageLoadError(obj, app.session)
|
||||||
|
|
||||||
|
default:
|
||||||
|
app.session.handleEvent(command, obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -51,117 +105,75 @@ func (app *wasmApp) startSession(this js.Value, args []js.Value) interface{} {
|
||||||
func (app *wasmApp) removeSession(id int) {
|
func (app *wasmApp) removeSession(id int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (app *wasmApp) createSession() Session {
|
||||||
|
session := newSession(app, 0, "", ParseDataText(js.Global().Call("sessionInfo", "").String()))
|
||||||
|
session.setBrige(app.close, app.brige)
|
||||||
|
session.setContent(app.createContentFunc(session))
|
||||||
|
return session
|
||||||
|
}
|
||||||
|
|
||||||
|
func (app *wasmApp) init() {
|
||||||
|
|
||||||
|
document := js.Global().Get("document")
|
||||||
|
body := document.Call("querySelector", "body")
|
||||||
|
|
||||||
|
script := document.Call("createElement", "script")
|
||||||
|
script.Set("type", "text/javascript")
|
||||||
|
script.Set("textContent", defaultScripts+wasmScripts)
|
||||||
|
body.Call("appendChild", script)
|
||||||
|
|
||||||
|
js.Global().Set("sendMessage", js.FuncOf(app.handleMessage))
|
||||||
|
|
||||||
|
app.close = make(chan DataObject)
|
||||||
|
app.session = app.createSession()
|
||||||
|
|
||||||
|
style := document.Call("createElement", "style")
|
||||||
|
css := appStyles + app.session.getCurrentTheme().cssText(app.session)
|
||||||
|
css = strings.ReplaceAll(css, `\n`, "\n")
|
||||||
|
css = strings.ReplaceAll(css, `\t`, "\t")
|
||||||
|
style.Set("textContent", css)
|
||||||
|
document.Call("querySelector", "head").Call("appendChild", style)
|
||||||
|
|
||||||
|
buffer := allocStringBuilder()
|
||||||
|
defer freeStringBuilder(buffer)
|
||||||
|
|
||||||
|
div := document.Call("createElement", "div")
|
||||||
|
div.Set("className", "ruiRoot")
|
||||||
|
div.Set("id", "ruiRootView")
|
||||||
|
viewHTML(app.session.RootView(), buffer)
|
||||||
|
div.Set("innerHTML", buffer.String())
|
||||||
|
body.Call("appendChild", div)
|
||||||
|
|
||||||
|
div = document.Call("createElement", "div")
|
||||||
|
div.Set("className", "ruiPopupLayer")
|
||||||
|
div.Set("id", "ruiPopupLayer")
|
||||||
|
div.Set("onclick", "clickOutsidePopup(event)")
|
||||||
|
div.Set("style", "visibility: hidden;")
|
||||||
|
body.Call("appendChild", div)
|
||||||
|
|
||||||
|
div = document.Call("createElement", "a")
|
||||||
|
div.Set("id", "ruiDownloader")
|
||||||
|
div.Set("download", "")
|
||||||
|
div.Set("style", "display: none;")
|
||||||
|
body.Call("appendChild", div)
|
||||||
|
}
|
||||||
|
|
||||||
// StartApp - create the new wasmApp and start it
|
// StartApp - create the new wasmApp and start it
|
||||||
func StartApp(addr string, createContentFunc func(Session) SessionContent, params AppParams) {
|
func StartApp(addr string, createContentFunc func(Session) SessionContent, params AppParams) {
|
||||||
app := new(wasmApp)
|
SetDebugLog(wasmLog)
|
||||||
app.params = params
|
SetErrorLog(wasmLog)
|
||||||
app.createContentFunc = createContentFunc
|
|
||||||
|
|
||||||
if createContentFunc == nil {
|
if createContentFunc == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app := new(wasmApp)
|
||||||
|
app.params = params
|
||||||
|
app.createContentFunc = createContentFunc
|
||||||
app.brige = createWasmBrige()
|
app.brige = createWasmBrige()
|
||||||
js.Global().Set("startSession", js.FuncOf(app.startSession))
|
|
||||||
|
|
||||||
/*
|
app.init()
|
||||||
script := defaultScripts + wasmScripts
|
<-app.close
|
||||||
script = strings.ReplaceAll(script, "\\", `\\`)
|
|
||||||
script = strings.ReplaceAll(script, "\n", `\n`)
|
|
||||||
script = strings.ReplaceAll(script, "\t", `\t`)
|
|
||||||
script = strings.ReplaceAll(script, "\"", `\"`)
|
|
||||||
script = strings.ReplaceAll(script, "'", `\'`)
|
|
||||||
|
|
||||||
js.Global().Call("execScript", `document.getElementById('ruiscript').text += "`+script+`"`)
|
|
||||||
*/
|
|
||||||
|
|
||||||
document := js.Global().Get("document")
|
|
||||||
body := document.Call("querySelector", "body")
|
|
||||||
body.Set("innerHTML", `<div class="ruiRoot" id="ruiRootView"></div>
|
|
||||||
<div class="ruiPopupLayer" id="ruiPopupLayer" style="visibility: hidden;" onclick="clickOutsidePopup(event)"></div>
|
|
||||||
<a id="ruiDownloader" download style="display: none;"></a>`)
|
|
||||||
|
|
||||||
//js.Global().Call("execScript", "initSession()")
|
|
||||||
js.Global().Call("initSession", "")
|
|
||||||
//window.Call("execScript", "initSession()")
|
|
||||||
|
|
||||||
for true {
|
|
||||||
if message, ok := app.brige.readMessage(); ok && app.session != nil {
|
|
||||||
if ProtocolInDebugLog {
|
|
||||||
DebugLog(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
if obj := ParseDataText(message); obj != nil {
|
|
||||||
switch command := obj.Tag(); command {
|
|
||||||
/*
|
|
||||||
case "startSession":
|
|
||||||
answer := ""
|
|
||||||
if session, answer = app.startSession(obj, events, brige); session != nil {
|
|
||||||
if !brige.writeMessage(answer) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
session.onStart()
|
|
||||||
go sessionEventHandler(session, events, brige)
|
|
||||||
}
|
|
||||||
|
|
||||||
case "reconnect":
|
|
||||||
if sessionText, ok := obj.PropertyValue("session"); ok {
|
|
||||||
if sessionID, err := strconv.Atoi(sessionText); err == nil {
|
|
||||||
if session = app.sessions[sessionID]; session != nil {
|
|
||||||
session.setBrige(events, brige)
|
|
||||||
answer := allocStringBuilder()
|
|
||||||
defer freeStringBuilder(answer)
|
|
||||||
|
|
||||||
session.writeInitScript(answer)
|
|
||||||
if !brige.writeMessage(answer.String()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
session.onReconnect()
|
|
||||||
go sessionEventHandler(session, events, brige)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
DebugLogF("Session #%d not exists", sessionID)
|
|
||||||
} else {
|
|
||||||
ErrorLog(`strconv.Atoi(sessionText) error: ` + err.Error())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ErrorLog(`"session" key not found`)
|
|
||||||
}
|
|
||||||
|
|
||||||
answer := ""
|
|
||||||
if session, answer = app.startSession(obj, events, brige); session != nil {
|
|
||||||
if !brige.writeMessage(answer) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
session.onStart()
|
|
||||||
go sessionEventHandler(session, events, brige)
|
|
||||||
}
|
|
||||||
|
|
||||||
case "disconnect":
|
|
||||||
session.onDisconnect()
|
|
||||||
return
|
|
||||||
|
|
||||||
case "session-close":
|
|
||||||
session.onFinish()
|
|
||||||
session.App().removeSession(session.ID())
|
|
||||||
brige.close()
|
|
||||||
|
|
||||||
*/
|
|
||||||
case "answer":
|
|
||||||
app.session.handleAnswer(obj)
|
|
||||||
|
|
||||||
case "imageLoaded":
|
|
||||||
app.session.imageManager().imageLoaded(obj, app.session)
|
|
||||||
|
|
||||||
case "imageError":
|
|
||||||
app.session.imageManager().imageLoadError(obj, app.session)
|
|
||||||
|
|
||||||
default:
|
|
||||||
app.session.handleEvent(command, obj)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func FinishApp() {
|
func FinishApp() {
|
||||||
|
@ -171,31 +183,3 @@ func FinishApp() {
|
||||||
func OpenBrowser(url string) bool {
|
func OpenBrowser(url string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
func OpenBrowser(url string) bool {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "linux":
|
|
||||||
for _, provider := range []string{"xdg-open", "x-www-browser", "www-browser"} {
|
|
||||||
if _, err = exec.LookPath(provider); err == nil {
|
|
||||||
if exec.Command(provider, url).Start(); err == nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case "windows":
|
|
||||||
err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start()
|
|
||||||
|
|
||||||
case "darwin":
|
|
||||||
err = exec.Command("open", url).Start()
|
|
||||||
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("unsupported platform")
|
|
||||||
}
|
|
||||||
|
|
||||||
return err != nil
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
|
@ -14,6 +14,47 @@ window.onblur = function(event) {
|
||||||
sendMessage( "session-pause{session=" + sessionID +"}" );
|
sendMessage( "session-pause{session=" + sessionID +"}" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sessionInfo() {
|
||||||
|
|
||||||
|
const touch_screen = (('ontouchstart' in document.documentElement) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)) ? "1" : "0";
|
||||||
|
var message = "startSession{touch=" + touch_screen
|
||||||
|
|
||||||
|
const style = window.getComputedStyle(document.body);
|
||||||
|
if (style) {
|
||||||
|
var direction = style.getPropertyValue('direction');
|
||||||
|
if (direction) {
|
||||||
|
message += ",direction=" + direction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const lang = window.navigator.language;
|
||||||
|
if (lang) {
|
||||||
|
message += ",language=\"" + lang + "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
const langs = window.navigator.languages;
|
||||||
|
if (langs) {
|
||||||
|
message += ",languages=\"" + langs + "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
const userAgent = window.navigator.userAgent
|
||||||
|
if (userAgent) {
|
||||||
|
message += ",user-agent=\"" + userAgent + "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
const darkThemeMq = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
|
if (darkThemeMq.matches) {
|
||||||
|
message += ",dark=1";
|
||||||
|
}
|
||||||
|
|
||||||
|
const pixelRatio = window.devicePixelRatio;
|
||||||
|
if (pixelRatio) {
|
||||||
|
message += ",pixel-ratio=" + pixelRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
return message + "}";
|
||||||
|
}
|
||||||
|
|
||||||
function getIntAttribute(element, tag) {
|
function getIntAttribute(element, tag) {
|
||||||
let value = element.getAttribute(tag);
|
let value = element.getAttribute(tag);
|
||||||
if (value) {
|
if (value) {
|
||||||
|
@ -1276,6 +1317,10 @@ function startDowndload(url, filename) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setTitle(title) {
|
||||||
|
document.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
function setTitleColor(color) {
|
function setTitleColor(color) {
|
||||||
var metas = document.getElementsByTagName('meta');
|
var metas = document.getElementsByTagName('meta');
|
||||||
if (metas) {
|
if (metas) {
|
||||||
|
@ -1292,6 +1337,10 @@ function setTitleColor(color) {
|
||||||
document.getElementsByTagName('head')[0].appendChild(meta);
|
document.getElementsByTagName('head')[0].appendChild(meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openURL(url) {
|
||||||
|
window.open(url, "_blank");
|
||||||
|
}
|
||||||
|
|
||||||
function detailsEvent(element) {
|
function detailsEvent(element) {
|
||||||
sendMessage("details-open{session=" + sessionID + ",id=" + element.id + ",open=" + (element.open ? "1}" : "0}"));
|
sendMessage("details-open{session=" + sessionID + ",id=" + element.id + ",open=" + (element.open ? "1}" : "0}"));
|
||||||
}
|
}
|
||||||
|
@ -1742,4 +1791,8 @@ function getPropertyValue(answerID, elementId, name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage('answer{answerID=' + answerID + ', value=""}')
|
sendMessage('answer{answerID=' + answerID + ', value=""}')
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendStyles(styles) {
|
||||||
|
document.querySelector('style').textContent += styles
|
||||||
}
|
}
|
|
@ -26,44 +26,7 @@ window.onload = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
function socketOpen() {
|
function socketOpen() {
|
||||||
|
sendMessage( sessionInfo() );
|
||||||
const touch_screen = (('ontouchstart' in document.documentElement) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)) ? "1" : "0";
|
|
||||||
var message = "startSession{touch=" + touch_screen
|
|
||||||
|
|
||||||
const style = window.getComputedStyle(document.body);
|
|
||||||
if (style) {
|
|
||||||
var direction = style.getPropertyValue('direction');
|
|
||||||
if (direction) {
|
|
||||||
message += ",direction=" + direction
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const lang = window.navigator.language;
|
|
||||||
if (lang) {
|
|
||||||
message += ",language=\"" + lang + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
const langs = window.navigator.languages;
|
|
||||||
if (langs) {
|
|
||||||
message += ",languages=\"" + langs + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
const userAgent = window.navigator.userAgent
|
|
||||||
if (userAgent) {
|
|
||||||
message += ",user-agent=\"" + userAgent + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
const darkThemeMq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
||||||
if (darkThemeMq.matches) {
|
|
||||||
message += ",dark=1";
|
|
||||||
}
|
|
||||||
|
|
||||||
const pixelRatio = window.devicePixelRatio;
|
|
||||||
if (pixelRatio) {
|
|
||||||
message += ",pixel-ratio=" + pixelRatio;
|
|
||||||
}
|
|
||||||
|
|
||||||
sendMessage( message + "}" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function socketReopen() {
|
function socketReopen() {
|
||||||
|
|
43
app_wasm.js
43
app_wasm.js
|
@ -1,47 +1,8 @@
|
||||||
|
|
||||||
|
function log(s) {
|
||||||
function initSession() {
|
console.log(s);
|
||||||
|
|
||||||
const touch_screen = (('ontouchstart' in document.documentElement) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)) ? "1" : "0";
|
|
||||||
var message = "sessionInfo{touch=" + touch_screen
|
|
||||||
|
|
||||||
const style = window.getComputedStyle(document.body);
|
|
||||||
if (style) {
|
|
||||||
var direction = style.getPropertyValue('direction');
|
|
||||||
if (direction) {
|
|
||||||
message += ",direction=" + direction
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const lang = window.navigator.language;
|
|
||||||
if (lang) {
|
|
||||||
message += ",language=\"" + lang + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
const langs = window.navigator.languages;
|
|
||||||
if (langs) {
|
|
||||||
message += ",languages=\"" + langs + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
const userAgent = window.navigator.userAgent
|
|
||||||
if (userAgent) {
|
|
||||||
message += ",user-agent=\"" + userAgent + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
const darkThemeMq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
||||||
if (darkThemeMq.matches) {
|
|
||||||
message += ",dark=1";
|
|
||||||
}
|
|
||||||
|
|
||||||
const pixelRatio = window.devicePixelRatio;
|
|
||||||
if (pixelRatio) {
|
|
||||||
message += ",pixel-ratio=" + pixelRatio;
|
|
||||||
}
|
|
||||||
|
|
||||||
startSession( message + "}" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
window.onfocus = function(event) {
|
window.onfocus = function(event) {
|
||||||
windowFocus = true
|
windowFocus = true
|
||||||
sendMessage( "session-resume{session=" + sessionID +"}" );
|
sendMessage( "session-resume{session=" + sessionID +"}" );
|
||||||
|
|
|
@ -2,7 +2,6 @@ package rui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -24,7 +23,7 @@ func (session *sessionData) startDownload(file downloadFile) {
|
||||||
currentDownloadId++
|
currentDownloadId++
|
||||||
id := strconv.Itoa(currentDownloadId)
|
id := strconv.Itoa(currentDownloadId)
|
||||||
downloadFiles[id] = file
|
downloadFiles[id] = file
|
||||||
session.runScript(fmt.Sprintf(`startDowndload("%s", "%s")`, id, file.filename))
|
session.runFunc("startDowndload", id, file.filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
func serveDownloadFile(id string, w http.ResponseWriter, r *http.Request) bool {
|
func serveDownloadFile(id string, w http.ResponseWriter, r *http.Request) bool {
|
||||||
|
|
13
session.go
13
session.go
|
@ -67,7 +67,7 @@ type Session interface {
|
||||||
|
|
||||||
// Content returns the SessionContent of session
|
// Content returns the SessionContent of session
|
||||||
Content() SessionContent
|
Content() SessionContent
|
||||||
setContent(content SessionContent, self Session) bool
|
setContent(content SessionContent) bool
|
||||||
|
|
||||||
// SetTitle sets the text of the browser title/tab
|
// SetTitle sets the text of the browser title/tab
|
||||||
SetTitle(title string)
|
SetTitle(title string)
|
||||||
|
@ -91,6 +91,7 @@ type Session interface {
|
||||||
// OpenURL opens the url in the new browser tab
|
// OpenURL opens the url in the new browser tab
|
||||||
OpenURL(url string)
|
OpenURL(url string)
|
||||||
|
|
||||||
|
getCurrentTheme() Theme
|
||||||
registerAnimation(props []AnimatedProperty) string
|
registerAnimation(props []AnimatedProperty) string
|
||||||
|
|
||||||
resolveConstants(value string) (string, bool)
|
resolveConstants(value string) (string, bool)
|
||||||
|
@ -245,10 +246,10 @@ func (session *sessionData) Content() SessionContent {
|
||||||
return session.content
|
return session.content
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *sessionData) setContent(content SessionContent, self Session) bool {
|
func (session *sessionData) setContent(content SessionContent) bool {
|
||||||
if content != nil {
|
if content != nil {
|
||||||
session.content = content
|
session.content = content
|
||||||
session.rootView = content.CreateRootView(self)
|
session.rootView = content.CreateRootView(session)
|
||||||
if session.rootView != nil {
|
if session.rootView != nil {
|
||||||
session.rootView.setParentID("ruiRootView")
|
session.rootView.setParentID("ruiRootView")
|
||||||
return true
|
return true
|
||||||
|
@ -554,11 +555,11 @@ func (session *sessionData) handleEvent(command string, data DataObject) {
|
||||||
|
|
||||||
func (session *sessionData) SetTitle(title string) {
|
func (session *sessionData) SetTitle(title string) {
|
||||||
title, _ = session.GetString(title)
|
title, _ = session.GetString(title)
|
||||||
session.runScript(`document.title = "` + title + `";`)
|
session.runFunc("setTitle", title)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *sessionData) SetTitleColor(color Color) {
|
func (session *sessionData) SetTitleColor(color Color) {
|
||||||
session.runScript(`setTitleColor("` + color.cssString() + `");`)
|
session.runFunc("setTitleColor", color.cssString())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *sessionData) RemoteAddr() string {
|
func (session *sessionData) RemoteAddr() string {
|
||||||
|
@ -570,5 +571,5 @@ func (session *sessionData) OpenURL(urlStr string) {
|
||||||
ErrorLog(err.Error())
|
ErrorLog(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
session.runScript(`window.open("` + urlStr + `", "_blank");`)
|
session.runFunc("openURL", urlStr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -325,15 +325,16 @@ func (session *sessionData) SetLanguage(lang string) {
|
||||||
if lang != session.language {
|
if lang != session.language {
|
||||||
session.language = lang
|
session.language = lang
|
||||||
|
|
||||||
if session.rootView != nil {
|
if session.rootView != nil && session.brige != nil {
|
||||||
buffer := allocStringBuilder()
|
buffer := allocStringBuilder()
|
||||||
defer freeStringBuilder(buffer)
|
defer freeStringBuilder(buffer)
|
||||||
|
|
||||||
buffer.WriteString(`document.getElementById('ruiRootView').innerHTML = '`)
|
//buffer.WriteString(`document.getElementById('ruiRootView').innerHTML = '`)
|
||||||
viewHTML(session.rootView, buffer)
|
viewHTML(session.rootView, buffer)
|
||||||
buffer.WriteString("';\nscanElementsSize();")
|
//buffer.WriteString("';\nscanElementsSize();")
|
||||||
|
|
||||||
session.runScript(buffer.String())
|
//session.runScript(buffer.String())
|
||||||
|
session.brige.updateInnerHTML("ruiRootView", buffer.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
98
wasmBrige.go
98
wasmBrige.go
|
@ -3,11 +3,10 @@
|
||||||
package rui
|
package rui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type wasmBrige struct {
|
type wasmBrige struct {
|
||||||
|
@ -18,11 +17,6 @@ type wasmBrige struct {
|
||||||
closed bool
|
closed bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var upgrader = websocket.Upgrader{
|
|
||||||
ReadBufferSize: 1024,
|
|
||||||
WriteBufferSize: 8096,
|
|
||||||
}
|
|
||||||
|
|
||||||
func createWasmBrige() webBrige {
|
func createWasmBrige() webBrige {
|
||||||
brige := new(wasmBrige)
|
brige := new(wasmBrige)
|
||||||
brige.queue = make(chan string, 1000)
|
brige.queue = make(chan string, 1000)
|
||||||
|
@ -30,23 +24,58 @@ func createWasmBrige() webBrige {
|
||||||
brige.answer = make(map[int]chan DataObject)
|
brige.answer = make(map[int]chan DataObject)
|
||||||
brige.closed = false
|
brige.closed = false
|
||||||
|
|
||||||
js.Global().Set("sendMessage", js.FuncOf(brige.sendMessage))
|
|
||||||
|
|
||||||
return brige
|
return brige
|
||||||
}
|
}
|
||||||
|
|
||||||
func (brige *wasmBrige) sendMessage(this js.Value, args []js.Value) interface{} {
|
func (brige *wasmBrige) startUpdateScript(htmlID string) bool {
|
||||||
if len(args) > 0 {
|
return false
|
||||||
brige.queue <- args[0].String()
|
}
|
||||||
|
|
||||||
|
func (brige *wasmBrige) finishUpdateScript(htmlID string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (brige *wasmBrige) runFunc(funcName string, args ...any) bool {
|
||||||
|
if ProtocolInDebugLog {
|
||||||
|
text := funcName + "("
|
||||||
|
for i, arg := range args {
|
||||||
|
if i > 0 {
|
||||||
|
text += fmt.Sprintf(", `%v`", arg)
|
||||||
|
} else {
|
||||||
|
text += fmt.Sprintf("`%v`", arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DebugLog(text + ")")
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
js.Global().Call(funcName, args...)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (brige *wasmBrige) updateInnerHTML(htmlID, html string) {
|
||||||
|
brige.runFunc("updateInnerHTML", htmlID, html)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (brige *wasmBrige) appendToInnerHTML(htmlID, html string) {
|
||||||
|
brige.runFunc("appendToInnerHTML", htmlID, html)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (brige *wasmBrige) updateCSSProperty(htmlID, property, value string) {
|
||||||
|
brige.runFunc("updateCSSProperty", htmlID, property, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (brige *wasmBrige) updateProperty(htmlID, property string, value any) {
|
||||||
|
brige.runFunc("updateProperty", htmlID, property, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (brige *wasmBrige) removeProperty(htmlID, property string) {
|
||||||
|
brige.runFunc("removeProperty", htmlID, property)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (brige *wasmBrige) close() {
|
func (brige *wasmBrige) close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (brige *wasmBrige) readMessage() (string, bool) {
|
func (brige *wasmBrige) readMessage() (string, bool) {
|
||||||
return <-brige.queue, true
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (brige *wasmBrige) writeMessage(script string) bool {
|
func (brige *wasmBrige) writeMessage(script string) bool {
|
||||||
|
@ -61,25 +90,36 @@ func (brige *wasmBrige) writeMessage(script string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (brige *wasmBrige) runGetterScript(script string) DataObject {
|
/*
|
||||||
brige.answerMutex.Lock()
|
func (brige *wasmBrige) runGetterScript(script string) DataObject {
|
||||||
answerID := brige.answerID
|
brige.answerMutex.Lock()
|
||||||
brige.answerID++
|
answerID := brige.answerID
|
||||||
brige.answerMutex.Unlock()
|
brige.answerID++
|
||||||
|
brige.answerMutex.Unlock()
|
||||||
|
|
||||||
answer := make(chan DataObject)
|
answer := make(chan DataObject)
|
||||||
brige.answer[answerID] = answer
|
brige.answer[answerID] = answer
|
||||||
errorText := ""
|
errorText := ""
|
||||||
|
|
||||||
js.Global().Set("answerID", strconv.Itoa(answerID))
|
js.Global().Set("answerID", strconv.Itoa(answerID))
|
||||||
|
|
||||||
window := js.Global().Get("window")
|
window := js.Global().Get("window")
|
||||||
window.Call("execScript", script)
|
window.Call("execScript", script)
|
||||||
|
|
||||||
result := NewDataObject("error")
|
result := NewDataObject("error")
|
||||||
result.SetPropertyValue("text", errorText)
|
result.SetPropertyValue("text", errorText)
|
||||||
delete(brige.answer, answerID)
|
delete(brige.answer, answerID)
|
||||||
return result
|
return result
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (brige *wasmBrige) canvasTextMetrics(htmlID, font, text string) TextMetrics {
|
||||||
|
// TODO
|
||||||
|
return TextMetrics{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (brige *wasmBrige) htmlPropertyValue(htmlID, name string) string {
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (brige *wasmBrige) answerReceived(answer DataObject) {
|
func (brige *wasmBrige) answerReceived(answer DataObject) {
|
||||||
|
|
|
@ -175,7 +175,6 @@ func (brige *wsBrige) updateCSSProperty(htmlID, property, value string) {
|
||||||
} else {
|
} else {
|
||||||
brige.runFunc("updateCSSProperty", htmlID, property, value)
|
brige.runFunc("updateCSSProperty", htmlID, property, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (brige *wsBrige) updateProperty(htmlID, property string, value any) {
|
func (brige *wsBrige) updateProperty(htmlID, property string, value any) {
|
||||||
|
|
Loading…
Reference in New Issue