From b76e3e56d8445baad6e1b434f8e53918b957ec5d Mon Sep 17 00:00:00 2001 From: Alexei Anoshenko <2277098+anoshenko@users.noreply.github.com> Date: Mon, 9 Jun 2025 19:35:14 +0300 Subject: [PATCH] Added "drop-effect-allowed" property --- app_scripts.js | 39 ++++-- dragAndDrop.go | 322 ++++++++++++++++++++++++++++++++++++++++++------- editView.go | 4 +- propertySet.go | 5 - view.go | 73 +++++++---- 5 files changed, 357 insertions(+), 86 deletions(-) diff --git a/app_scripts.js b/app_scripts.js index c729388..4aacd91 100644 --- a/app_scripts.js +++ b/app_scripts.js @@ -2144,10 +2144,10 @@ function dragAndDropEvent(element, event, tag) { //event.preventDefault() let message = tag + "{session=" + sessionID + ",id=" + element.id + mouseEventData(element, event); + if (event.target) { + message += ",target=" + event.target.id; + } if (event.dataTransfer) { - if (event.target) { - message += ",target=" + event.target.id; - } let dataText = "" for (const item of event.dataTransfer.items) { const data = event.dataTransfer.getData(item.type); @@ -2161,7 +2161,25 @@ function dragAndDropEvent(element, event, tag) { if (dataText != "") { message += ',data="' + dataText + '"'; } + + dataText = "" + for (const file of event.dataTransfer.files) { + if (dataText != "") { + dataText += ";"; + } + dataText += file.name; + } + if (dataText != "") { + message += ',files="' + dataText + '"'; + } + if (event.dataTransfer.effectAllowed && event.dataTransfer.effectAllowed != "uninitialized") { + message += ',effect-allowed="' + event.dataTransfer.effectAllowed + '"'; + } + if (event.dataTransfer.dropEffect) { + message += ',drop-effect="' + event.dataTransfer.dropEffect + '"'; + } } + message += "}"; sendMessage(message); } @@ -2193,14 +2211,12 @@ function dragStartEvent(element, event) { let img = new Image(); img.src = image; event.dataTransfer.setDragImage(img, x, y); - - let effect = element.getAttribute("data-drag-effect"); - if (effect) { - event.dataTransfer.effectAllowed = effect; - } } - // TODO drag effect + let allowed = element.getAttribute("data-drop-effect-allowed"); + if (allowed) { + event.dataTransfer.effectAllowed = allowed; + } dragAndDropEvent(element, event, "drag-start-event"); } @@ -2210,6 +2226,11 @@ function dragEndEvent(element, event) { } function dragEnterEvent(element, event) { + let effect = element.getAttribute("data-drop-effect"); + if (effect) { + event.dataTransfer.dropEffect = effect; + } + dragAndDropEvent(element, event, "drag-enter-event") } diff --git a/dragAndDrop.go b/dragAndDrop.go index 8a0c5e4..156ae62 100644 --- a/dragAndDrop.go +++ b/dragAndDrop.go @@ -39,7 +39,23 @@ const ( // Supported types: float, int, string. DragImageYOffset PropertyName = "drag-image-y-offset" - // DragEffect is the constant for "drag-effect" property tag. + // DropEffect is the constant for "drag-effect" property tag. + // + // Used by View. + // Controls the feedback (typically visual) the user is given during a drag and drop operation. + // It will affect which cursor is displayed while dragging. For example, when the user hovers over a target drop element, + // the browser's cursor may indicate which type of operation will occur. + // + // Supported types: int, string. + // + // Values: + // - 0 (DropEffectUndefined) or "undefined" - The property value is not defined (defaut value). + // - 1 (DropEffectCopy) or "copy" - A copy of the source item may be made at the new location. + // - 2 (DropEffectMove) or "move" - An item may be moved to a new location. + // - 4 (DropEffectLink) or "link" - A link may be established to the source at the new location. + DropEffect PropertyName = "drag-effect" + + // DropEffectAllowed is the constant for "drop-effect-allowed" property tag. // // Used by View. // Specifies the effect that is allowed for a drag operation. @@ -52,15 +68,15 @@ const ( // Supported types: int, string. // // Values: - // - 0 (DragEffectAll) or "all" - All operations are permitted (defaut value). - // - 1 (DragEffectCopy) or "copy" - A copy of the source item may be made at the new location. - // - 2 (DragEffectMove) or "move" - An item may be moved to a new location. - // - 3 (DragEffectLink) or "link" - A link may be established to the source at the new location. - // - 4 (DragEffectCopyMove) or "copyMove" - A copy or move operation is permitted. - // - 5 (DragEffectCopyLink) or "copyLink" - A copy or link operation is permitted. - // - 6 (DragEffectLinkMove) or "linkMove" - A link or move operation is permitted. - // - 7 (DragEffectNone) or "none" - The item may not be dropped. - DragEffect PropertyName = "drag-effect" + // - 0 (DropEffectUndefined) or "undefined" - The property value is not defined (defaut value). Equivalent to DropEffectAll + // - 1 (DropEffectCopy) or "copy" - A copy of the source item may be made at the new location. + // - 2 (DropEffectMove) or "move" - An item may be moved to a new location. + // - 3 (DropEffectLink) or "link" - A link may be established to the source at the new location. + // - 4 (DropEffectCopyMove) or "copy|move" - A copy or move operation is permitted. + // - 5 (DropEffectCopyLink) or "copy|link" - A copy or link operation is permitted. + // - 6 (DropEffectLinkMove) or "link|move" - A link or move operation is permitted. + // - 7 (DropEffectAll) or "all" or "copy|move|link" - All operations are permitted. + DropEffectAllowed PropertyName = "drag-effect-allowed" // DragStartEvent is the constant for "drag-start-event" property tag. // @@ -116,36 +132,42 @@ const ( // DropEvent PropertyName = "drop-event" - // DragEffectAll - the value of the "drag-effect" property: all operations (copy, move, and link) are permitted (defaut value). - DragEffectAll = 0 + // DropEffectUndefined - the value of the "drop-effect" and "drop-effect-allowed" properties: the value is not defined (default value). + DropEffectUndefined = 0 - // DragEffectCopy - the value of the "drag-effect" property: a copy of the source item may be made at the new location. - DragEffectCopy = 1 + // DropEffectNone - the value of the DropEffect field of the DragEvent struct: the item may not be dropped. + DropEffectNone = 0 - // DragEffectMove - the value of the "drag-effect" property: an item may be moved to a new location. - DragEffectMove = 2 + // DropEffectCopy - the value of the "drop-effect" and "drop-effect-allowed" properties: a copy of the source item may be made at the new location. + DropEffectCopy = 1 - // DragEffectLink - the value of the "drag-effect" property: a link may be established to the source at the new location. - DragEffectLink = 3 + // DropEffectMove - the value of the "drop-effect" and "drop-effect-allowed" properties: an item may be moved to a new location. + DropEffectMove = 2 - // DragEffectCopyMove - the value of the "drag-effect" property: a copy or move operation is permitted. - DragEffectCopyMove = 4 + // DropEffectLink - the value of the "drop-effect" and "drop-effect-allowed" properties: a link may be established to the source at the new location. + DropEffectLink = 4 - // DragEffectCopyLink - the value of the "drag-effect" property: a copy or link operation is permitted. - DragEffectCopyLink = 5 + // DropEffectCopyMove - the value of the "drop-effect-allowed" property: a copy or move operation is permitted. + DropEffectCopyMove = DropEffectCopy + DropEffectMove - // DragEffectLinkMove - the value of the "drag-effect" property: a link or move operation is permitted. - DragEffectLinkMove = 6 + // DropEffectCopyLink - the value of the "drop-effect-allowed" property: a copy or link operation is permitted. + DropEffectCopyLink = DropEffectCopy + DropEffectLink - // DragEffectNone - the value of the "drag-effect" property: the item may not be dropped. - DragEffectNone = 7 + // DropEffectLinkMove - the value of the "drop-effect-allowed" property: a link or move operation is permitted. + DropEffectLinkMove = DropEffectLink + DropEffectMove + + // DropEffectAll - the value of the "drop-effect-allowed" property: all operations (copy, move, and link) are permitted (defaut value). + DropEffectAll = DropEffectCopy + DropEffectMove + DropEffectLink ) // MouseEvent represent a mouse event type DragAndDropEvent struct { MouseEvent - Data map[string]string - Target View + Data map[string]string + Files string + Target View + EffectAllowed int + DropEffect int } func (event *DragAndDropEvent) init(session Session, data DataObject) { @@ -175,6 +197,136 @@ func (event *DragAndDropEvent) init(session Session, data DataObject) { if targetId, ok := data.PropertyValue("target"); ok { event.Target = session.viewByHTMLID(targetId) } + + if effect, ok := data.PropertyValue("effect-allowed"); ok { + for i, value := range []string{"undefined", "copy", "move", "copyMove", "link", "copyLink", "linkMove", "all"} { + if value == effect { + event.EffectAllowed = i + break + } + } + } + + if effect, ok := data.PropertyValue("drop-effect"); ok && effect != "" { + for i, value := range []string{"none", "copy", "move", "", "link"} { + if value == effect { + event.DropEffect = i + break + } + } + } + + // TODO files +} + +func stringToDropEffect(text string) (int, bool) { + text = strings.Trim(text, " \t\n") + if n, ok := enumStringToInt(text, []string{"", "copy", "move", "", "link"}, false); ok { + switch n { + case DropEffectUndefined, DropEffectCopy, DropEffectMove, DropEffectLink: + return n, true + } + } + return 0, false +} + +func (view *viewData) setDropEffect(value any) []PropertyName { + if !setSimpleProperty(view, DropEffect, value) { + if text, ok := value.(string); ok { + + if n, ok := stringToDropEffect(text); ok { + if n == DropEffectUndefined { + view.setRaw(DropEffect, nil) + } else { + view.setRaw(DropEffect, n) + } + } else { + invalidPropertyValue(DropEffect, value) + return nil + } + + } else if i, ok := isInt(value); ok { + + switch i { + case DropEffectUndefined: + view.setRaw(DropEffect, nil) + + case DropEffectCopy, DropEffectMove, DropEffectLink: + view.setRaw(DropEffect, i) + + default: + invalidPropertyValue(DropEffect, value) + return nil + } + + } else { + + notCompatibleType(DropEffect, value) + return nil + } + + } + + return []PropertyName{DropEffect} +} + +func stringToDropEffectAllowed(text string) (int, bool) { + if strings.Contains(text, "|") { + elements := strings.Split(text, "|") + result := 0 + for _, element := range elements { + if n, ok := stringToDropEffect(element); ok && n != DropEffectUndefined { + result |= n + } else { + return 0, false + } + } + return result, true + } + + text = strings.Trim(text, " \t\n") + if text != "" { + if n, ok := enumStringToInt(text, []string{"undefined", "copy", "move", "", "link", "", "", "all"}, false); ok { + return n, true + } + } + return 0, false +} + +func (view *viewData) setDropEffectAllowed(value any) []PropertyName { + if !setSimpleProperty(view, DropEffectAllowed, value) { + if text, ok := value.(string); ok { + + if n, ok := stringToDropEffectAllowed(text); ok { + if n == DropEffectUndefined { + view.setRaw(DropEffectAllowed, nil) + } else { + view.setRaw(DropEffectAllowed, n) + } + } else { + invalidPropertyValue(DropEffectAllowed, value) + return nil + } + + } else { + n, ok := isInt(value) + if !ok { + notCompatibleType(DropEffectAllowed, value) + return nil + } + + if n == DropEffectUndefined { + view.setRaw(DropEffectAllowed, nil) + } else if n > DropEffectUndefined && n <= DropEffectAll { + view.setRaw(DropEffectAllowed, n) + } else { + notCompatibleType(DropEffectAllowed, value) + return nil + } + } + } + + return []PropertyName{DropEffectAllowed} } func handleDragAndDropEvents(view View, tag PropertyName, data DataObject) { @@ -227,7 +379,26 @@ func dragAndDropHtml(view View, buffer *strings.Builder) { buffer.WriteString(` ondragstart="dragStartEvent(this, event)" `) } - viewEventsHtml[DragAndDropEvent](view, []PropertyName{DragEndEvent, DragEnterEvent, DragLeaveEvent}, buffer) + enterEvent := false + switch GetDropEffect(view) { + case DropEffectCopy: + buffer.WriteString(` data-drop-effect="copy" ondragenter="dragEnterEvent(this, event)"`) + enterEvent = true + + case DropEffectMove: + buffer.WriteString(` data-drop-effect="move" ondragenter="dragEnterEvent(this, event)"`) + enterEvent = true + + case DropEffectLink: + buffer.WriteString(` data-drop-effect="link" ondragenter="dragEnterEvent(this, event)"`) + enterEvent = true + } + + if enterEvent { + viewEventsHtml[DragAndDropEvent](view, []PropertyName{DragEndEvent, DragLeaveEvent}, buffer) + } else { + viewEventsHtml[DragAndDropEvent](view, []PropertyName{DragEndEvent, DragEnterEvent, DragLeaveEvent}, buffer) + } session := view.Session() if img, ok := stringProperty(view, DragImage, session); ok && img != "" { @@ -257,9 +428,9 @@ func dragAndDropHtml(view View, buffer *strings.Builder) { buffer.WriteString(`" `) } - effects := enumProperties[DragEffect].cssValues - if n := GetDragEffect(view); n > 0 && n < len(effects) { - buffer.WriteString(` data-drag-effect="`) + effects := []string{"undifined", "copy", "move", "copyMove", "link", "copyLink", "linkMove", "all"} + if n := GetDropEffectAllowed(view); n > 0 && n < len(effects) { + buffer.WriteString(` data-drop-effect-allowed="`) buffer.WriteString(effects[n]) buffer.WriteString(`" `) } @@ -326,21 +497,84 @@ func GetDragImageYOffset(view View, subviewID ...string) float64 { return floatStyledProperty(view, subviewID, DragImageYOffset, 0) } -// GetDragEffect returns the effect that is allowed for a drag operation. +// GetDropEffect returns the effect that is allowed for a drag operation. +// Controls the feedback (typically visual) the user is given during a drag and drop operation. +// It will affect which cursor is displayed while dragging. +// +// Returns one of next values: +// - 0 (DropEffectUndefined) - The value is not defined (all operations are permitted). +// - 1 (DropEffectCopy) - A copy of the source item may be made at the new location. +// - 2 (DropEffectMove) - An item may be moved to a new location. +// - 4 (DropEffectLink) - A link may be established to the source at the new location. +// +// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. +func GetDropEffect(view View, subviewID ...string) int { + if view = getSubview(view, subviewID); view != nil { + value := view.getRaw(DropEffect) + if value == nil { + value = valueFromStyle(view, DropEffect) + } + + if value != nil { + switch value := value.(type) { + case int: + return value + + case string: + if value, ok := view.Session().resolveConstants(value); ok { + if n, ok := stringToDropEffect(value); ok { + return n + } + } + + default: + return DropEffectUndefined + } + } + } + return DropEffectUndefined +} + +// GetDropEffectAllowed returns the effect that is allowed for a drag operation. // The copy operation is used to indicate that the data being dragged will be copied from its present location to the drop location. // The move operation is used to indicate that the data being dragged will be moved, // and the link operation is used to indicate that some form of relationship -// or connection will be created between the source and drop locations.. Returns one of next values: -// - 0 (DragEffectAll) or "all" - All operations are permitted (defaut value). -// - 1 (DragEffectCopy) or "copy" - A copy of the source item may be made at the new location. -// - 2 (DragEffectMove) or "move" - An item may be moved to a new location. -// - 3 (DragEffectLink) or "link" - A link may be established to the source at the new location. -// - 4 (DragEffectCopyMove) or "copyMove" - A copy or move operation is permitted. -// - 5 (DragEffectCopyLink) or "copyLink" - A copy or link operation is permitted. -// - 6 (DragEffectLinkMove) or "linkMove" - A link or move operation is permitted. -// - 7 (DragEffectNone) or "none" - The item may not be dropped. +// or connection will be created between the source and drop locations. +// +// Returns one of next values: +// - 0 (DropEffectUndefined) - The value is not defined (all operations are permitted). +// - 1 (DropEffectCopy) - A copy of the source item may be made at the new location. +// - 2 (DropEffectMove) - An item may be moved to a new location. +// - 4 (DropEffectLink) - A link may be established to the source at the new location. +// - 3 (DropEffectCopyMove) - A copy or move operation is permitted. +// - 5 (DropEffectCopyLink) - A copy or link operation is permitted. +// - 6 (DropEffectLinkMove) - A link or move operation is permitted. +// - 7 (DropEffectAll) - All operations are permitted. // // If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. -func GetDragEffect(view View, subviewID ...string) int { - return enumStyledProperty(view, subviewID, DragEffect, DragEffectAll, true) +func GetDropEffectAllowed(view View, subviewID ...string) int { + if view = getSubview(view, subviewID); view != nil { + value := view.getRaw(DropEffectAllowed) + if value == nil { + value = valueFromStyle(view, DropEffectAllowed) + } + + if value != nil { + switch value := value.(type) { + case int: + return value + + case string: + if value, ok := view.Session().resolveConstants(value); ok { + if n, ok := stringToDropEffectAllowed(value); ok { + return n + } + } + + default: + return DropEffectUndefined + } + } + } + return DropEffectUndefined } diff --git a/editView.go b/editView.go index 0b81faa..c65a783 100644 --- a/editView.go +++ b/editView.go @@ -261,9 +261,9 @@ func (edit *editViewData) AppendText(text string) { return } } - edit.setRaw(Text, text) + edit.Set(Text, text) } else { - edit.setRaw(Text, GetText(edit)+text) + edit.Set(Text, GetText(edit)+text) } } diff --git a/propertySet.go b/propertySet.go index a6eec7d..c788382 100644 --- a/propertySet.go +++ b/propertySet.go @@ -496,11 +496,6 @@ var enumProperties = map[PropertyName]enumPropertyData{ string(ColumnFill), []string{"balance", "auto"}, }, - DragEffect: { - []string{"all", "copy", "move", "link", "copyMove", "copyLink", "linkMove", "none"}, - "", - []string{"all", "copy", "move", "link", "copyMove", "copyLink", "linkMove", "none"}, - }, } func notCompatibleType(tag PropertyName, value any) { diff --git a/view.go b/view.go index 8adfbe1..a632583 100644 --- a/view.go +++ b/view.go @@ -479,6 +479,11 @@ func (view *viewData) setFunc(tag PropertyName, value any) []PropertyName { case DragStartEvent, DragEndEvent, DragEnterEvent, DragLeaveEvent, DragOverEvent, DropEvent: return setOneArgEventListener[View, DragAndDropEvent](view, tag, value) + case DropEffect: + return view.setDropEffect(value) + + case DropEffectAllowed: + return view.setDropEffectAllowed(value) } return viewStyleSet(view, tag, value) @@ -509,16 +514,16 @@ func (view *viewData) propertyChanged(tag PropertyName) { switch tag { case TabIndex: - if value, ok := intProperty(view, TabIndex, view.Session(), 0); ok { - session.updateProperty(view.htmlID(), "tabindex", strconv.Itoa(value)) + if value, ok := intProperty(view, TabIndex, session, 0); ok { + session.updateProperty(htmlID, "tabindex", strconv.Itoa(value)) } else if view.Focusable() { - session.updateProperty(view.htmlID(), "tabindex", "0") + session.updateProperty(htmlID, "tabindex", "0") } else { - session.updateProperty(view.htmlID(), "tabindex", "-1") + session.updateProperty(htmlID, "tabindex", "-1") } case Style, StyleDisabled: - session.updateProperty(view.htmlID(), "class", view.htmlClass(IsDisabled(view))) + session.updateProperty(htmlID, "class", view.htmlClass(IsDisabled(view))) case Disabled: tabIndex := GetTabIndex(view, htmlID) @@ -775,7 +780,7 @@ func (view *viewData) propertyChanged(tag PropertyName) { case PerspectiveOriginX, PerspectiveOriginY: x, y := GetPerspectiveOrigin(view) - session.updateCSSProperty(htmlID, "perspective-origin", transformOriginCSS(x, y, AutoSize(), view.Session())) + session.updateCSSProperty(htmlID, "perspective-origin", transformOriginCSS(x, y, AutoSize(), session)) case BackfaceVisible: if GetBackfaceVisible(view) { @@ -786,7 +791,7 @@ func (view *viewData) propertyChanged(tag PropertyName) { case TransformOriginX, TransformOriginY, TransformOriginZ: x, y, z := getTransformOrigin(view, session) - session.updateCSSProperty(htmlID, "transform-origin", transformOriginCSS(x, y, z, view.Session())) + session.updateCSSProperty(htmlID, "transform-origin", transformOriginCSS(x, y, z, session)) case Transform: css := "" @@ -813,7 +818,7 @@ func (view *viewData) propertyChanged(tag PropertyName) { if view.getRaw(DragStartEvent) != nil || view.getRaw(DragData) != nil { session.updateProperty(htmlID, "ondragstart", "dragStartEvent(this, event)") } else { - session.removeProperty(view.htmlID(), "ondragstart") + session.removeProperty(htmlID, "ondragstart") } case DropEvent: @@ -823,18 +828,18 @@ func (view *viewData) propertyChanged(tag PropertyName) { if view.getRaw(DragOverEvent) != nil { session.updateProperty(htmlID, "data-drag-over", "1") } else { - session.removeProperty(view.htmlID(), "data-drag-over") + session.removeProperty(htmlID, "data-drag-over") } } else { - session.removeProperty(view.htmlID(), "ondrop") - session.removeProperty(view.htmlID(), "ondragover") + session.removeProperty(htmlID, "ondrop") + session.removeProperty(htmlID, "ondragover") } case DragOverEvent: if view.getRaw(DragOverEvent) != nil { session.updateProperty(htmlID, "data-drag-over", "1") } else { - session.removeProperty(view.htmlID(), "data-drag-over") + session.removeProperty(htmlID, "data-drag-over") } case DragData: @@ -843,50 +848,66 @@ func (view *viewData) propertyChanged(tag PropertyName) { session.updateProperty(htmlID, "data-drag", data) session.updateProperty(htmlID, "ondragstart", "dragStartEvent(this, event)") } else { - session.removeProperty(view.htmlID(), "draggable") - session.removeProperty(view.htmlID(), "data-drag") + session.removeProperty(htmlID, "draggable") + session.removeProperty(htmlID, "data-drag") if view.getRaw(DragStartEvent) == nil { - session.removeProperty(view.htmlID(), "ondragstart") + session.removeProperty(htmlID, "ondragstart") } } case DragImage: - if img, ok := stringProperty(view, DragImage, view.session); ok && img != "" { + if img, ok := stringProperty(view, DragImage, session); ok && img != "" { img = strings.Trim(img, " \t") if img[0] == '@' { - img, ok = view.session.ImageConstant(img[1:]) + img, ok = session.ImageConstant(img[1:]) if !ok { - session.removeProperty(view.htmlID(), "data-drag-image") + session.removeProperty(htmlID, "data-drag-image") return } } session.updateProperty(htmlID, "data-drag-image", img) } else { - session.removeProperty(view.htmlID(), "data-drag-image") + session.removeProperty(htmlID, "data-drag-image") } case DragImageXOffset: if f := GetDragImageXOffset(view); f != 0 { session.updateProperty(htmlID, "data-drag-image-x", f) } else { - session.removeProperty(view.htmlID(), "data-drag-image-x") + session.removeProperty(htmlID, "data-drag-image-x") } case DragImageYOffset: if f := GetDragImageXOffset(view); f != 0 { session.updateProperty(htmlID, "data-drag-image-y", f) } else { - session.removeProperty(view.htmlID(), "data-drag-image-y") + session.removeProperty(htmlID, "data-drag-image-y") } - case DragEffect: - effects := enumProperties[DragEffect].cssValues - if n := GetDragEffect(view); n > 0 && n < len(effects) { - session.updateProperty(htmlID, "data-drag-effect", effects[n]) + case DropEffect: + effect := GetDropEffect(view) + switch effect { + case DropEffectCopy: + session.updateProperty(htmlID, "data-drop-effect", "copy") + case DropEffectMove: + session.updateProperty(htmlID, "data-drop-effect", "move") + case DropEffectLink: + session.updateProperty(htmlID, "data-drop-effect", "link") + default: + session.removeProperty(htmlID, "data-drop-effect") + } + + case DropEffectAllowed: + effect := GetDropEffectAllowed(view) + if effect >= DropEffectCopy && effect >= DropEffectAll { + values := []string{"undifined", "copy", "move", "copyMove", "link", "copyLink", "linkMove", "all"} + session.updateProperty(htmlID, "data-drop-effect-allowed", values[effect]) + } else { + session.removeProperty(htmlID, "data-drop-effect-allowed") } case DataList: - updateInnerHTML(view.htmlID(), view.Session()) + updateInnerHTML(htmlID, session) case Opacity: if f, ok := floatTextProperty(view, Opacity, session, 0); ok {