forked from mbk-lab/rui_orig
2
0
Fork 0

Bug fixing

This commit is contained in:
anoshenko 2022-11-08 16:31:21 +03:00
parent 9f084cc3f2
commit ecbcda7a53
11 changed files with 87 additions and 99 deletions

View File

@ -4581,7 +4581,7 @@ onNo или onCancel (если она не nil).
### Интерфейс Animation ### Интерфейс Animation
Для задания параметров анимации мспользуется интерфейс Animation. Он расширяет интерфейс Properties. Для задания параметров анимации используется интерфейс Animation. Он расширяет интерфейс Properties.
Интерфейс создается с помощью функции: Интерфейс создается с помощью функции:
func NewAnimation(params Params) Animation func NewAnimation(params Params) Animation
@ -4751,7 +4751,7 @@ KeyFrames - промежуточные значения свойства (клю
Обязательными являются поля Tag, From, To. Поле KeyFrames опционально, может быть nil. Обязательными являются поля Tag, From, To. Поле KeyFrames опционально, может быть nil.
Поле KeyFrames описывает ключавые кадры. В качестве ключа типа int используется процент времени Поле KeyFrames описывает ключевые кадры. В качестве ключа типа int используется процент времени
прошедший с начала анимации (именно начала самой анимации, время заданное свойством "delay" исключается). прошедший с начала анимации (именно начала самой анимации, время заданное свойством "delay" исключается).
А значание это значение свойства в данный момент времени. Например А значание это значение свойства в данный момент времени. Например
@ -4767,9 +4767,9 @@ KeyFrames - промежуточные значения свойства (клю
В данном примере свойство "width" 90% времени будет увеличиваться со 100px до 220px. В оставшиеся В данном примере свойство "width" 90% времени будет увеличиваться со 100px до 220px. В оставшиеся
10% времени - будет уменьшаться с 220px до 200px. 10% времени - будет уменьшаться с 220px до 200px.
Свойству "property" присваивается []AnimatedProperty, а значит можно анимаровать сразу несколько свойств. Свойству "property" присваивается []AnimatedProperty, а значит можно анимировать сразу несколько свойств.
Вы должны задать хотя бы один эдемент "property", иначе анимация будет игнорироваться. Вы должны задать хотя бы один элемент "property", иначе анимация будет игнорироваться.
#### Свойство "id" #### Свойство "id"

View File

@ -609,8 +609,7 @@ func (session *sessionData) registerAnimation(props []AnimatedProperty) string {
style := cssBuilder.finish() style := cssBuilder.finish()
session.animationCSS += style session.animationCSS += style
style = strings.ReplaceAll(style, "\n", `\n`) session.addAnimationCSS(style)
session.runScript(`document.querySelector('style').textContent += "` + style + `"`)
return name return name
} }

View File

@ -26,7 +26,7 @@ func (app *wasmApp) Finish() {
} }
func wasmLog(text string) { func wasmLog(text string) {
js.Global().Call("log", text) js.Global().Get("console").Call("log", text)
} }
func (app *wasmApp) handleMessage(this js.Value, args []js.Value) any { func (app *wasmApp) handleMessage(this js.Value, args []js.Value) any {
@ -37,60 +37,9 @@ func (app *wasmApp) handleMessage(this js.Value, args []js.Value) any {
} }
if obj := ParseDataText(text); obj != nil { if obj := ParseDataText(text); obj != nil {
switch command := obj.Tag(); command { switch command := obj.Tag(); command {
/* case "session-close":
case "startSession": app.close <- obj
answer := ""
if session, answer = app.startSession(obj, events, bridge); session != nil {
if !bridge.writeMessage(answer) {
return
}
session.onStart()
go sessionEventHandler(session, events, bridge)
}
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.setBridge(events, bridge)
answer := allocStringBuilder()
defer freeStringBuilder(answer)
session.writeInitScript(answer)
if !bridge.writeMessage(answer.String()) {
return
}
session.onReconnect()
go sessionEventHandler(session, events, bridge)
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, bridge); session != nil {
if !bridge.writeMessage(answer) {
return
}
session.onStart()
go sessionEventHandler(session, events, bridge)
}
case "disconnect":
session.onDisconnect()
return
case "session-close":
session.onFinish()
session.App().removeSession(session.ID())
bridge.close()
*/
case "answer": case "answer":
app.session.handleAnswer(obj) app.session.handleAnswer(obj)
@ -176,6 +125,10 @@ func (app *wasmApp) init(params AppParams) {
style.Set("textContent", css) style.Set("textContent", css)
document.Call("querySelector", "head").Call("appendChild", style) document.Call("querySelector", "head").Call("appendChild", style)
style = document.Call("createElement", "style")
style.Set("id", "ruiAnimations")
document.Call("querySelector", "head").Call("appendChild", style)
buffer := allocStringBuilder() buffer := allocStringBuilder()
defer freeStringBuilder(buffer) defer freeStringBuilder(buffer)
@ -216,14 +169,14 @@ func StartApp(addr string, createContentFunc func(Session) SessionContent, param
app := new(wasmApp) app := new(wasmApp)
app.createContentFunc = createContentFunc app.createContentFunc = createContentFunc
app.bridge = createWasmBridge() app.close = make(chan DataObject)
app.bridge = createWasmBridge(app.close)
app.init(params) app.init(params)
<-app.close <-app.close
} }
func FinishApp() { func FinishApp() {
//app.Finish()
} }
func OpenBrowser(url string) bool { func OpenBrowser(url string) bool {

View File

@ -5,6 +5,8 @@ import (
"strings" "strings"
) )
var wasmMediaResources = false
//go:embed app_scripts.js //go:embed app_scripts.js
var defaultScripts string var defaultScripts string
@ -66,6 +68,7 @@ func getStartPage(buffer *strings.Builder, params AppParams, addScripts string)
<style>`) <style>`)
buffer.WriteString(appStyles) buffer.WriteString(appStyles)
buffer.WriteString(`</style> buffer.WriteString(`</style>
<style id="ruiAnimations"></style>
<script> <script>
`) `)
buffer.WriteString(defaultScripts) buffer.WriteString(defaultScripts)

View File

@ -83,8 +83,9 @@ func (manager *imageManager) loadImage(url string, onLoaded func(Image), session
image.loadingStatus = ImageLoading image.loadingStatus = ImageLoading
manager.images[url] = image manager.images[url] = image
if runtime.GOOS == "js" { if runtime.GOOS == "js" && wasmMediaResources {
if file, ok := resources.images[url]; ok && file.fs != nil { if file, ok := resources.images[url]; ok && file.fs != nil {
dataType := map[string]string{ dataType := map[string]string{
".svg": "data:image/svg+xml", ".svg": "data:image/svg+xml",
".png": "data:image/png", ".png": "data:image/png",

View File

@ -226,7 +226,7 @@ func (imageView *imageViewData) src(src string) (string, string) {
if src != "" { if src != "" {
srcset := imageView.srcSet(src) srcset := imageView.srcSet(src)
if runtime.GOOS == "js" { if runtime.GOOS == "js" && wasmMediaResources {
if image, ok := resources.images[src]; ok && image.fs != nil { if image, ok := resources.images[src]; ok && image.fs != nil {
dataType := map[string]string{ dataType := map[string]string{
".svg": "data:image/svg+xml", ".svg": "data:image/svg+xml",

View File

@ -79,7 +79,7 @@ func NewPath() Path {
func (path *pathData) Reset() { func (path *pathData) Reset() {
path.elements = []pathElement{ path.elements = []pathElement{
pathElement{funcName: "beginPath", args: []any{}}, {funcName: "beginPath", args: []any{}},
} }
} }

View File

@ -18,6 +18,8 @@ type webBridge interface {
removeProperty(htmlID, property string) removeProperty(htmlID, property string)
readMessage() (string, bool) readMessage() (string, bool)
writeMessage(text string) bool writeMessage(text string) bool
addAnimationCSS(css string)
clearAnimation()
cavnasStart(htmlID string) cavnasStart(htmlID string)
callCanvasFunc(funcName string, args ...any) callCanvasFunc(funcName string, args ...any)
callCanvasVarFunc(v any, funcName string, args ...any) callCanvasVarFunc(v any, funcName string, args ...any)
@ -119,9 +121,10 @@ type Session interface {
updateCSSProperty(htmlID, property, value string) updateCSSProperty(htmlID, property, value string)
updateProperty(htmlID, property string, value any) updateProperty(htmlID, property string, value any)
removeProperty(htmlID, property string) removeProperty(htmlID, property string)
runScript(script string)
startUpdateScript(htmlID string) bool startUpdateScript(htmlID string) bool
finishUpdateScript(htmlID string) finishUpdateScript(htmlID string)
addAnimationCSS(css string)
clearAnimation()
cavnasStart(htmlID string) cavnasStart(htmlID string)
callCanvasFunc(funcName string, args ...any) callCanvasFunc(funcName string, args ...any)
createCanvasVar(funcName string, args ...any) any createCanvasVar(funcName string, args ...any) any
@ -309,7 +312,7 @@ func (session *sessionData) reload() {
buffer.WriteString("';\nscanElementsSize();") buffer.WriteString("';\nscanElementsSize();")
} }
session.runScript(buffer.String()) session.bridge.writeMessage(buffer.String())
} }
func (session *sessionData) ignoreViewUpdates() bool { func (session *sessionData) ignoreViewUpdates() bool {
@ -409,6 +412,18 @@ func (session *sessionData) finishUpdateScript(htmlID string) {
} }
} }
func (session *sessionData) addAnimationCSS(css string) {
if session.bridge != nil {
session.bridge.addAnimationCSS(css)
}
}
func (session *sessionData) clearAnimation() {
if session.bridge != nil {
session.bridge.clearAnimation()
}
}
func (session *sessionData) cavnasStart(htmlID string) { func (session *sessionData) cavnasStart(htmlID string) {
if session.bridge != nil { if session.bridge != nil {
session.bridge.cavnasStart(htmlID) session.bridge.cavnasStart(htmlID)
@ -452,14 +467,6 @@ func (session *sessionData) cavnasFinish() {
} }
} }
func (session *sessionData) runScript(script string) {
if session.bridge != nil {
session.bridge.writeMessage(script)
} else {
ErrorLog("No connection")
}
}
func (session *sessionData) canvasTextMetrics(htmlID, font, text string) TextMetrics { func (session *sessionData) canvasTextMetrics(htmlID, font, text string) TextMetrics {
if session.bridge != nil { if session.bridge != nil {
return session.bridge.canvasTextMetrics(htmlID, font, text) return session.bridge.canvasTextMetrics(htmlID, font, text)

View File

@ -329,11 +329,7 @@ func (session *sessionData) SetLanguage(lang string) {
buffer := allocStringBuilder() buffer := allocStringBuilder()
defer freeStringBuilder(buffer) defer freeStringBuilder(buffer)
//buffer.WriteString(`document.getElementById('ruiRootView').innerHTML = '`)
viewHTML(session.rootView, buffer) viewHTML(session.rootView, buffer)
//buffer.WriteString("';\nscanElementsSize();")
//session.runScript(buffer.String())
session.bridge.updateInnerHTML("ruiRootView", buffer.String()) session.bridge.updateInnerHTML("ruiRootView", buffer.String())
} }
} }

View File

@ -5,25 +5,22 @@ package rui
import ( import (
"fmt" "fmt"
"strconv" "strconv"
"sync" "strings"
"syscall/js" "syscall/js"
) )
type wasmBridge struct { type wasmBridge struct {
queue chan string answer map[int]chan DataObject
answer map[int]chan DataObject answerID int
answerID int canvas js.Value
answerMutex sync.Mutex closeEvent chan DataObject
closed bool
canvas js.Value
} }
func createWasmBridge() webBridge { func createWasmBridge(close chan DataObject) webBridge {
bridge := new(wasmBridge) bridge := new(wasmBridge)
bridge.queue = make(chan string, 1000)
bridge.answerID = 1 bridge.answerID = 1
bridge.answer = make(map[int]chan DataObject) bridge.answer = make(map[int]chan DataObject)
bridge.closed = false bridge.closeEvent = close
return bridge return bridge
} }
@ -57,7 +54,15 @@ func (bridge *wasmBridge) callFunc(funcName string, args ...any) bool {
} }
func (bridge *wasmBridge) updateInnerHTML(htmlID, html string) { func (bridge *wasmBridge) updateInnerHTML(htmlID, html string) {
bridge.updateProperty(htmlID, "innerHTML", html) if ProtocolInDebugLog {
DebugLog(fmt.Sprintf("%s.innerHTML = '%s'", htmlID, html))
}
element := js.Global().Get("document").Call("getElementById", htmlID)
if !element.IsUndefined() && !element.IsNull() {
element.Set("innerHTML", html)
js.Global().Call("scanElementsSize")
}
} }
func (bridge *wasmBridge) appendToInnerHTML(htmlID, html string) { func (bridge *wasmBridge) appendToInnerHTML(htmlID, html string) {
@ -86,15 +91,7 @@ func (bridge *wasmBridge) updateCSSProperty(htmlID, property, value string) {
} }
func (bridge *wasmBridge) updateProperty(htmlID, property string, value any) { func (bridge *wasmBridge) updateProperty(htmlID, property string, value any) {
if ProtocolInDebugLog { bridge.callFunc("updateProperty", htmlID, property, value)
DebugLog(fmt.Sprintf("%s.%s = '%v'", htmlID, property, value))
}
element := js.Global().Get("document").Call("getElementById", htmlID)
if !element.IsUndefined() && !element.IsNull() {
element.Set(property, value)
js.Global().Call("scanElementsSize")
}
} }
func (bridge *wasmBridge) removeProperty(htmlID, property string) { func (bridge *wasmBridge) removeProperty(htmlID, property string) {
@ -102,6 +99,7 @@ func (bridge *wasmBridge) removeProperty(htmlID, property string) {
} }
func (bridge *wasmBridge) close() { func (bridge *wasmBridge) close() {
bridge.closeEvent <- NewDataObject("close")
} }
func (bridge *wasmBridge) readMessage() (string, bool) { func (bridge *wasmBridge) readMessage() (string, bool) {
@ -120,6 +118,23 @@ func (bridge *wasmBridge) writeMessage(script string) bool {
return true return true
} }
func (bridge *wasmBridge) addAnimationCSS(css string) {
css = strings.ReplaceAll(css, `\t`, "\t")
css = strings.ReplaceAll(css, `\n`, "\n")
css = strings.ReplaceAll(css, `\'`, "'")
css = strings.ReplaceAll(css, `\"`, "\"")
css = strings.ReplaceAll(css, `\\`, "\\")
styles := js.Global().Get("document").Call("getElementById", "ruiAnimations")
content := styles.Get("textContent").String()
styles.Set("textContent", content+"\n"+css)
}
func (bridge *wasmBridge) clearAnimation() {
styles := js.Global().Get("document").Call("getElementById", "ruiAnimations")
styles.Set("textContent", "")
}
func (bridge *wasmBridge) cavnasStart(htmlID string) { func (bridge *wasmBridge) cavnasStart(htmlID string) {
if ProtocolInDebugLog { if ProtocolInDebugLog {
DebugLog("const ctx = document.getElementById('" + htmlID + "'elementId').getContext('2d');\nctx.save();") DebugLog("const ctx = document.getElementById('" + htmlID + "'elementId').getContext('2d');\nctx.save();")

View File

@ -224,6 +224,20 @@ func (bridge *wsBridge) removeProperty(htmlID, property string) {
} }
} }
func (bridge *wsBridge) addAnimationCSS(css string) {
bridge.writeMessage(`var styles = document.getElementById('ruiAnimations');
if (styles) {
styles.textContent += '` + css + `';
}`)
}
func (bridge *wsBridge) clearAnimation() {
bridge.writeMessage(`var styles = document.getElementById('ruiAnimations');
if (styles) {
styles.textContent = '';
}`)
}
func (bridge *wsBridge) cavnasStart(htmlID string) { func (bridge *wsBridge) cavnasStart(htmlID string) {
bridge.canvasBuffer.Reset() bridge.canvasBuffer.Reset()
bridge.canvasBuffer.WriteString(`const ctx = getCanvasContext('`) bridge.canvasBuffer.WriteString(`const ctx = getCanvasContext('`)