forked from mbk-lab/rui_orig
Optimisation
This commit is contained in:
parent
4523a9a427
commit
d096a35af9
42
appWasm.go
42
appWasm.go
|
@ -4,7 +4,6 @@ package rui
|
|||
|
||||
import (
|
||||
_ "embed"
|
||||
"strings"
|
||||
"syscall/js"
|
||||
)
|
||||
|
||||
|
@ -22,40 +21,6 @@ func (app *wasmApp) Finish() {
|
|||
app.session.close()
|
||||
}
|
||||
|
||||
/*
|
||||
func (app *wasmApp) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
|
||||
if ProtocolInDebugLog {
|
||||
DebugLogF("%s %s", req.Method, req.URL.Path)
|
||||
}
|
||||
|
||||
switch req.Method {
|
||||
case "GET":
|
||||
switch req.URL.Path {
|
||||
case "/":
|
||||
w.WriteHeader(http.StatusOK)
|
||||
io.WriteString(w, app.getStartPage())
|
||||
|
||||
case "/ws":
|
||||
if brige := CreateSocketBrige(w, req); brige != nil {
|
||||
go app.socketReader(brige)
|
||||
}
|
||||
|
||||
default:
|
||||
filename := req.URL.Path[1:]
|
||||
if size := len(filename); size > 0 && filename[size-1] == '/' {
|
||||
filename = filename[:size-1]
|
||||
}
|
||||
|
||||
if !serveResourceFile(filename, w, req) &&
|
||||
!serveDownloadFile(filename, w, req) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func (app *wasmApp) startSession(this js.Value, args []js.Value) interface{} {
|
||||
if app.createContentFunc == nil || len(args) == 1 {
|
||||
return nil
|
||||
|
@ -99,6 +64,7 @@ func StartApp(addr string, createContentFunc func(Session) SessionContent, param
|
|||
app.brige = createWasmBrige()
|
||||
js.Global().Set("startSession", js.FuncOf(app.startSession))
|
||||
|
||||
/*
|
||||
script := defaultScripts + wasmScripts
|
||||
script = strings.ReplaceAll(script, "\\", `\\`)
|
||||
script = strings.ReplaceAll(script, "\n", `\n`)
|
||||
|
@ -106,9 +72,8 @@ func StartApp(addr string, createContentFunc func(Session) SessionContent, param
|
|||
script = strings.ReplaceAll(script, "\"", `\"`)
|
||||
script = strings.ReplaceAll(script, "'", `\'`)
|
||||
|
||||
//window := js.Global().Get("window")
|
||||
//window.Call("execScript", `document.getElementById('ruiscript').text = "`+script+`"`)
|
||||
js.Global().Call("execScript", `document.getElementById('ruiscript').text += "`+script+`"`)
|
||||
*/
|
||||
|
||||
document := js.Global().Get("document")
|
||||
body := document.Call("querySelector", "body")
|
||||
|
@ -116,7 +81,8 @@ func StartApp(addr string, createContentFunc func(Session) SessionContent, param
|
|||
<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("execScript", "initSession()")
|
||||
js.Global().Call("initSession", "")
|
||||
//window.Call("execScript", "initSession()")
|
||||
|
||||
for true {
|
||||
|
|
|
@ -1161,6 +1161,12 @@ function blur(elementId) {
|
|||
}
|
||||
}
|
||||
|
||||
function blurCurrent() {
|
||||
if (document.activeElement != document.body) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
}
|
||||
|
||||
function playerEvent(element, tag) {
|
||||
//event.stopPropagation();
|
||||
sendMessage(tag + "{session=" + sessionID + ",id=" + element.id + "}");
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package rui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -190,7 +189,7 @@ func (button *checkboxData) changedCheckboxState(state bool) {
|
|||
defer freeStringBuilder(buffer)
|
||||
|
||||
button.htmlCheckbox(buffer, state)
|
||||
button.Session().runScript(fmt.Sprintf(`updateInnerHTML('%v', '%v');`, button.htmlID()+"checkbox", buffer.String()))
|
||||
button.Session().runFunc("updateInnerHTML", button.htmlID()+"checkbox", buffer.String())
|
||||
}
|
||||
|
||||
func checkboxClickListener(view View) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package rui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -114,7 +113,7 @@ func (picker *colorPickerData) set(tag string, value any) bool {
|
|||
func (picker *colorPickerData) colorChanged(oldColor Color) {
|
||||
if newColor := GetColorPickerValue(picker); oldColor != newColor {
|
||||
if picker.created {
|
||||
picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), newColor.rgbString()))
|
||||
picker.session.runFunc("setInputValue", picker.htmlID(), newColor.rgbString())
|
||||
}
|
||||
for _, listener := range picker.colorChangedListeners {
|
||||
listener(picker, newColor)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package rui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -98,7 +97,7 @@ func (picker *datePickerData) remove(tag string) {
|
|||
delete(picker.properties, DatePickerValue)
|
||||
date := GetDatePickerValue(picker)
|
||||
if picker.created {
|
||||
picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), date.Format(dateFormat)))
|
||||
picker.session.runFunc("setInputValue", picker.htmlID(), date.Format(dateFormat))
|
||||
}
|
||||
for _, listener := range picker.dateChangedListeners {
|
||||
listener(picker, date)
|
||||
|
@ -224,7 +223,7 @@ func (picker *datePickerData) set(tag string, value any) bool {
|
|||
if date, ok := setTimeValue(DatePickerValue); ok {
|
||||
if date != oldDate {
|
||||
if picker.created {
|
||||
picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), date.Format(dateFormat)))
|
||||
picker.session.runFunc("setInputValue", picker.htmlID(), date.Format(dateFormat))
|
||||
}
|
||||
for _, listener := range picker.dateChangedListeners {
|
||||
listener(picker, date)
|
||||
|
|
|
@ -87,7 +87,7 @@ func (list *dropDownListData) remove(tag string) {
|
|||
delete(list.properties, Current)
|
||||
if oldCurrent != 0 {
|
||||
if list.created {
|
||||
list.session.runScript(fmt.Sprintf(`selectDropDownListItem('%s', %d)`, list.htmlID(), 0))
|
||||
list.session.runFunc("selectDropDownListItem", list.htmlID(), 0)
|
||||
}
|
||||
list.onSelectedItemChanged(0)
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ func (list *dropDownListData) set(tag string, value any) bool {
|
|||
|
||||
if current := GetCurrent(list); oldCurrent != current {
|
||||
if list.created {
|
||||
list.session.runScript(fmt.Sprintf(`selectDropDownListItem('%s', %d)`, list.htmlID(), current))
|
||||
list.session.runFunc("selectDropDownListItem", list.htmlID(), current)
|
||||
}
|
||||
list.onSelectedItemChanged(current)
|
||||
}
|
||||
|
|
18
editView.go
18
editView.go
|
@ -1,7 +1,6 @@
|
|||
package rui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
@ -137,7 +136,7 @@ func (edit *editViewData) remove(tag string) {
|
|||
if oldText != "" {
|
||||
edit.textChanged("")
|
||||
if edit.created {
|
||||
edit.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, edit.htmlID(), ""))
|
||||
edit.session.runFunc("setInputValue", edit.htmlID(), "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,11 +210,7 @@ func (edit *editViewData) set(tag string, value any) bool {
|
|||
if GetEditViewType(edit) == MultiLineText {
|
||||
updateInnerHTML(edit.htmlID(), edit.Session())
|
||||
} else {
|
||||
text = strings.ReplaceAll(text, `"`, `\"`)
|
||||
text = strings.ReplaceAll(text, `'`, `\'`)
|
||||
text = strings.ReplaceAll(text, "\n", `\n`)
|
||||
text = strings.ReplaceAll(text, "\r", `\r`)
|
||||
edit.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, edit.htmlID(), text))
|
||||
edit.session.runFunc("setInputValue", edit.htmlID(), text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -365,14 +360,7 @@ func (edit *editViewData) AppendText(text string) {
|
|||
if textValue, ok := value.(string); ok {
|
||||
textValue += text
|
||||
edit.properties[Text] = textValue
|
||||
|
||||
text := strings.ReplaceAll(text, `"`, `\"`)
|
||||
text = strings.ReplaceAll(text, `'`, `\'`)
|
||||
text = strings.ReplaceAll(text, "\n", `\n`)
|
||||
text = strings.ReplaceAll(text, "\r", `\r`)
|
||||
|
||||
edit.session.runScript(`appendToInnerHTML("` + edit.htmlID() + `", "` + text + `")`)
|
||||
|
||||
edit.session.runFunc("appendToInnerHTML", edit.htmlID(), text)
|
||||
edit.textChanged(textValue)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package rui
|
|||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -109,7 +108,7 @@ func (picker *filePickerData) LoadFile(file FileInfo, result func(FileInfo, []by
|
|||
for i, info := range picker.files {
|
||||
if info.Name == file.Name && info.Size == file.Size && info.LastModified == file.LastModified {
|
||||
picker.loader[i] = result
|
||||
picker.Session().runScript(fmt.Sprintf(`loadSelectedFile("%s", %d)`, picker.htmlID(), i))
|
||||
picker.Session().runFunc("loadSelectedFile", picker.htmlID(), i)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
2
image.go
2
image.go
|
@ -76,7 +76,7 @@ func (manager *imageManager) loadImage(url string, onLoaded func(Image), session
|
|||
image.listener = onLoaded
|
||||
image.loadingStatus = ImageLoading
|
||||
manager.images[url] = image
|
||||
session.runScript("loadImage('" + url + "');")
|
||||
session.runFunc("loadImage", url)
|
||||
return image
|
||||
}
|
||||
|
||||
|
|
11
listView.go
11
listView.go
|
@ -819,12 +819,6 @@ func (listView *listViewData) updateCheckboxItem(index int, checked bool) {
|
|||
buffer := allocStringBuilder()
|
||||
defer freeStringBuilder(buffer)
|
||||
|
||||
buffer.WriteString(`updateInnerHTML('`)
|
||||
buffer.WriteString(listView.htmlID())
|
||||
buffer.WriteRune('-')
|
||||
buffer.WriteString(strconv.Itoa(index))
|
||||
buffer.WriteString(`', '`)
|
||||
|
||||
buffer.WriteString(listView.checkboxItemDiv(listView, checkbox, hCheckboxAlign, vCheckboxAlign))
|
||||
if checked {
|
||||
buffer.WriteString(onDiv)
|
||||
|
@ -842,9 +836,8 @@ func (listView *listViewData) updateCheckboxItem(index int, checked bool) {
|
|||
buffer.WriteString("ERROR: invalid item view")
|
||||
}
|
||||
}
|
||||
buffer.WriteString(`</div></div>');`)
|
||||
|
||||
session.runScript(buffer.String())
|
||||
buffer.WriteString(`</div></div>`)
|
||||
session.runFunc("updateInnerHTML", listView.htmlID()+"-"+strconv.Itoa(index), buffer.String())
|
||||
}
|
||||
|
||||
func (listView *listViewData) htmlProperties(self View, buffer *strings.Builder) {
|
||||
|
|
|
@ -472,11 +472,7 @@ func (player *mediaPlayerData) propertyChanged(tag string) {
|
|||
|
||||
case Muted:
|
||||
value, _ := boolProperty(player, tag, player.Session())
|
||||
if value {
|
||||
player.Session().runScript("setMediaMuted('" + player.htmlID() + "', true)")
|
||||
} else {
|
||||
player.Session().runScript("setMediaMuted('" + player.htmlID() + "', false)")
|
||||
}
|
||||
player.Session().runFunc("setMediaMuted", player.htmlID(), value)
|
||||
|
||||
case Preload:
|
||||
value, _ := enumProperty(player, tag, player.Session(), 0)
|
||||
|
@ -659,15 +655,15 @@ func (player *mediaPlayerData) handleCommand(self View, command string, data Dat
|
|||
}
|
||||
|
||||
func (player *mediaPlayerData) Play() {
|
||||
player.session.runScript(fmt.Sprintf(`mediaPlay('%v');`, player.htmlID()))
|
||||
player.session.runFunc("mediaPlay", player.htmlID())
|
||||
}
|
||||
|
||||
func (player *mediaPlayerData) Pause() {
|
||||
player.session.runScript(fmt.Sprintf(`mediaPause('%v');`, player.htmlID()))
|
||||
player.session.runFunc("mediaPause", player.htmlID())
|
||||
}
|
||||
|
||||
func (player *mediaPlayerData) SetCurrentTime(seconds float64) {
|
||||
player.session.runScript(fmt.Sprintf(`mediaSetSetCurrentTime('%v', %v);`, player.htmlID(), seconds))
|
||||
player.session.runFunc("mediaSetSetCurrentTime", player.htmlID(), seconds)
|
||||
}
|
||||
|
||||
func (player *mediaPlayerData) getFloatPlayerProperty(tag string) (float64, bool) {
|
||||
|
@ -731,7 +727,7 @@ func (player *mediaPlayerData) Duration() float64 {
|
|||
}
|
||||
|
||||
func (player *mediaPlayerData) SetPlaybackRate(rate float64) {
|
||||
player.session.runScript(fmt.Sprintf(`mediaSetPlaybackRate('%v', %v);`, player.htmlID(), rate))
|
||||
player.session.runFunc("mediaSetPlaybackRate", player.htmlID(), rate)
|
||||
}
|
||||
|
||||
func (player *mediaPlayerData) PlaybackRate() float64 {
|
||||
|
@ -743,7 +739,7 @@ func (player *mediaPlayerData) PlaybackRate() float64 {
|
|||
|
||||
func (player *mediaPlayerData) SetVolume(volume float64) {
|
||||
if volume >= 0 && volume <= 1 {
|
||||
player.session.runScript(fmt.Sprintf(`mediaSetVolume('%v', %v);`, player.htmlID(), volume))
|
||||
player.session.runFunc("mediaSetVolume", player.htmlID(), volume)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package rui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -117,7 +116,7 @@ func (picker *numberPickerData) set(tag string, value any) bool {
|
|||
if f, ok := floatProperty(picker, NumberPickerValue, picker.Session(), min); ok && f != oldValue {
|
||||
newValue, _ := floatTextProperty(picker, NumberPickerValue, picker.Session(), min)
|
||||
if picker.created {
|
||||
picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), newValue))
|
||||
picker.session.runFunc("setInputValue", picker.htmlID(), newValue)
|
||||
}
|
||||
for _, listener := range picker.numberChangedListeners {
|
||||
listener(picker, f)
|
||||
|
@ -163,7 +162,7 @@ func (picker *numberPickerData) propertyChanged(tag string) {
|
|||
|
||||
case NumberPickerValue:
|
||||
value := GetNumberPickerValue(picker)
|
||||
picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%f')`, picker.htmlID(), value))
|
||||
picker.session.runFunc("setInputValue", picker.htmlID(), value)
|
||||
for _, listener := range picker.numberChangedListeners {
|
||||
listener(picker, value)
|
||||
}
|
||||
|
|
14
popup.go
14
popup.go
|
@ -610,19 +610,17 @@ func ShowPopup(view View, param Params) Popup {
|
|||
func (manager *popupManager) updatePopupLayerInnerHTML(session Session) {
|
||||
if manager.popups == nil {
|
||||
manager.popups = []Popup{}
|
||||
session.runScript(`updateInnerHTML('ruiPopupLayer', '');`)
|
||||
session.runFunc("updateInnerHTML", "ruiPopupLayer", "")
|
||||
return
|
||||
}
|
||||
|
||||
buffer := allocStringBuilder()
|
||||
defer freeStringBuilder(buffer)
|
||||
|
||||
buffer.WriteString(`updateInnerHTML('ruiPopupLayer', '`)
|
||||
for _, p := range manager.popups {
|
||||
p.html(buffer)
|
||||
for _, popup := range manager.popups {
|
||||
popup.html(buffer)
|
||||
}
|
||||
buffer.WriteString(`');`)
|
||||
session.runScript(buffer.String())
|
||||
session.runFunc("updateInnerHTML", "ruiPopupLayer", buffer.String())
|
||||
}
|
||||
|
||||
func (manager *popupManager) showPopup(popup Popup) {
|
||||
|
@ -637,7 +635,7 @@ func (manager *popupManager) showPopup(popup Popup) {
|
|||
manager.popups = append(manager.popups, popup)
|
||||
}
|
||||
|
||||
session.runScript(`if (document.activeElement != document.body) document.activeElement.blur();`)
|
||||
session.runFunc("blurCurrent")
|
||||
manager.updatePopupLayerInnerHTML(session)
|
||||
updateCSSProperty("ruiPopupLayer", "visibility", "visible", session)
|
||||
updateCSSProperty("ruiRoot", "pointer-events", "none", session)
|
||||
|
@ -660,7 +658,7 @@ func (manager *popupManager) dismissPopup(popup Popup) {
|
|||
manager.popups = []Popup{}
|
||||
updateCSSProperty("ruiRoot", "pointer-events", "auto", session)
|
||||
updateCSSProperty("ruiPopupLayer", "visibility", "hidden", session)
|
||||
session.runScript(`updateInnerHTML('ruiPopupLayer', '');`)
|
||||
session.runFunc("updateInnerHTML", "ruiPopupLayer", "")
|
||||
} else {
|
||||
manager.popups = manager.popups[:count-1]
|
||||
manager.updatePopupLayerInnerHTML(session)
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package rui
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ScrollEvent is the constant for "scroll-event" property tag.
|
||||
// The "scroll-event" is fired when the content of the view is scrolled.
|
||||
// The main listener format:
|
||||
|
@ -59,7 +57,7 @@ func ScrollViewTo(view View, subviewID string, x, y float64) {
|
|||
view = ViewByID(view, subviewID)
|
||||
}
|
||||
if view != nil {
|
||||
view.Session().runScript(fmt.Sprintf(`scrollTo("%s", %g, %g)`, view.htmlID(), x, y))
|
||||
view.Session().runFunc("scrollTo", view.htmlID(), x, y)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,7 +68,7 @@ func ScrollViewToStart(view View, subviewID ...string) {
|
|||
view = ViewByID(view, subviewID[0])
|
||||
}
|
||||
if view != nil {
|
||||
view.Session().runScript(`scrollToStart("` + view.htmlID() + `")`)
|
||||
view.Session().runFunc("scrollToStart", view.htmlID())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,6 +79,6 @@ func ScrollViewToEnd(view View, subviewID ...string) {
|
|||
view = ViewByID(view, subviewID[0])
|
||||
}
|
||||
if view != nil {
|
||||
view.Session().runScript(`scrollToEnd("` + view.htmlID() + `")`)
|
||||
view.Session().runFunc("scrollToEnd", view.htmlID())
|
||||
}
|
||||
}
|
||||
|
|
10
session.go
10
session.go
|
@ -8,6 +8,7 @@ import (
|
|||
)
|
||||
|
||||
type webBrige interface {
|
||||
runFunc(funcName string, args ...any) bool
|
||||
readMessage() (string, bool)
|
||||
writeMessage(text string) bool
|
||||
runGetterScript(script string) DataObject
|
||||
|
@ -96,6 +97,7 @@ type Session interface {
|
|||
|
||||
setBrige(events chan DataObject, brige webBrige)
|
||||
writeInitScript(writer *strings.Builder)
|
||||
runFunc(funcName string, args ...any)
|
||||
runScript(script string)
|
||||
runGetterScript(script string) DataObject //, answer chan DataObject)
|
||||
handleAnswer(data DataObject)
|
||||
|
@ -321,6 +323,14 @@ func (session *sessionData) imageManager() *imageManager {
|
|||
return session.images
|
||||
}
|
||||
|
||||
func (session *sessionData) runFunc(funcName string, args ...any) {
|
||||
if session.brige != nil {
|
||||
session.brige.runFunc(funcName, args...)
|
||||
} else {
|
||||
ErrorLog("No connection")
|
||||
}
|
||||
}
|
||||
|
||||
func (session *sessionData) runScript(script string) {
|
||||
if session.brige != nil {
|
||||
session.brige.writeMessage(script)
|
||||
|
|
|
@ -39,15 +39,13 @@ func sizeConstant(session Session, tag string) (SizeUnit, bool) {
|
|||
func updateCSSStyle(htmlID string, session Session) {
|
||||
if !session.ignoreViewUpdates() {
|
||||
if view := session.viewByHTMLID(htmlID); view != nil {
|
||||
var builder viewCSSBuilder
|
||||
|
||||
builder.buffer = allocStringBuilder()
|
||||
builder.buffer.WriteString(`updateCSSStyle('`)
|
||||
builder.buffer.WriteString(view.htmlID())
|
||||
builder.buffer.WriteString(`', '`)
|
||||
builder := viewCSSBuilder{buffer: allocStringBuilder()}
|
||||
//builder.buffer.WriteString(`updateCSSStyle('`)
|
||||
//builder.buffer.WriteString(view.htmlID())
|
||||
//builder.buffer.WriteString(`', '`)
|
||||
view.cssStyle(view, &builder)
|
||||
builder.buffer.WriteString(`');`)
|
||||
view.Session().runScript(builder.finish())
|
||||
//builder.buffer.WriteString(`');`)
|
||||
session.runFunc("updateCSSStyle", view.htmlID(), builder.finish())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,8 +64,7 @@ func updateInnerHTML(htmlID string, session Session) {
|
|||
|
||||
script.Grow(32 * 1024)
|
||||
view.htmlSubviews(view, script)
|
||||
view.Session().runScript(fmt.Sprintf(`updateInnerHTML('%v', '%v');`, view.htmlID(), script.String()))
|
||||
//view.updateEventHandlers()
|
||||
session.runFunc("updateInnerHTML", view.htmlID(), script.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,8 +72,7 @@ func updateInnerHTML(htmlID string, session Session) {
|
|||
func appendToInnerHTML(htmlID, content string, session Session) {
|
||||
if !session.ignoreViewUpdates() {
|
||||
if view := session.viewByHTMLID(htmlID); view != nil {
|
||||
view.Session().runScript(fmt.Sprintf(`appendToInnerHTML('%v', '%v');`, view.htmlID(), content))
|
||||
//view.updateEventHandlers()
|
||||
session.runFunc("appendToInnerHTML", view.htmlID(), content)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +83,7 @@ func updateProperty(htmlID, property, value string, session Session) {
|
|||
buffer.WriteString(fmt.Sprintf(`element.setAttribute('%v', '%v');`, property, value))
|
||||
buffer.WriteRune('\n')
|
||||
} else {
|
||||
session.runScript(fmt.Sprintf(`updateProperty('%v', '%v', '%v');`, htmlID, property, value))
|
||||
session.runFunc("updateProperty", htmlID, property, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +94,7 @@ func updateCSSProperty(htmlID, property, value string, session Session) {
|
|||
buffer.WriteString(fmt.Sprintf(`element.style['%v'] = '%v';`, property, value))
|
||||
buffer.WriteRune('\n')
|
||||
} else {
|
||||
session.runScript(fmt.Sprintf(`updateCSSProperty('%v', '%v', '%v');`, htmlID, property, value))
|
||||
session.runFunc("updateCSSProperty", htmlID, property, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,10 +108,8 @@ func updateBoolProperty(htmlID, property string, value bool, session Session) {
|
|||
buffer.WriteString(fmt.Sprintf(`element.setAttribute('%v', false);`, property))
|
||||
}
|
||||
buffer.WriteRune('\n')
|
||||
} else if value {
|
||||
session.runScript(fmt.Sprintf(`updateProperty('%v', '%v', true);`, htmlID, property))
|
||||
} else {
|
||||
session.runScript(fmt.Sprintf(`updateProperty('%v', '%v', false);`, htmlID, property))
|
||||
session.runFunc("updateProperty", htmlID, property, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +120,7 @@ func removeProperty(htmlID, property string, session Session) {
|
|||
buffer.WriteString(fmt.Sprintf(`if (element.hasAttribute('%v')) { element.removeAttribute('%v');}`, property, property))
|
||||
buffer.WriteRune('\n')
|
||||
} else {
|
||||
session.runScript(fmt.Sprintf(`removeProperty('%v', '%v');`, htmlID, property))
|
||||
session.runFunc("removeProperty", htmlID, property)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -825,8 +825,7 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) {
|
|||
defer session.setIgnoreViewUpdates(false)
|
||||
}
|
||||
|
||||
var cssBuilder viewCSSBuilder
|
||||
cssBuilder.buffer = allocStringBuilder()
|
||||
cssBuilder := viewCSSBuilder{buffer: allocStringBuilder()}
|
||||
defer freeStringBuilder(cssBuilder.buffer)
|
||||
|
||||
var view tableCellView
|
||||
|
|
|
@ -151,7 +151,7 @@ func (tabsLayout *tabsLayoutData) remove(tag string) {
|
|||
return
|
||||
}
|
||||
if tabsLayout.created {
|
||||
tabsLayout.session.runScript(fmt.Sprintf("activateTab('%v', %d);", tabsLayout.htmlID(), 0))
|
||||
tabsLayout.session.runFunc("activateTab", tabsLayout.htmlID(), 0)
|
||||
for _, listener := range tabsLayout.tabListener {
|
||||
listener(tabsLayout, 0, oldCurrent)
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ func (tabsLayout *tabsLayoutData) set(tag string, value any) bool {
|
|||
return true
|
||||
}
|
||||
if tabsLayout.created {
|
||||
tabsLayout.session.runScript(fmt.Sprintf("activateTab('%v', %d);", tabsLayout.htmlID(), current))
|
||||
tabsLayout.session.runFunc("activateTab", tabsLayout.htmlID(), current)
|
||||
for _, listener := range tabsLayout.tabListener {
|
||||
listener(tabsLayout, current, oldCurrent)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package rui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -98,7 +97,7 @@ func (picker *timePickerData) remove(tag string) {
|
|||
delete(picker.properties, TimePickerValue)
|
||||
time := GetTimePickerValue(picker)
|
||||
if picker.created {
|
||||
picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), time.Format(timeFormat)))
|
||||
picker.session.runFunc("setInputValue", picker.htmlID(), time.Format(timeFormat))
|
||||
}
|
||||
for _, listener := range picker.timeChangedListeners {
|
||||
listener(picker, time)
|
||||
|
@ -212,7 +211,7 @@ func (picker *timePickerData) set(tag string, value any) bool {
|
|||
if time, ok := setTimeValue(TimePickerValue); ok {
|
||||
if time != oldTime {
|
||||
if picker.created {
|
||||
picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), time.Format(timeFormat)))
|
||||
picker.session.runFunc("setInputValue", picker.htmlID(), time.Format(timeFormat))
|
||||
}
|
||||
for _, listener := range picker.timeChangedListeners {
|
||||
listener(picker, time)
|
||||
|
|
2
view.go
2
view.go
|
@ -754,7 +754,7 @@ func viewHTML(view View, buffer *strings.Builder) {
|
|||
buffer.WriteRune('"')
|
||||
}
|
||||
|
||||
var cssBuilder viewCSSBuilder
|
||||
cssBuilder := viewCSSBuilder{buffer: allocStringBuilder()}
|
||||
view.cssStyle(view, &cssBuilder)
|
||||
|
||||
if style := cssBuilder.finish(); style != "" {
|
||||
|
|
|
@ -803,7 +803,7 @@ func colorStyledProperty(view View, subviewID []string, tag string, inherit bool
|
|||
// The focused View is the View which will receive keyboard events by default.
|
||||
func FocusView(view View) {
|
||||
if view != nil {
|
||||
view.Session().runScript("focus('" + view.htmlID() + "')")
|
||||
view.Session().runFunc("focus", view.htmlID())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -811,21 +811,21 @@ func FocusView(view View) {
|
|||
// The focused View is the View which will receive keyboard events by default.
|
||||
func FocusViewByID(viewID string, session Session) {
|
||||
if viewID != "" {
|
||||
session.runScript("focus('" + viewID + "')")
|
||||
session.runFunc("focus", viewID)
|
||||
}
|
||||
}
|
||||
|
||||
// BlurView removes keyboard focus from the specified View.
|
||||
func BlurView(view View) {
|
||||
if view != nil {
|
||||
view.Session().runScript("blur('" + view.htmlID() + "')")
|
||||
view.Session().runFunc("blur", view.htmlID())
|
||||
}
|
||||
}
|
||||
|
||||
// BlurViewByID removes keyboard focus from the View with the specified viewID.
|
||||
func BlurViewByID(viewID string, session Session) {
|
||||
if viewID != "" {
|
||||
session.runScript("blur('" + viewID + "')")
|
||||
session.runFunc("blur", viewID)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
87
webBrige.go
87
webBrige.go
|
@ -3,8 +3,10 @@
|
|||
package rui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
|
@ -16,6 +18,7 @@ type wsBrige struct {
|
|||
answerID int
|
||||
answerMutex sync.Mutex
|
||||
closed bool
|
||||
buffer strings.Builder
|
||||
}
|
||||
|
||||
var upgrader = websocket.Upgrader{
|
||||
|
@ -43,6 +46,90 @@ func (brige *wsBrige) close() {
|
|||
brige.conn.Close()
|
||||
}
|
||||
|
||||
func (brige *wsBrige) argToString(arg any) (string, bool) {
|
||||
switch arg := arg.(type) {
|
||||
case string:
|
||||
arg = strings.ReplaceAll(arg, "\\", `\\`)
|
||||
arg = strings.ReplaceAll(arg, "'", `\'`)
|
||||
arg = strings.ReplaceAll(arg, "\n", `\n`)
|
||||
arg = strings.ReplaceAll(arg, "\r", `\r`)
|
||||
arg = strings.ReplaceAll(arg, "\t", `\t`)
|
||||
arg = strings.ReplaceAll(arg, "\b", `\b`)
|
||||
arg = strings.ReplaceAll(arg, "\f", `\f`)
|
||||
arg = strings.ReplaceAll(arg, "\v", `\v`)
|
||||
return `'` + arg + `'`, true
|
||||
|
||||
case rune:
|
||||
switch arg {
|
||||
case '\t':
|
||||
return `'\t'`, true
|
||||
case '\r':
|
||||
return `'\r'`, true
|
||||
case '\n':
|
||||
return `'\n'`, true
|
||||
case '\b':
|
||||
return `'\b'`, true
|
||||
case '\f':
|
||||
return `'\f'`, true
|
||||
case '\v':
|
||||
return `'\v'`, true
|
||||
case '\'':
|
||||
return `'\''`, true
|
||||
case '\\':
|
||||
return `'\\'`, true
|
||||
}
|
||||
if arg < ' ' {
|
||||
return fmt.Sprintf(`'\x%02d'`, int(arg)), true
|
||||
}
|
||||
return `'` + string(arg) + `'`, true
|
||||
|
||||
case bool:
|
||||
if arg {
|
||||
return "true", true
|
||||
} else {
|
||||
return "false", true
|
||||
}
|
||||
|
||||
case float32:
|
||||
return fmt.Sprintf("%g", float64(arg)), true
|
||||
|
||||
case float64:
|
||||
return fmt.Sprintf("%g", arg), true
|
||||
|
||||
default:
|
||||
if n, ok := isInt(arg); ok {
|
||||
return fmt.Sprintf("%d", n), true
|
||||
}
|
||||
}
|
||||
|
||||
ErrorLog("Unsupported agument type")
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (brige *wsBrige) runFunc(funcName string, args ...any) bool {
|
||||
brige.buffer.Reset()
|
||||
brige.buffer.WriteString(funcName)
|
||||
brige.buffer.WriteRune('(')
|
||||
for i, arg := range args {
|
||||
argText, ok := brige.argToString(arg)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
brige.buffer.WriteString(", ")
|
||||
}
|
||||
brige.buffer.WriteString(argText)
|
||||
}
|
||||
brige.buffer.WriteString(");")
|
||||
|
||||
if err := brige.conn.WriteMessage(websocket.TextMessage, []byte(brige.buffer.String())); err != nil {
|
||||
ErrorLog(err.Error())
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (brige *wsBrige) readMessage() (string, bool) {
|
||||
_, p, err := brige.conn.ReadMessage()
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue