diff --git a/editView.go b/editView.go index 7a3e373..4981b06 100644 --- a/editView.go +++ b/editView.go @@ -118,7 +118,7 @@ func (edit *editViewData) remove(tag string) { if exists { delete(edit.properties, tag) if edit.created { - edit.session.updateBoolProperty(edit.htmlID(), tag, false) + edit.session.updateProperty(edit.htmlID(), tag, false) } edit.propertyChangedEvent(tag) } @@ -270,7 +270,7 @@ func (edit *editViewData) set(tag string, value any) bool { case Spellcheck: if edit.setBoolProperty(Spellcheck, value) { if edit.created { - edit.session.updateBoolProperty(edit.htmlID(), Spellcheck, IsSpellcheck(edit)) + edit.session.updateProperty(edit.htmlID(), Spellcheck, IsSpellcheck(edit)) } edit.propertyChangedEvent(tag) return true diff --git a/mediaPlayer.go b/mediaPlayer.go index bb8d22f..527686d 100644 --- a/mediaPlayer.go +++ b/mediaPlayer.go @@ -465,7 +465,7 @@ func (player *mediaPlayerData) propertyChanged(tag string) { case Controls, Loop: value, _ := boolProperty(player, tag, player.session) if value { - player.session.updateBoolProperty(player.htmlID(), tag, value) + player.session.updateProperty(player.htmlID(), tag, value) } else { player.session.removeProperty(player.htmlID(), tag) } diff --git a/session.go b/session.go index fb268c4..554607a 100644 --- a/session.go +++ b/session.go @@ -8,11 +8,13 @@ import ( ) type webBrige interface { + startUpdateScript(htmlID string) bool + finishUpdateScript(htmlID string) runFunc(funcName string, args ...any) bool updateInnerHTML(htmlID, html string) appendToInnerHTML(htmlID, html string) updateCSSProperty(htmlID, property, value string) - updateProperty(htmlID, property, value any) + updateProperty(htmlID, property string, value any) removeProperty(htmlID, property string) readMessage() (string, bool) writeMessage(text string) bool @@ -107,10 +109,11 @@ type Session interface { updateInnerHTML(htmlID, html string) appendToInnerHTML(htmlID, html string) updateCSSProperty(htmlID, property, value string) - updateProperty(htmlID, property, value string) - updateBoolProperty(htmlID, property string, value bool) + updateProperty(htmlID, property string, value any) removeProperty(htmlID, property string) runScript(script string) + startUpdateScript(htmlID string) bool + finishUpdateScript(htmlID string) canvasTextMetrics(htmlID, font, text string) TextMetrics htmlPropertyValue(htmlID, name string) string handleAnswer(data DataObject) @@ -131,10 +134,6 @@ type Session interface { popupManager() *popupManager imageManager() *imageManager - - startUpdateScript(htmlID string) - updateScript(htmlID string) *strings.Builder - finishUpdateScript(htmlID string) } type sessionData struct { @@ -365,50 +364,33 @@ func (session *sessionData) appendToInnerHTML(htmlID, html string) { } func (session *sessionData) updateCSSProperty(htmlID, property, value string) { - if !session.ignoreViewUpdates() { - if buffer := session.updateScript(htmlID); buffer != nil { - buffer.WriteString(fmt.Sprintf(`element.style['%v'] = '%v';`, property, value)) - buffer.WriteRune('\n') - } else { - session.runFunc("updateCSSProperty", htmlID, property, value) - } + if !session.ignoreViewUpdates() && session.brige != nil { + session.brige.updateCSSProperty(htmlID, property, value) } } -func (session *sessionData) updateProperty(htmlID, property, value string) { - if !session.ignoreViewUpdates() { - if buffer := session.updateScript(htmlID); buffer != nil { - buffer.WriteString(fmt.Sprintf(`element.setAttribute('%v', '%v');`, property, value)) - buffer.WriteRune('\n') - } else { - session.runFunc("updateProperty", htmlID, property, value) - } - } -} - -func (session *sessionData) updateBoolProperty(htmlID, property string, value bool) { - if !session.ignoreViewUpdates() { - if buffer := session.updateScript(htmlID); buffer != nil { - if value { - buffer.WriteString(fmt.Sprintf(`element.setAttribute('%v', true);`, property)) - } else { - buffer.WriteString(fmt.Sprintf(`element.setAttribute('%v', false);`, property)) - } - buffer.WriteRune('\n') - } else { - session.runFunc("updateProperty", htmlID, property, value) - } +func (session *sessionData) updateProperty(htmlID, property string, value any) { + if !session.ignoreViewUpdates() && session.brige != nil { + session.brige.updateProperty(htmlID, property, value) } } func (session *sessionData) removeProperty(htmlID, property string) { - if !session.ignoreViewUpdates() { - if buffer := session.updateScript(htmlID); buffer != nil { - buffer.WriteString(fmt.Sprintf(`if (element.hasAttribute('%v')) { element.removeAttribute('%v');}`, property, property)) - buffer.WriteRune('\n') - } else { - session.runFunc("removeProperty", htmlID, property) - } + if !session.ignoreViewUpdates() && session.brige != nil { + session.brige.removeProperty(htmlID, property) + } +} + +func (session *sessionData) startUpdateScript(htmlID string) bool { + if session.brige != nil { + return session.brige.startUpdateScript(htmlID) + } + return false +} + +func (session *sessionData) finishUpdateScript(htmlID string) { + if session.brige != nil { + session.brige.finishUpdateScript(htmlID) } } diff --git a/sessionUtils.go b/sessionUtils.go index 770fff4..4da1e2d 100644 --- a/sessionUtils.go +++ b/sessionUtils.go @@ -1,33 +1,5 @@ package rui -import ( - "strings" -) - -func (session *sessionData) startUpdateScript(htmlID string) { - buffer := allocStringBuilder() - session.updateScripts[htmlID] = buffer - buffer.WriteString("var element = document.getElementById('") - buffer.WriteString(htmlID) - buffer.WriteString("');\nif (element) {\n") -} - -func (session *sessionData) updateScript(htmlID string) *strings.Builder { - if buffer, ok := session.updateScripts[htmlID]; ok { - return buffer - } - return nil -} - -func (session *sessionData) finishUpdateScript(htmlID string) { - if buffer, ok := session.updateScripts[htmlID]; ok { - buffer.WriteString("scanElementsSize();\n}\n") - session.runScript(buffer.String()) - freeStringBuilder(buffer) - delete(session.updateScripts, htmlID) - } -} - func sizeConstant(session Session, tag string) (SizeUnit, bool) { if text, ok := session.Constant(tag); ok { return StringToSizeUnit(text) @@ -40,7 +12,8 @@ func updateCSSStyle(htmlID string, session Session) { if view := session.viewByHTMLID(htmlID); view != nil { builder := viewCSSBuilder{buffer: allocStringBuilder()} view.cssStyle(view, &builder) - session.runFunc("updateCSSStyle", view.htmlID(), builder.finish()) + //session.runFunc("updateCSSStyle", view.htmlID(), builder.finish()) + session.updateProperty(view.htmlID(), "style", builder.finish()) } } } @@ -64,67 +37,6 @@ func updateInnerHTML(htmlID string, session Session) { } } -/* -func updateProperty(htmlID, property, value string, session Session) { - if !session.ignoreViewUpdates() { - if buffer := session.updateScript(htmlID); buffer != nil { - buffer.WriteString(fmt.Sprintf(`element.setAttribute('%v', '%v');`, property, value)) - buffer.WriteRune('\n') - } else { - session.runFunc("updateProperty", htmlID, property, value) - } - } -} - -func updateCSSProperty(htmlID, property, value string, session Session) { - if !session.ignoreViewUpdates() { - if buffer := session.updateScript(htmlID); buffer != nil { - buffer.WriteString(fmt.Sprintf(`element.style['%v'] = '%v';`, property, value)) - buffer.WriteRune('\n') - } else { - session.runFunc("updateCSSProperty", htmlID, property, value) - } - } -} - -func updateBoolProperty(htmlID, property string, value bool, session Session) { - if !session.ignoreViewUpdates() { - if buffer := session.updateScript(htmlID); buffer != nil { - if value { - buffer.WriteString(fmt.Sprintf(`element.setAttribute('%v', true);`, property)) - } else { - buffer.WriteString(fmt.Sprintf(`element.setAttribute('%v', false);`, property)) - } - buffer.WriteRune('\n') - } else { - session.runFunc("updateProperty", htmlID, property, value) - } - } -} - -func removeProperty(htmlID, property string, session Session) { - if !session.ignoreViewUpdates() { - if buffer := session.updateScript(htmlID); buffer != nil { - buffer.WriteString(fmt.Sprintf(`if (element.hasAttribute('%v')) { element.removeAttribute('%v');}`, property, property)) - buffer.WriteRune('\n') - } else { - session.runFunc("removeProperty", htmlID, property) - } - } -} -*/ -/* -func setDisabled(htmlID string, disabled bool, session Session) { - if !session.ignoreViewUpdates() { - if disabled { - session.runScript(fmt.Sprintf(`setDisabled('%v', true);`, htmlID)) - } else { - session.runScript(fmt.Sprintf(`setDisabled('%v', false);`, htmlID)) - } - } -} -*/ - func viewByHTMLID(id string, startView View) View { if startView != nil { if startView.htmlID() == id { diff --git a/view.go b/view.go index 32c19d5..754ef1e 100644 --- a/view.go +++ b/view.go @@ -398,32 +398,24 @@ func viewPropertyChanged(view *viewData, tag string) { case Border: if getBorder(view, Border) == nil { - buffer := session.updateScript(htmlID) - if buffer == nil { - session.startUpdateScript(htmlID) + if session.startUpdateScript(htmlID) { + defer session.finishUpdateScript(htmlID) } session.updateCSSProperty(htmlID, BorderWidth, "") session.updateCSSProperty(htmlID, BorderColor, "") session.updateCSSProperty(htmlID, BorderStyle, "none") - if buffer == nil { - session.finishUpdateScript(htmlID) - } return } fallthrough case BorderLeft, BorderRight, BorderTop, BorderBottom: if border := getBorder(view, Border); border != nil { - buffer := session.updateScript(htmlID) - if buffer == nil { - session.startUpdateScript(htmlID) + if session.startUpdateScript(htmlID) { + defer session.finishUpdateScript(htmlID) } session.updateCSSProperty(htmlID, BorderWidth, border.cssWidthValue(session)) session.updateCSSProperty(htmlID, BorderColor, border.cssColorValue(session)) session.updateCSSProperty(htmlID, BorderStyle, border.cssStyleValue(session)) - if buffer == nil { - session.finishUpdateScript(htmlID) - } } return @@ -520,15 +512,11 @@ func viewPropertyChanged(view *viewData, tag string) { text = filter.cssStyle(session) } } - buffer := session.updateScript(htmlID) - if buffer == nil { - session.startUpdateScript(htmlID) + if session.startUpdateScript(htmlID) { + defer session.finishUpdateScript(htmlID) } session.updateCSSProperty(htmlID, "-webkit-backdrop-filter", text) session.updateCSSProperty(htmlID, tag, text) - if buffer == nil { - session.finishUpdateScript(htmlID) - } return case FontName: @@ -602,9 +590,8 @@ func viewPropertyChanged(view *viewData, tag string) { return case UserSelect: - buffer := session.updateScript(htmlID) - if buffer == nil { - session.startUpdateScript(htmlID) + if session.startUpdateScript(htmlID) { + defer session.finishUpdateScript(htmlID) } if userSelect, ok := boolProperty(view, UserSelect, session); ok { if userSelect { @@ -618,9 +605,6 @@ func viewPropertyChanged(view *viewData, tag string) { session.updateCSSProperty(htmlID, "-webkit-user-select", "") session.updateCSSProperty(htmlID, "user-select", "") } - if buffer == nil { - session.finishUpdateScript(htmlID) - } return } diff --git a/webBrige.go b/webBrige.go index 7ac6d0d..ff44bce 100644 --- a/webBrige.go +++ b/webBrige.go @@ -13,12 +13,13 @@ import ( ) type wsBrige struct { - conn *websocket.Conn - answer map[int]chan DataObject - answerID int - answerMutex sync.Mutex - closed bool - buffer strings.Builder + conn *websocket.Conn + answer map[int]chan DataObject + answerID int + answerMutex sync.Mutex + closed bool + buffer strings.Builder + updateScripts map[string]*strings.Builder } var upgrader = websocket.Upgrader{ @@ -38,6 +39,7 @@ func CreateSocketBrige(w http.ResponseWriter, req *http.Request) webBrige { brige.answer = make(map[int]chan DataObject) brige.conn = conn brige.closed = false + brige.updateScripts = map[string]*strings.Builder{} return brige } @@ -46,6 +48,27 @@ func (brige *wsBrige) close() { brige.conn.Close() } +func (brige *wsBrige) startUpdateScript(htmlID string) bool { + if _, ok := brige.updateScripts[htmlID]; ok { + return false + } + buffer := allocStringBuilder() + brige.updateScripts[htmlID] = buffer + buffer.WriteString("var element = document.getElementById('") + buffer.WriteString(htmlID) + buffer.WriteString("');\nif (element) {\n") + return true +} + +func (brige *wsBrige) finishUpdateScript(htmlID string) { + if buffer, ok := brige.updateScripts[htmlID]; ok { + buffer.WriteString("scanElementsSize();\n}\n") + brige.writeMessage(buffer.String()) + freeStringBuilder(buffer) + delete(brige.updateScripts, htmlID) + } +} + func (brige *wsBrige) argToString(arg any) (string, bool) { switch arg := arg.(type) { case string: @@ -143,15 +166,42 @@ func (brige *wsBrige) appendToInnerHTML(htmlID, html string) { } func (brige *wsBrige) updateCSSProperty(htmlID, property, value string) { - brige.runFunc("updateCSSProperty", htmlID, property, value) + if buffer, ok := brige.updateScripts[htmlID]; ok { + buffer.WriteString(`element.style['`) + buffer.WriteString(property) + buffer.WriteString(`'] = '`) + buffer.WriteString(value) + buffer.WriteString("';\n") + } else { + brige.runFunc("updateCSSProperty", htmlID, property, value) + } + } -func (brige *wsBrige) updateProperty(htmlID, property, value any) { - brige.runFunc("updateProperty", htmlID, property, value) +func (brige *wsBrige) updateProperty(htmlID, property string, value any) { + if buffer, ok := brige.updateScripts[htmlID]; ok { + if val, ok := brige.argToString(value); ok { + buffer.WriteString(`element.setAttribute('`) + buffer.WriteString(property) + buffer.WriteString(`', `) + buffer.WriteString(val) + buffer.WriteString(");\n") + } + } else { + brige.runFunc("updateProperty", htmlID, property, value) + } } func (brige *wsBrige) removeProperty(htmlID, property string) { - brige.runFunc("removeProperty", htmlID, property) + if buffer, ok := brige.updateScripts[htmlID]; ok { + buffer.WriteString(`if (element.hasAttribute('`) + buffer.WriteString(property) + buffer.WriteString(`')) { element.removeAttribute('`) + buffer.WriteString(property) + buffer.WriteString("');}\n") + } else { + brige.runFunc("removeProperty", htmlID, property) + } } func (brige *wsBrige) readMessage() (string, bool) {