Skip to content

Commit d8c2a6b

Browse files
committed
Merge branch 'main' into release/3.0
2 parents 749a978 + d317ba8 commit d8c2a6b

File tree

4 files changed

+38
-8
lines changed

4 files changed

+38
-8
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
_No unreleased changes_
1111

12+
## [3.0.0-pre23] - 2025-06-05
13+
14+
### Changed
15+
- Ensure old widgets are disposed when replaced by new ones by @TimLariviere in https://github.com/fabulous-dev/Fabulous/pull/1105
16+
1217
## [3.0.0-pre22] - 2025-05-18
1318

1419
### Changed
@@ -233,7 +238,8 @@ _No unreleased changes_
233238
### Changed
234239
- Fabulous.XamarinForms & Fabulous.MauiControls have been moved been out of the Fabulous repository. Find them in their own repositories: [https://github.com/fabulous-dev/Fabulous.XamarinForms](https://github.com/fabulous-dev/Fabulous.XamarinForms) / [https://github.com/fabulous-dev/Fabulous.MauiControls](https://github.com/fabulous-dev/Fabulous.MauiControls)
235240

236-
[unreleased]: https://github.com/fabulous-dev/Fabulous/compare/3.0.0-pre22...HEAD
241+
[unreleased]: https://github.com/fabulous-dev/Fabulous/compare/3.0.0-pre23...HEAD
242+
[3.0.0-pre23]: https://github.com/fabulous-dev/Fabulous/releases/tag/3.0.0-pre23
237243
[3.0.0-pre22]: https://github.com/fabulous-dev/Fabulous/releases/tag/3.0.0-pre22
238244
[3.0.0-pre21]: https://github.com/fabulous-dev/Fabulous/releases/tag/3.0.0-pre21
239245
[3.0.0-pre20]: https://github.com/fabulous-dev/Fabulous/releases/tag/3.0.0-pre20

src/Fabulous/Attributes.fs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,19 @@ module Attributes =
193193

194194
childNode.ApplyDiff(&diff)
195195

196-
let updateNode _ (newValueOpt: Widget voption) (node: IViewNode) =
196+
let updateNode (oldValueOpt: Widget voption) (newValueOpt: Widget voption) (node: IViewNode) =
197+
if oldValueOpt.IsSome then
198+
// Dispose the existing child if it exists
199+
let childView = get node.Target
200+
201+
if not(isNull childView) then
202+
let childNode = node.TreeContext.GetViewNode(childView)
203+
childNode.Dispose()
204+
197205
match newValueOpt with
198206
| ValueNone -> set node.Target null
199207
| ValueSome widget ->
200208
let struct (_, view) = Helpers.createViewForWidget node widget
201-
202209
set node.Target (unbox view)
203210

204211
defineWidget name applyDiff updateNode
@@ -255,8 +262,21 @@ module Attributes =
255262

256263
| _ -> ()
257264

258-
let updateNode _ (newValueOpt: ArraySlice<Widget> voption) (node: IViewNode) =
265+
let updateNode (oldValueOpt: ArraySlice<Widget> voption) (newValueOpt: ArraySlice<Widget> voption) (node: IViewNode) =
259266
let targetColl = getCollection node.Target
267+
268+
if oldValueOpt.IsSome then
269+
// Dispose the existing children if they exist
270+
let oldWidgets = oldValueOpt.Value
271+
let span = ArraySlice.toSpan oldWidgets
272+
273+
for index = 0 to span.Length do
274+
let childView = box targetColl[index]
275+
276+
if not(isNull childView) then
277+
let childNode = node.TreeContext.GetViewNode(childView)
278+
childNode.Dispose()
279+
260280
targetColl.Clear()
261281

262282
match newValueOpt with

src/Fabulous/ViewNode.fs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,16 @@ type ViewNode =
8181
member inline private this.ApplyWidgetDiffs(diffs: WidgetChanges inref) =
8282
for diff in diffs do
8383
match diff with
84-
| WidgetChange.Added newWidget
85-
| WidgetChange.ReplacedBy newWidget ->
84+
| WidgetChange.Added newWidget ->
8685
let definition = (AttributeDefinitionStore.getWidget newWidget.Key)
8786

8887
definition.UpdateNode ValueNone (ValueSome newWidget.Value) (this :> IViewNode)
8988

89+
| WidgetChange.ReplacedBy(oldWidget, newWidget) ->
90+
let definition = (AttributeDefinitionStore.getWidget newWidget.Key)
91+
92+
definition.UpdateNode (ValueSome oldWidget.Value) (ValueSome newWidget.Value) (this :> IViewNode)
93+
9094
| WidgetChange.Removed removed ->
9195
let definition = (AttributeDefinitionStore.getWidget removed.Key)
9296

src/Fabulous/WidgetDiff.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ and [<Struct; RequireQualifiedAccess>] WidgetChange =
8383
| Added of widget: WidgetAttribute
8484
| Removed of widget: WidgetAttribute
8585
| Updated of widget: WidgetAttribute * diff: WidgetDiff // updated * diff
86-
| ReplacedBy of widget: WidgetAttribute
86+
| ReplacedBy of oldWidget: WidgetAttribute * newWidget: WidgetAttribute
8787

8888
and [<Struct; RequireQualifiedAccess>] WidgetCollectionChange =
8989
| Added of attr: WidgetCollectionAttribute
@@ -395,7 +395,7 @@ and [<Struct; IsByRefLike>] WidgetChangesEnumerator
395395

396396
WidgetChange.Updated(nextAttr, diff)
397397
else
398-
WidgetChange.ReplacedBy nextAttr
398+
WidgetChange.ReplacedBy(prevAttr, nextAttr)
399399

400400
e.current <- change
401401
res <- ValueSome true

0 commit comments

Comments
 (0)