Repository: maxence-charriere/go-app (language: go)

Issue:
Raw can't be updated
SVG in app.Raw() will not change after click the button twice.
```go

var Demo2 = func() func() app.UI {
	return func() app.UI {
		return &Button{}
	}
}()

type Button struct {
	app.Compo
	state bool
}

func (this *Button) Render() app.UI {
	const (
		raw1 = `<svg width="16px" height="16px" viewBox="0 0 1024 1024"><path d="M872 474H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h720c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"/></svg>`
		raw2 = `<svg width="16px" height="16px" viewBox="0 0 1024 1024"><path d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8Z"/><path d="M192 474h672q8 0 8 8v60q0 8-8 8H160q-8 0-8-8v-60q0-8 8-8Z"/></svg>`
	)
	return app.Button().Type("button").
		Body(
			app.If(this.state, func() app.UI {
				return app.Raw(raw1)
			}).Else(func() app.UI {
				return app.Raw(raw2)
			}),
			app.Span().Text(fmt.Sprintf("Click me [%v]", this.state)),
		).
		OnClick(func(ctx app.Context, e app.Event) {
			this.state = !this.state
			log.Log(this.state)
		})
}

```


Discussion / hints:
I wonder what will happen if you use (as I probably would):

```
app.Raw(func(b bool) string {
	if b {
		return raw1
	} else {
		return raw2
	}
}(this.state))
```
@maxence-charriere I tried that, and it looks like `app.Raw()` is kinda broken. It does not update and I think it should. Even if using `<div>1</div>` and `<div>2</div>` as the two raw strings and also when using same `app.Raw()` with switching the strings or two different `app.Raw()` as the original example.

@gepengscu We actually avoid using `app.Raw()` in our projects. You can solve that by using custom elements for the SVG like so:

```go
app.Button().Type("button").
	Body(
		app.If(uc.state, func() app.UI {
			return app.Elem("svg").XMLNS("http://www.w3.org/2000/svg").
				Attr("height", "16px").
				Attr("width", "16px").
				Attr("viewBox", "0 0 1024 1024").
				Body(
					app.ElemSelfClosing("path").XMLNS("http://www.w3.org/2000/svg").
						Attr("d", "M872 474H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h720c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"),
				)
		}).Else(func() app.UI {
			return app.Elem("svg").XMLNS("http://www.w3.org/2000/svg").
				Attr("height", "16px").
				Attr("width", "16px").
				Attr("viewBox", "0 0 1024 1024").
				Body(
					app.ElemSelfClosing("path").XMLNS("http://www.w3.org/2000/svg").
						Attr("d", "M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8Z"),
					app.ElemSelfClosing("path").XMLNS("http://www.w3.org/2000/svg").
						Attr("d", "M192 474h672q8 0 8 8v60q0 8-8 8H160q-8 0-8-8v-60q0-8 8-8Z"),
				)
		}),
		app.Span().Text(fmt.Sprintf("Click me [%v]", uc.state)),
	).
	OnClick(func(ctx app.Context, e app.Event) {
		uc.state = !uc.state
		app.Log(uc.state)
	})
```
@oderwat @maxence-charriere  The raw.parent() is nil after raw mounted to DOM. Add ```newMount.setParent(parent) ``` in  nodeManager.updateRawHTML  of "node.go" can solve the problem.
```go

func (m nodeManager) updateRawHTML(ctx Context, v, new *raw) (UI, error) {
	if v.value == new.value {
		return v, nil
	}
	newMount, err := m.Mount(ctx, v.depth(), new)
	if err != nil {
		return nil, errors.New("mounting updated raw html failed").
			WithTag("type", reflect.TypeOf(v)).
			WithTag("depth", v.depth()).
			WithTag("raw-preview", previewText(v.value)).
			Wrap(err)
	}
	for parent := v.parent(); parent != nil; parent = parent.parent() {
		if parent, isHTML := parent.(HTML); isHTML {
			parent.JSValue().replaceChild(newMount, v)
			newMount.setParent(parent)   <----- set parent here
			break
		}
	}
	m.Dismount(v)
	return newMount, nil
}

```

Fix patch:
diff --git a/pkg/app/node.go b/pkg/app/node.go
index e17e2e49..03591ef4 100644
--- a/pkg/app/node.go
+++ b/pkg/app/node.go
@@ -605,6 +605,7 @@ func (m nodeManager) updateRawHTML(ctx Context, v, new *raw) (UI, error) {
 	for parent := v.parent(); parent != nil; parent = parent.parent() {
 		if parent, isHTML := parent.(HTML); isHTML {
 			parent.JSValue().replaceChild(newMount, v)
+			newMount.setParent(parent)
 			break
 		}
 	}


Test patch:
diff --git a/pkg/app/node_test.go b/pkg/app/node_test.go
index 788906b1..bba164ac 100644
--- a/pkg/app/node_test.go
+++ b/pkg/app/node_test.go
@@ -841,6 +841,7 @@ func TestNodeManagerUpdate(t *testing.T) {
 		require.IsType(t, Raw(""), newSpan)
 		require.Equal(t, "<span>bye</span>", newSpan.(*raw).value)
 		require.True(t, newSpan.Mounted())
+		require.Equal(t, body, newSpan.parent())
 		require.False(t, span.Mounted())
 	})