mirror of https://github.com/anoshenko/rui.git
Bug fixing
This commit is contained in:
parent
a9e4eddb3f
commit
b18c632a44
88
appServer.go
88
appServer.go
|
|
@ -128,6 +128,9 @@ func (app *application) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
io.WriteString(w, app.getStartPage())
|
io.WriteString(w, app.getStartPage())
|
||||||
|
|
||||||
|
case "/e":
|
||||||
|
app.sseHandler(w, req)
|
||||||
|
|
||||||
case "/ws":
|
case "/ws":
|
||||||
if bridge := createSocketBridge(w, req); bridge != nil {
|
if bridge := createSocketBridge(w, req); bridge != nil {
|
||||||
go app.socketReader(bridge)
|
go app.socketReader(bridge)
|
||||||
|
|
@ -157,6 +160,7 @@ func (app *application) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func setSessionIDCookie(w http.ResponseWriter, sessionID int) {
|
func setSessionIDCookie(w http.ResponseWriter, sessionID int) {
|
||||||
cookie := http.Cookie{
|
cookie := http.Cookie{
|
||||||
Name: "session",
|
Name: "session",
|
||||||
|
|
@ -174,6 +178,7 @@ func getSessionIDCookie(req *http.Request) (int, error) {
|
||||||
|
|
||||||
return strconv.Atoi(cookie.Value)
|
return strconv.Atoi(cookie.Value)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
func (app *application) postHandler(w http.ResponseWriter, req *http.Request) {
|
func (app *application) postHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
|
|
@ -208,7 +213,12 @@ func (app *application) postHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
command := obj.Tag()
|
command := obj.Tag()
|
||||||
|
|
||||||
if session == nil || command == "startSession" {
|
if session == nil {
|
||||||
|
if command != "start-session" {
|
||||||
|
io.WriteString(w, "reloadPage();")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
events := make(chan DataObject, 1024)
|
events := make(chan DataObject, 1024)
|
||||||
bridge := createHttpBridge(req)
|
bridge := createHttpBridge(req)
|
||||||
response = bridge.response
|
response = bridge.response
|
||||||
|
|
@ -219,30 +229,25 @@ func (app *application) postHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
go sessionEventHandler(session, events, bridge)
|
go sessionEventHandler(session, events, bridge)
|
||||||
|
|
||||||
start := func() {
|
|
||||||
startSession(session, app.createContentFunc)
|
|
||||||
bridge.sendResponse()
|
|
||||||
}
|
|
||||||
go start()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch command {
|
switch command {
|
||||||
|
|
||||||
case "startSession":
|
|
||||||
// do nothing
|
|
||||||
|
|
||||||
case "nop":
|
|
||||||
session.sendResponse()
|
|
||||||
|
|
||||||
case "session-close":
|
case "session-close":
|
||||||
session.onFinish()
|
session.onFinish()
|
||||||
session.App().removeSession(session.ID())
|
session.App().removeSession(session.ID())
|
||||||
return
|
return
|
||||||
|
|
||||||
|
case "nop":
|
||||||
|
if len(response) == 0 {
|
||||||
|
session.addToEventsQueue(obj)
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if !session.handleAnswer(command, obj) {
|
if !session.handleAnswer(command, obj) {
|
||||||
session.addToEventsQueue(obj)
|
session.addToEventsQueue(obj)
|
||||||
|
} else {
|
||||||
|
io.WriteString(w, "sendNop();")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -252,6 +257,20 @@ func (app *application) postHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (app *application) sseHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
|
/*
|
||||||
|
sessionID, err := strconv.Atoi(req.URL.Query().Get("id"))
|
||||||
|
if err != nil {
|
||||||
|
ErrorLog("SessionID error: " + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if sessionInfo, ok := app.sessions[sessionID]; ok {
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
func getSessionID(obj DataObject) (int, bool) {
|
func getSessionID(obj DataObject) (int, bool) {
|
||||||
sessionText, ok := obj.PropertyValue("session")
|
sessionText, ok := obj.PropertyValue("session")
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -286,14 +305,14 @@ func (app *application) socketReader(bridge *wsBridge) {
|
||||||
obj, err := ParseDataText(message)
|
obj, err := ParseDataText(message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrorLog(err.Error())
|
ErrorLog(err.Error())
|
||||||
return
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
switch command := obj.Tag(); command {
|
switch command := obj.Tag(); command {
|
||||||
case "startSession":
|
case "start-session":
|
||||||
if session = app.createSession(obj, events, bridge, nil); session != nil {
|
if session = app.createSession(obj, events, bridge, nil); session != nil {
|
||||||
go startSession(session, app.createContentFunc)
|
|
||||||
go sessionEventHandler(session, events, bridge)
|
go sessionEventHandler(session, events, bridge)
|
||||||
|
events <- obj
|
||||||
}
|
}
|
||||||
|
|
||||||
case "reconnect":
|
case "reconnect":
|
||||||
|
|
@ -311,16 +330,6 @@ func (app *application) socketReader(bridge *wsBridge) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if session == nil {
|
if session == nil {
|
||||||
/* answer := ""
|
|
||||||
if session, answer = app.startSession(obj, events, bridge, nil); session != nil {
|
|
||||||
if !bridge.writeMessage(answer) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
session.onStart()
|
|
||||||
go sessionEventHandler(session, events, bridge)
|
|
||||||
bridge.writeMessage("restartSession();")
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
bridge.writeMessage("reloadPage();")
|
bridge.writeMessage("reloadPage();")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -339,6 +348,7 @@ func sessionEventHandler(session Session, events chan DataObject, bridge bridge)
|
||||||
|
|
||||||
switch command := data.Tag(); command {
|
switch command := data.Tag(); command {
|
||||||
case "disconnect":
|
case "disconnect":
|
||||||
|
session.setBridge(nil, nil)
|
||||||
session.onDisconnect()
|
session.onDisconnect()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -348,8 +358,11 @@ func sessionEventHandler(session Session, events chan DataObject, bridge bridge)
|
||||||
bridge.close()
|
bridge.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
case "nop":
|
||||||
|
session.sendResponse()
|
||||||
|
|
||||||
default:
|
default:
|
||||||
go session.handleEvent(command, data)
|
session.handleEvent(command, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -373,27 +386,6 @@ func (app *application) createSession(params DataObject, events chan DataObject,
|
||||||
return session
|
return session
|
||||||
}
|
}
|
||||||
|
|
||||||
func startSession(session Session, createContentFunc func(Session) SessionContent) {
|
|
||||||
|
|
||||||
if !session.setContent(createContentFunc(session)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
answer := allocStringBuilder()
|
|
||||||
defer freeStringBuilder(answer)
|
|
||||||
|
|
||||||
session.writeInitScript(answer)
|
|
||||||
answerText := answer.String()
|
|
||||||
|
|
||||||
if ProtocolInDebugLog {
|
|
||||||
DebugLog("Start session:")
|
|
||||||
DebugLog(answerText)
|
|
||||||
}
|
|
||||||
|
|
||||||
session.writeScript(answerText)
|
|
||||||
session.onStart()
|
|
||||||
}
|
|
||||||
|
|
||||||
var apps = []*application{}
|
var apps = []*application{}
|
||||||
|
|
||||||
// StartApp - create the new application and start it
|
// StartApp - create the new application and start it
|
||||||
|
|
|
||||||
40
app_post.js
40
app_post.js
|
|
@ -1,5 +1,10 @@
|
||||||
|
let eventSource
|
||||||
|
|
||||||
async function sendMessage(message) {
|
async function sendMessage(message) {
|
||||||
|
if (!eventSource) {
|
||||||
|
createEventSource();
|
||||||
|
}
|
||||||
|
|
||||||
const response = await fetch('/', {
|
const response = await fetch('/', {
|
||||||
method : 'POST',
|
method : 'POST',
|
||||||
body : message,
|
body : message,
|
||||||
|
|
@ -12,14 +17,43 @@ async function sendMessage(message) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createEventSource() {
|
||||||
|
/*
|
||||||
|
eventSource = new EventSource("e?id="+sessionID);
|
||||||
|
eventSource.onmessage = onEventMessage;
|
||||||
|
eventSource.onerror = onEventError;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEventMessage(event) {
|
||||||
|
let script = base64ToString(event.data);
|
||||||
|
if (script != "") {
|
||||||
|
window.eval(script)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEventError(err) {
|
||||||
|
console.log(err);
|
||||||
|
eventSource = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
sendMessage( sessionInfo() );
|
sendMessage( sessionInfo("start-session") );
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onfocus = function() {
|
window.onfocus = function() {
|
||||||
windowFocus = true
|
windowFocus = true;
|
||||||
sendMessage( "session-resume{}" );
|
sendMessage( "session-resume{session=" + sessionID +"}" );
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeSocket() {
|
function closeSocket() {
|
||||||
|
if (eventSource) {
|
||||||
|
eventSource.close();
|
||||||
|
eventSource = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendNop() {
|
||||||
|
sendMessage( "nop{session=" + sessionID +"}" );
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
//let sessionID = "0"
|
|
||||||
let windowFocus = true
|
let windowFocus = true
|
||||||
|
|
||||||
window.onresize = function() {
|
window.onresize = function() {
|
||||||
|
|
@ -18,10 +17,15 @@ function reloadPage() {
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
function sessionInfo() {
|
function sessionInfo(messageID) {
|
||||||
|
|
||||||
const touch_screen = (('ontouchstart' in document.documentElement) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)) ? "1" : "0";
|
let message = messageID + "{session=" + sessionID
|
||||||
let message = "startSession{session=" + sessionID + ",touch=" + touch_screen
|
|
||||||
|
if (('ontouchstart' in document.documentElement) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)) {
|
||||||
|
message += ",touch=1"
|
||||||
|
} else {
|
||||||
|
message += ",touch=0"
|
||||||
|
}
|
||||||
|
|
||||||
const style = window.getComputedStyle(document.body);
|
const style = window.getComputedStyle(document.body);
|
||||||
if (style) {
|
if (style) {
|
||||||
|
|
@ -65,8 +69,12 @@ function sessionInfo() {
|
||||||
return message + "}";
|
return message + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendReconnectMessage() {
|
||||||
|
sendMessage( sessionInfo("reconnect") );
|
||||||
|
}
|
||||||
|
|
||||||
function restartSession() {
|
function restartSession() {
|
||||||
sendMessage( sessionInfo() );
|
sendMessage( sessionInfo("start-session") );
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIntAttribute(element, tag) {
|
function getIntAttribute(element, tag) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
let socket
|
let socket;
|
||||||
|
|
||||||
function sendMessage(message) {
|
function sendMessage(message) {
|
||||||
if (!socket) {
|
if (!socket) {
|
||||||
createSocket(function() {
|
createSocket(function() {
|
||||||
sendMessage( "reconnect{session=" + sessionID + "}" );
|
sendReconnectMessage();
|
||||||
if (!windowFocus) {
|
if (!windowFocus) {
|
||||||
windowFocus = true;
|
windowFocus = true;
|
||||||
sendMessage( "session-resume{session=" + sessionID +"}" );
|
sendMessage( "session-resume{session=" + sessionID +"}" );
|
||||||
|
|
@ -16,13 +16,13 @@ function sendMessage(message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createSocket(onopen) {
|
function createSocket(onopen) {
|
||||||
let socketUrl = document.location.protocol == "https:" ? "wss://" : "ws://"
|
let socketUrl = document.location.protocol == "https:" ? "wss://" : "ws://" ;
|
||||||
socketUrl += document.location.hostname
|
socketUrl += document.location.hostname;
|
||||||
const port = document.location.port
|
const port = document.location.port;
|
||||||
if (port) {
|
if (port) {
|
||||||
socketUrl += ":" + port
|
socketUrl += ":" + port;
|
||||||
}
|
}
|
||||||
socketUrl += window.location.pathname + "ws"
|
socketUrl += window.location.pathname + "ws";
|
||||||
|
|
||||||
socket = new WebSocket(socketUrl);
|
socket = new WebSocket(socketUrl);
|
||||||
socket.onopen = onopen;
|
socket.onopen = onopen;
|
||||||
|
|
@ -35,19 +35,19 @@ function createSocket(onopen) {
|
||||||
|
|
||||||
function closeSocket() {
|
function closeSocket() {
|
||||||
if (socket) {
|
if (socket) {
|
||||||
socket.close()
|
socket.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onload = createSocket(function() {
|
window.onload = createSocket(function() {
|
||||||
sendMessage( sessionInfo() );
|
sendMessage( sessionInfo("start-session") );
|
||||||
});
|
});
|
||||||
|
|
||||||
window.onfocus = function() {
|
window.onfocus = function() {
|
||||||
windowFocus = true
|
windowFocus = true;
|
||||||
if (!socket) {
|
if (!socket) {
|
||||||
createSocket(function() {
|
createSocket(function() {
|
||||||
sendMessage( "reconnect{session=" + sessionID + "}" );
|
sendReconnectMessage();
|
||||||
sendMessage( "session-resume{session=" + sessionID +"}" );
|
sendMessage( "session-resume{session=" + sessionID +"}" );
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -55,18 +55,14 @@ window.onfocus = function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSocketReopen() {
|
|
||||||
sendMessage( "reconnect{session=" + sessionID + "}" );
|
|
||||||
}
|
|
||||||
|
|
||||||
function socketReconnect() {
|
function socketReconnect() {
|
||||||
if (!socket) {
|
if (!socket) {
|
||||||
createSocket(onSocketReopen);
|
createSocket(sendReconnectMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSocketClose(event) {
|
function onSocketClose(event) {
|
||||||
console.log("socket closed")
|
console.log("socket closed");
|
||||||
socket = null;
|
socket = null;
|
||||||
if (!event.wasClean && windowFocus) {
|
if (!event.wasClean && windowFocus) {
|
||||||
window.setTimeout(socketReconnect, 10000);
|
window.setTimeout(socketReconnect, 10000);
|
||||||
|
|
|
||||||
|
|
@ -130,8 +130,6 @@ func (storage *clientStorageData) handleEvent(command string, data DataObject) {
|
||||||
ErrorLog(text)
|
ErrorLog(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
//case "storageSuccess":
|
|
||||||
|
|
||||||
case "storageValues":
|
case "storageValues":
|
||||||
fn, ok := storage.getResult[request]
|
fn, ok := storage.getResult[request]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"iter"
|
"iter"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Properties interface of properties map
|
// Properties interface of properties map
|
||||||
|
|
@ -37,6 +38,7 @@ type Properties interface {
|
||||||
type propertyList struct {
|
type propertyList struct {
|
||||||
properties map[PropertyName]any
|
properties map[PropertyName]any
|
||||||
normalize func(PropertyName) PropertyName
|
normalize func(PropertyName) PropertyName
|
||||||
|
mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type dataProperty struct {
|
type dataProperty struct {
|
||||||
|
|
@ -60,10 +62,15 @@ func (properties *propertyList) init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (properties *propertyList) IsEmpty() bool {
|
func (properties *propertyList) IsEmpty() bool {
|
||||||
|
properties.mutex.Lock()
|
||||||
|
defer properties.mutex.Unlock()
|
||||||
return len(properties.properties) == 0
|
return len(properties.properties) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (properties *propertyList) getRaw(tag PropertyName) any {
|
func (properties *propertyList) getRaw(tag PropertyName) any {
|
||||||
|
properties.mutex.Lock()
|
||||||
|
defer properties.mutex.Unlock()
|
||||||
|
|
||||||
if value, ok := properties.properties[tag]; ok {
|
if value, ok := properties.properties[tag]; ok {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
@ -71,11 +78,13 @@ func (properties *propertyList) getRaw(tag PropertyName) any {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (properties *propertyList) setRaw(tag PropertyName, value any) {
|
func (properties *propertyList) setRaw(tag PropertyName, value any) {
|
||||||
|
properties.mutex.Lock()
|
||||||
if value == nil {
|
if value == nil {
|
||||||
delete(properties.properties, tag)
|
delete(properties.properties, tag)
|
||||||
} else {
|
} else {
|
||||||
properties.properties[tag] = value
|
properties.properties[tag] = value
|
||||||
}
|
}
|
||||||
|
properties.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -83,8 +92,11 @@ func (properties *propertyList) setRaw(tag PropertyName, value any) {
|
||||||
properties.remove(properties, properties.normalize(tag))
|
properties.remove(properties, properties.normalize(tag))
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func (properties *propertyList) Clear() {
|
func (properties *propertyList) Clear() {
|
||||||
|
properties.mutex.Lock()
|
||||||
properties.properties = map[PropertyName]any{}
|
properties.properties = map[PropertyName]any{}
|
||||||
|
properties.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (properties *propertyList) All() iter.Seq2[PropertyName, any] {
|
func (properties *propertyList) All() iter.Seq2[PropertyName, any] {
|
||||||
|
|
@ -98,10 +110,13 @@ func (properties *propertyList) All() iter.Seq2[PropertyName, any] {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (properties *propertyList) AllTags() []PropertyName {
|
func (properties *propertyList) AllTags() []PropertyName {
|
||||||
|
properties.mutex.Lock()
|
||||||
tags := make([]PropertyName, 0, len(properties.properties))
|
tags := make([]PropertyName, 0, len(properties.properties))
|
||||||
for tag := range properties.properties {
|
for tag := range properties.properties {
|
||||||
tags = append(tags, tag)
|
tags = append(tags, tag)
|
||||||
}
|
}
|
||||||
|
properties.mutex.Unlock()
|
||||||
|
|
||||||
slices.Sort(tags)
|
slices.Sort(tags)
|
||||||
return tags
|
return tags
|
||||||
}
|
}
|
||||||
|
|
|
||||||
57
session.go
57
session.go
|
|
@ -169,7 +169,7 @@ type Session interface {
|
||||||
styleProperty(styleTag string, propertyTag PropertyName) any
|
styleProperty(styleTag string, propertyTag PropertyName) any
|
||||||
|
|
||||||
setBridge(events chan DataObject, bridge bridge)
|
setBridge(events chan DataObject, bridge bridge)
|
||||||
writeInitScript(writer *strings.Builder)
|
writeInitScript()
|
||||||
callFunc(funcName string, args ...any)
|
callFunc(funcName string, args ...any)
|
||||||
updateInnerHTML(htmlID, html string)
|
updateInnerHTML(htmlID, html string)
|
||||||
appendToInnerHTML(htmlID, html string)
|
appendToInnerHTML(htmlID, html string)
|
||||||
|
|
@ -294,6 +294,9 @@ func (session *sessionData) ID() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *sessionData) setBridge(events chan DataObject, bridge bridge) {
|
func (session *sessionData) setBridge(events chan DataObject, bridge bridge) {
|
||||||
|
if session.events != nil {
|
||||||
|
close(session.events)
|
||||||
|
}
|
||||||
session.events = events
|
session.events = events
|
||||||
session.bridge = bridge
|
session.bridge = bridge
|
||||||
}
|
}
|
||||||
|
|
@ -351,23 +354,39 @@ func (session *sessionData) RootView() View {
|
||||||
return session.rootView
|
return session.rootView
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *sessionData) writeInitScript(writer *strings.Builder) {
|
func (session *sessionData) writeInitScript() {
|
||||||
|
|
||||||
|
if session.bridge == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ProtocolInDebugLog {
|
||||||
|
DebugLog("Start session:")
|
||||||
|
}
|
||||||
|
|
||||||
if css := session.getCurrentTheme().cssText(session); css != "" {
|
if css := session.getCurrentTheme().cssText(session); css != "" {
|
||||||
css = strings.ReplaceAll(css, "\n", `\n`)
|
css = strings.ReplaceAll(css, "\n", `\n`)
|
||||||
css = strings.ReplaceAll(css, "\t", `\t`)
|
css = strings.ReplaceAll(css, "\t", `\t`)
|
||||||
writer.WriteString(`document.querySelector('style').textContent += "`)
|
|
||||||
writer.WriteString(css)
|
script := `document.querySelector('style').textContent += "` + css + "\";\n"
|
||||||
writer.WriteString("\";\n")
|
session.bridge.writeScript(script)
|
||||||
|
|
||||||
|
if ProtocolInDebugLog {
|
||||||
|
DebugLog(script)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if session.rootView != nil {
|
if session.rootView != nil {
|
||||||
writer.WriteString(`document.getElementById('ruiRootView').innerHTML = '`)
|
|
||||||
buffer := allocStringBuilder()
|
buffer := allocStringBuilder()
|
||||||
defer freeStringBuilder(buffer)
|
defer freeStringBuilder(buffer)
|
||||||
viewHTML(session.rootView, buffer, "")
|
viewHTML(session.rootView, buffer, "")
|
||||||
text := strings.ReplaceAll(buffer.String(), "'", `\'`)
|
|
||||||
writer.WriteString(text)
|
html := buffer.String()
|
||||||
writer.WriteString("';\nscanElementsSize();")
|
session.bridge.callFunc("updateInnerHTML", "ruiRootView", html)
|
||||||
|
|
||||||
|
if ProtocolInDebugLog {
|
||||||
|
DebugLog(html)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session.updateTooltipConstants()
|
session.updateTooltipConstants()
|
||||||
|
|
@ -666,7 +685,7 @@ func (session *sessionData) handleAnswer(command string, data DataObject) bool {
|
||||||
switch command {
|
switch command {
|
||||||
case "answer":
|
case "answer":
|
||||||
if session.bridge != nil {
|
if session.bridge != nil {
|
||||||
session.bridge.answerReceived(data)
|
go session.bridge.answerReceived(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
case "imageLoaded":
|
case "imageLoaded":
|
||||||
|
|
@ -675,6 +694,11 @@ func (session *sessionData) handleAnswer(command string, data DataObject) bool {
|
||||||
case "imageError":
|
case "imageError":
|
||||||
session.imageManager().imageLoadError(data)
|
session.imageManager().imageLoadError(data)
|
||||||
|
|
||||||
|
case "storageError", "storageValues":
|
||||||
|
if session.clientStorage != nil {
|
||||||
|
session.clientStorage.handleEvent(command, data)
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -793,6 +817,12 @@ func (session *sessionData) handleSessionInfo(params DataObject) {
|
||||||
|
|
||||||
func (session *sessionData) handleEvent(command string, data DataObject) {
|
func (session *sessionData) handleEvent(command string, data DataObject) {
|
||||||
switch command {
|
switch command {
|
||||||
|
case "start-session":
|
||||||
|
if session.setContent(session.App().getCreateContentFunc()(session)) {
|
||||||
|
session.writeInitScript()
|
||||||
|
session.onStart()
|
||||||
|
}
|
||||||
|
|
||||||
case "session-pause":
|
case "session-pause":
|
||||||
session.onPause()
|
session.onPause()
|
||||||
|
|
||||||
|
|
@ -824,11 +854,6 @@ func (session *sessionData) handleEvent(command string, data DataObject) {
|
||||||
case "sessionInfo":
|
case "sessionInfo":
|
||||||
session.handleSessionInfo(data)
|
session.handleSessionInfo(data)
|
||||||
|
|
||||||
case "storageError", "storageSuccess", "storageValues":
|
|
||||||
if session.clientStorage != nil {
|
|
||||||
session.clientStorage.handleEvent(command, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if viewID, ok := data.PropertyValue("id"); ok {
|
if viewID, ok := data.PropertyValue("id"); ok {
|
||||||
if viewID != "body" {
|
if viewID != "body" {
|
||||||
|
|
@ -931,8 +956,10 @@ func (session *sessionData) OpenURL(urlStr string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *sessionData) addToEventsQueue(data DataObject) {
|
func (session *sessionData) addToEventsQueue(data DataObject) {
|
||||||
|
if session.events != nil {
|
||||||
session.events <- data
|
session.events <- data
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (session *sessionData) StartTimer(ms int, timerFunc func(Session)) int {
|
func (session *sessionData) StartTimer(ms int, timerFunc func(Session)) int {
|
||||||
timerID := 0
|
timerID := 0
|
||||||
|
|
|
||||||
35
webBridge.go
35
webBridge.go
|
|
@ -84,7 +84,7 @@ func createSocketBridge(w http.ResponseWriter, req *http.Request) *wsBridge {
|
||||||
func createHttpBridge(req *http.Request) *httpBridge {
|
func createHttpBridge(req *http.Request) *httpBridge {
|
||||||
bridge := new(httpBridge)
|
bridge := new(httpBridge)
|
||||||
bridge.initBridge()
|
bridge.initBridge()
|
||||||
bridge.response = make(chan string, 10)
|
bridge.response = make(chan string, 100)
|
||||||
bridge.writeMessage = func(script string) bool {
|
bridge.writeMessage = func(script string) bool {
|
||||||
if script != "" {
|
if script != "" {
|
||||||
if ProtocolInDebugLog {
|
if ProtocolInDebugLog {
|
||||||
|
|
@ -139,14 +139,31 @@ func (bridge *webBridge) finishUpdateScript(htmlID string) {
|
||||||
func (bridge *webBridge) argToString(arg any) (string, bool) {
|
func (bridge *webBridge) argToString(arg any) (string, bool) {
|
||||||
switch arg := arg.(type) {
|
switch arg := arg.(type) {
|
||||||
case string:
|
case string:
|
||||||
arg = strings.ReplaceAll(arg, "\\", `\\`)
|
escChars := []struct{ esc, repl string }{
|
||||||
arg = strings.ReplaceAll(arg, "'", `\'`)
|
{esc: "\\", repl: `\\`},
|
||||||
arg = strings.ReplaceAll(arg, "\n", `\n`)
|
{esc: "'", repl: `\'`},
|
||||||
arg = strings.ReplaceAll(arg, "\r", `\r`)
|
{esc: "\b", repl: `\b`},
|
||||||
arg = strings.ReplaceAll(arg, "\t", `\t`)
|
{esc: "\t", repl: `\t`},
|
||||||
arg = strings.ReplaceAll(arg, "\b", `\b`)
|
{esc: "\n", repl: `\n`},
|
||||||
arg = strings.ReplaceAll(arg, "\f", `\f`)
|
{esc: "\v", repl: `\v`},
|
||||||
arg = strings.ReplaceAll(arg, "\v", `\v`)
|
{esc: "\r", repl: `\r`},
|
||||||
|
{esc: "\f", repl: `\f`},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range escChars {
|
||||||
|
if strings.Contains(arg, s.esc) {
|
||||||
|
arg = strings.ReplaceAll(arg, s.esc, s.repl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for n := range 0x20 {
|
||||||
|
esc := string([]rune{rune(n)})
|
||||||
|
if strings.Contains(arg, esc) {
|
||||||
|
repl := fmt.Sprintf(`\x%02d`, n)
|
||||||
|
arg = strings.ReplaceAll(arg, esc, repl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return `'` + arg + `'`, true
|
return `'` + arg + `'`, true
|
||||||
|
|
||||||
case rune:
|
case rune:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue