diff --git a/kraken/lib/src/css/overflow.dart b/kraken/lib/src/css/overflow.dart index 260a548cc8..9cac7e674d 100644 --- a/kraken/lib/src/css/overflow.dart +++ b/kraken/lib/src/css/overflow.dart @@ -105,6 +105,11 @@ mixin ElementOverflowMixin on ElementBase { KrakenScrollable? _scrollableX; KrakenScrollable? _scrollableY; + void disposeScrolling() { + _scrollableX = null; + _scrollableY = null; + } + void updateRenderBoxModelWithOverflowX(ScrollListener scrollListener) { if (renderBoxModel is RenderSliverListLayout) { RenderSliverListLayout renderBoxModel = this.renderBoxModel as RenderSliverListLayout; @@ -147,7 +152,7 @@ mixin ElementOverflowMixin on ElementBase { } renderBoxModel.scrollListener = scrollListener; - renderBoxModel.pointerListener = _pointerListener; + renderBoxModel.scrollPointerListener = _scrollPointerListener; if (renderBoxModel is RenderLayoutBox) { if (shouldScrolling) { @@ -199,7 +204,7 @@ mixin ElementOverflowMixin on ElementBase { } renderBoxModel.scrollListener = scrollListener; - renderBoxModel.pointerListener = _pointerListener; + renderBoxModel.scrollPointerListener = _scrollPointerListener; if (renderBoxModel is RenderLayoutBox) { if (shouldScrolling) { @@ -214,7 +219,7 @@ mixin ElementOverflowMixin on ElementBase { void scrollingContentBoxStyleListener(String property, String? original, String present) { RenderLayoutBox scrollingContentBox = (renderBoxModel as RenderLayoutBox).renderScrollingContent!; RenderStyle scrollingContentRenderStyle = scrollingContentBox.renderStyle; - + switch (property) { case DISPLAY: scrollingContentRenderStyle.display = renderStyle.display; @@ -334,7 +339,7 @@ mixin ElementOverflowMixin on ElementBase { outerLayoutBox.addAll(children); } - void _pointerListener(PointerEvent event) { + void _scrollPointerListener(PointerEvent event) { if (event is PointerDownEvent) { if (_scrollableX != null) { _scrollableX!.handlePointerDown(event); diff --git a/kraken/lib/src/dom/element.dart b/kraken/lib/src/dom/element.dart index cdcc522d12..3e1a543116 100644 --- a/kraken/lib/src/dom/element.dart +++ b/kraken/lib/src/dom/element.dart @@ -412,6 +412,9 @@ class Element extends Node // Remove renderBox. _removeRenderBoxModel(renderBoxModel!); + + // Remove pointer listener + removeEventResponder(renderBoxModel!); } @override @@ -555,6 +558,7 @@ class Element extends Node renderStyle.detach(); style.dispose(); properties.clear(); + disposeScrolling(); super.dispose(); } @@ -1703,8 +1707,8 @@ bool _hasIntersectionObserverEvent(Map eventHandlers) { void _detachRenderBoxModel(RenderBox renderBox) { if (renderBox.parent == null) return; + // Remove reference from parent RenderObject? parentRenderObject = renderBox.parent as RenderObject; - if (parentRenderObject is RenderObjectWithChildMixin) { parentRenderObject.child = null; // RenderViewportBox } else if (parentRenderObject is ContainerRenderObjectMixin) { diff --git a/kraken/lib/src/dom/event_handler.dart b/kraken/lib/src/dom/event_handler.dart index 4903d21c03..2359bb6413 100644 --- a/kraken/lib/src/dom/event_handler.dart +++ b/kraken/lib/src/dom/event_handler.dart @@ -37,6 +37,7 @@ mixin ElementEventMixin on EventTarget { renderBox.onLongPress = null; renderBox.getEventTarget = null; renderBox.dispatchEvent = null; + renderBox.getEventHandlers = null; } EventTarget getEventTarget() { diff --git a/kraken/lib/src/gesture/scrollable.dart b/kraken/lib/src/gesture/scrollable.dart index 3f13ecb11e..af4d15149c 100644 --- a/kraken/lib/src/gesture/scrollable.dart +++ b/kraken/lib/src/gesture/scrollable.dart @@ -239,7 +239,14 @@ class KrakenScrollable with _CustomTickerProviderStateMixin implements ScrollCon mixin RenderOverflowMixin on RenderBox { ScrollListener? scrollListener; - void Function(PointerEvent)? pointerListener; + void Function(PointerEvent)? scrollPointerListener; + + void disposeScroll() { + scrollListener = null; + scrollPointerListener = null; + _scrollOffsetX = null; + _scrollOffsetY = null; + } bool _clipX = false; bool get clipX => _clipX; diff --git a/kraken/lib/src/rendering/box_model.dart b/kraken/lib/src/rendering/box_model.dart index 113e88c919..b6aa5dc86e 100644 --- a/kraken/lib/src/rendering/box_model.dart +++ b/kraken/lib/src/rendering/box_model.dart @@ -172,6 +172,14 @@ class RenderLayoutBox extends RenderBoxModel } } + @override + void dispose() { + super.dispose(); + + paintingOrder.clear(); + stickyChildren.clear(); + } + @override void markNeedsLayout() { super.markNeedsLayout(); @@ -682,7 +690,7 @@ class RenderBoxModel extends RenderBox // Copy overflow ..scrollListener = scrollListener - ..pointerListener = pointerListener + ..scrollPointerListener = scrollPointerListener ..clipX = clipX ..clipY = clipY ..enableScrollX = enableScrollX @@ -1304,17 +1312,32 @@ class RenderBoxModel extends RenderBox renderStyle.backgroundAttachment == CSSBackgroundAttachmentType.local; } + void _detachAllChildren() { + if (this is RenderObjectWithChildMixin) { + (this as RenderObjectWithChildMixin).child = null; + } else if (this is ContainerRenderObjectMixin) { + (this as ContainerRenderObjectMixin).removeAll(); + } + } + /// Called when its corresponding element disposed + @mustCallSuper void dispose() { // Clear renderObjects in list when disposed to avoid memory leak if (fixedChildren.isNotEmpty) { fixedChildren.clear(); } + // Dispose scroll behavior + disposeScroll(); + // Dispose box decoration painter. disposePainter(); // Evict render decoration image cache. renderStyle.decoration?.image?.image.evict(); + + // Remove reference from childs + _detachAllChildren(); } Offset getTotalScrollOffset() { @@ -1428,8 +1451,8 @@ class RenderBoxModel extends RenderBox @override void handleEvent(PointerEvent event, HitTestEntry entry) { super.handleEvent(event, entry); - if (pointerListener != null) { - pointerListener!(event); + if (scrollPointerListener != null) { + scrollPointerListener!(event); } } diff --git a/kraken/lib/src/rendering/flex.dart b/kraken/lib/src/rendering/flex.dart index 1ede6f5b4b..b7346aa1e0 100644 --- a/kraken/lib/src/rendering/flex.dart +++ b/kraken/lib/src/rendering/flex.dart @@ -197,6 +197,15 @@ class RenderFlexLayout extends RenderLayoutBox { return CSSFlex.isHorizontalFlexDirection(renderStyle.flexDirection); } + @override + void dispose() { + super.dispose(); + + flexLineBoxMetrics.clear(); + childrenIntrinsicMainSizes.clear(); + childrenOldConstraints.clear(); + } + double _getIntrinsicSize({ FlexDirection? sizingDirection, double? diff --git a/kraken/lib/src/rendering/flow.dart b/kraken/lib/src/rendering/flow.dart index de277fd1f7..99a33e4e79 100644 --- a/kraken/lib/src/rendering/flow.dart +++ b/kraken/lib/src/rendering/flow.dart @@ -175,6 +175,13 @@ class RenderFlowLayout extends RenderLayoutBox { /// Line boxes of flow layout List<_RunMetrics> lineBoxMetrics = <_RunMetrics>[]; + @override + void dispose() { + super.dispose(); + + lineBoxMetrics.clear(); + } + @override void setupParentData(RenderBox child) { if (child.parentData is! RenderLayoutParentData) { diff --git a/kraken/lib/src/rendering/sliver_list.dart b/kraken/lib/src/rendering/sliver_list.dart index 8fb6eca051..3fb71fc896 100644 --- a/kraken/lib/src/rendering/sliver_list.dart +++ b/kraken/lib/src/rendering/sliver_list.dart @@ -42,7 +42,7 @@ class RenderSliverListLayout extends RenderLayoutBox { }) : _renderSliverBoxChildManager = manager, _scrollListener = onScroll, super(renderStyle: renderStyle) { - pointerListener = _pointerListener; + scrollPointerListener = _scrollPointerListener; scrollable = KrakenScrollable(axisDirection: getAxisDirection(axis)); axis = renderStyle.sliverDirection; @@ -121,7 +121,7 @@ class RenderSliverListLayout extends RenderLayoutBox { } } - void _pointerListener(PointerEvent event) { + void _scrollPointerListener(PointerEvent event) { if (event is PointerDownEvent) { scrollable.handlePointerDown(event); }