diff --git a/animation.go b/animation.go index d11063f..706cab4 100644 --- a/animation.go +++ b/animation.go @@ -607,8 +607,12 @@ func (view *viewData) SetAnimated(tag string, value interface{}, animation Anima return view.Set(tag, value) } - updateProperty(view.htmlID(), "ontransitionend", "transitionEndEvent(this, event)", view.session) - updateProperty(view.htmlID(), "ontransitioncancel", "transitionCancelEvent(this, event)", view.session) + session := view.Session() + htmlID := view.htmlID() + session.startUpdateScript(htmlID) + + updateProperty(htmlID, "ontransitionend", "transitionEndEvent(this, event)", view.session) + updateProperty(htmlID, "ontransitioncancel", "transitionCancelEvent(this, event)", view.session) if prevAnimation, ok := view.transitions[tag]; ok { view.singleTransition[tag] = prevAnimation @@ -618,6 +622,8 @@ func (view *viewData) SetAnimated(tag string, value interface{}, animation Anima view.transitions[tag] = animation view.updateTransitionCSS() + session.finishUpdateScript(htmlID) + result := view.Set(tag, value) if !result { delete(view.singleTransition, tag) diff --git a/app_scripts.js b/app_scripts.js index bec958d..8499f71 100644 --- a/app_scripts.js +++ b/app_scripts.js @@ -231,7 +231,7 @@ function updateProperty(elementId, property, value) { } } -function removeProperty(elementId, property, value) { +function removeProperty(elementId, property) { var element = document.getElementById(elementId); if (element && element.hasAttribute(property)) { element.removeAttribute(property); diff --git a/session.go b/session.go index d2d38c4..a85a079 100644 --- a/session.go +++ b/session.go @@ -104,6 +104,10 @@ type Session interface { popupManager() *popupManager imageManager() *imageManager + + startUpdateScript(htmlID string) + updateScript(htmlID string) *strings.Builder + finishUpdateScript(htmlID string) } type sessionData struct { @@ -134,6 +138,7 @@ type sessionData struct { events chan DataObject animationCounter int animationCSS string + updateScripts map[string]*strings.Builder } func newSession(app Application, id int, customTheme string, params DataObject) Session { @@ -149,6 +154,7 @@ func newSession(app Application, id int, customTheme string, params DataObject) session.ignoreUpdates = false session.animationCounter = 0 session.animationCSS = "" + session.updateScripts = map[string]*strings.Builder{} if customTheme != "" { if theme, ok := CreateThemeFromText(customTheme); ok { diff --git a/sessionUtils.go b/sessionUtils.go index e9d7d02..0fede25 100644 --- a/sessionUtils.go +++ b/sessionUtils.go @@ -2,8 +2,33 @@ package rui import ( "fmt" + "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) @@ -58,19 +83,36 @@ func appendToInnerHTML(htmlID, content string, session Session) { func updateProperty(htmlID, property, value string, session Session) { if !session.ignoreViewUpdates() { - session.runScript(fmt.Sprintf(`updateProperty('%v', '%v', '%v');`, htmlID, property, value)) + if buffer := session.updateScript(htmlID); buffer != nil { + 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)) + } } } func updateCSSProperty(htmlID, property, value string, session Session) { if !session.ignoreViewUpdates() { - session.runScript(fmt.Sprintf(`updateCSSProperty('%v', '%v', '%v');`, htmlID, property, value)) + if buffer := session.updateScript(htmlID); buffer != nil { + 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)) + } } } func updateBoolProperty(htmlID, property string, value bool, session Session) { if !session.ignoreViewUpdates() { - if value { + 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 if value { session.runScript(fmt.Sprintf(`updateProperty('%v', '%v', true);`, htmlID, property)) } else { session.runScript(fmt.Sprintf(`updateProperty('%v', '%v', false);`, htmlID, property)) @@ -80,7 +122,12 @@ func updateBoolProperty(htmlID, property string, value bool, session Session) { func removeProperty(htmlID, property string, session Session) { if !session.ignoreViewUpdates() { - session.runScript(fmt.Sprintf(`removeProperty('%v', '%v');`, htmlID, property)) + 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.runScript(fmt.Sprintf(`removeProperty('%v', '%v');`, htmlID, property)) + } } } diff --git a/view.go b/view.go index 59122c7..070caa9 100644 --- a/view.go +++ b/view.go @@ -402,18 +402,32 @@ func viewPropertyChanged(view *viewData, tag string) { case Border: if getBorder(view, Border) == nil { + buffer := session.updateScript(htmlID) + if buffer == nil { + session.startUpdateScript(htmlID) + } updateCSSProperty(htmlID, BorderWidth, "", session) updateCSSProperty(htmlID, BorderColor, "", session) updateCSSProperty(htmlID, BorderStyle, "none", session) + 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) + } updateCSSProperty(htmlID, BorderWidth, border.cssWidthValue(session), session) updateCSSProperty(htmlID, BorderColor, border.cssColorValue(session), session) updateCSSProperty(htmlID, BorderStyle, border.cssStyleValue(session), session) + if buffer == nil { + session.finishUpdateScript(htmlID) + } } return @@ -510,8 +524,15 @@ func viewPropertyChanged(view *viewData, tag string) { text = filter.cssStyle(session) } } + buffer := session.updateScript(htmlID) + if buffer == nil { + session.startUpdateScript(htmlID) + } updateCSSProperty(htmlID, "-webkit-backdrop-filter", text, session) updateCSSProperty(htmlID, tag, text, session) + if buffer == nil { + session.finishUpdateScript(htmlID) + } return case FontName: @@ -585,6 +606,10 @@ func viewPropertyChanged(view *viewData, tag string) { return case UserSelect: + buffer := session.updateScript(htmlID) + if buffer == nil { + session.startUpdateScript(htmlID) + } if userSelect, ok := boolProperty(view, UserSelect, session); ok { if userSelect { updateCSSProperty(htmlID, "-webkit-user-select", "auto", session) @@ -597,6 +622,9 @@ func viewPropertyChanged(view *viewData, tag string) { updateCSSProperty(htmlID, "-webkit-user-select", "", session) updateCSSProperty(htmlID, "user-select", "", session) } + if buffer == nil { + session.finishUpdateScript(htmlID) + } return } diff --git a/viewUtils.go b/viewUtils.go index 00aa590..e49d3e8 100644 --- a/viewUtils.go +++ b/viewUtils.go @@ -47,20 +47,20 @@ func SetChangeListener(view View, viewID, tag string, listener func(View, string // true - all properties were set successful, // false - error (incompatible type or invalid format of a string value, see AppLog). func SetParams(rootView View, viewID string, params Params) bool { - var view View if viewID != "" { - view = ViewByID(rootView, viewID) - } else { - view = rootView + rootView = ViewByID(rootView, viewID) } - if view == nil { + if rootView == nil { return false } + session := rootView.Session() + session.startUpdateScript(rootView.htmlID()) result := true for tag, value := range params { - result = view.Set(tag, value) && result + result = rootView.Set(tag, value) && result } + session.finishUpdateScript(rootView.htmlID()) return result }