Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/jaspr/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## Unreleased patch

- Added `detachRootComponent()` to `ComponentsBinding` to cleanly unmount the root component.
- Updated `testClient` in `jaspr_test` to automatically unmount the root component and clean up `document.body` between test cases.

## 0.23.2

- Added `basePath` property to `AppBinding` to support hosting applications under a sub-path.
Expand Down
12 changes: 12 additions & 0 deletions packages/jaspr/lib/src/framework/components_binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ mixin ComponentsBinding on AppBinding {
buildOwner.performInitialBuild(element, completeInitialFrame);
}

/// Detaches the current root component from the tree and disposes/unmounts it.
void detachRootComponent() {
if (_rootElement != null) {
final buildOwner = _rootElement!._owner!;
buildOwner.lockState(() {
buildOwner._inactiveElements.add(_rootElement!);
buildOwner._inactiveElements._unmountAll();
});
_rootElement = null;
}
}

RenderObject createRootRenderObject();

BuildOwner createRootBuildOwner() {
Expand Down
5 changes: 5 additions & 0 deletions packages/jaspr/test/client/basic/basic_browser_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,10 @@ void main() {

expect(find.text('Count: 1'), findsOneComponent);
});

testClient('should clean up and unmount after previous test', (tester) async {
expect(find.text('Count: 0'), findsNothing);
expect(find.text('Count: 1'), findsNothing);
});
});
}
5 changes: 5 additions & 0 deletions packages/jaspr_router/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## Unreleased patch

- Added `dispose()` to the `HistoryManager` interface.
- Implemented `RouterState.dispose()` to cancel `onPopState` subscriptions when the router is unmounted.

## 0.8.3

- Fixed routing and redirect bug to respect the `<base href="...">` configuration by prepending `basePath` on client history operations, server redirect headers, and `Link` hrefs.
Expand Down
6 changes: 4 additions & 2 deletions packages/jaspr_router/lib/src/platform/platform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ abstract class PlatformRouter {
/// Interface for history management
/// Will be implemented separately on browser and server
abstract class HistoryManager {
/// Initialize the history manager and setup any listeners to history changes
void init(BuildContext context, {void Function(Object? state, {String? url})? onChangeState});
/// Initialize the history manager and setup any listeners to history changes.
///
/// Returns a callback that can be used to stop listening.
VoidCallback? init(BuildContext context, {void Function(Object? state, {String? url})? onChangeState});

/// Push a new state to the history
void push(String url, {String? title, Object? data});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ class HistoryManagerImpl implements HistoryManager {
}

@override
void init(BuildContext context, {void Function(Object? state, {String? url})? onChangeState}) {
VoidCallback? init(BuildContext context, {void Function(Object? state, {String? url})? onChangeState}) {
// No-op
return null;
}
}

Expand Down
7 changes: 5 additions & 2 deletions packages/jaspr_router/lib/src/platform/platform_web.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:js_interop';

import 'package:jaspr/jaspr.dart';
Expand All @@ -23,12 +24,14 @@ class PlatformRouterImpl implements PlatformRouter {
/// Accesses the window.history api
class HistoryManagerImpl implements HistoryManager {
@override
void init(BuildContext context, {void Function(Object? state, {String? url})? onChangeState}) {
VoidCallback? init(BuildContext context, {void Function(Object? state, {String? url})? onChangeState}) {
if (onChangeState != null) {
window.onPopState.listen((event) {
final subscription = window.onPopState.listen((event) {
onChangeState(window.history.state);
});
return subscription.cancel;
}
return null;
}

@override
Expand Down
10 changes: 9 additions & 1 deletion packages/jaspr_router/lib/src/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class RouterState extends State<Router> with PreloadStateMixin {
RouteMatchList get matchList => _matchList ?? RouteMatchList.empty;

Map<Object, RouteLoader> routeLoaders = {};
VoidCallback? _routeChangeDispose;

@override
Future<void> preloadState() async {
Expand All @@ -64,7 +65,7 @@ class RouterState extends State<Router> with PreloadStateMixin {
@override
void initState() {
super.initState();
PlatformRouter.instance.history.init(
_routeChangeDispose = PlatformRouter.instance.history.init(
context,
onChangeState: (state, {url}) {
_update(url ?? context.url, extra: state, updateHistory: false, replace: true);
Expand Down Expand Up @@ -223,6 +224,13 @@ class RouterState extends State<Router> with PreloadStateMixin {
return prefix + location;
}

@override
void dispose() {
_routeChangeDispose?.call();
_routeChangeDispose = null;
super.dispose();
}

@override
Component build(BuildContext context) {
return Component.fragment([
Expand Down
5 changes: 4 additions & 1 deletion packages/jaspr_router/test/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,12 @@ class MockHistoryManager implements HistoryManager {
late void Function(Object? state, {String? url})? onChangeState;

@override
void init(BuildContext context, {void Function(Object? state, {String? url})? onChangeState}) {
VoidCallback? init(BuildContext context, {void Function(Object? state, {String? url})? onChangeState}) {
history = [context.url];
this.onChangeState = onChangeState;
return () {
onChangeState = null;
};
}

@override
Expand Down
6 changes: 5 additions & 1 deletion packages/jaspr_test/lib/src/finders.dart
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,11 @@ abstract class Finder {
/// See [collectAllElementsFrom].
@protected
Iterable<Element> get allCandidates {
return collectAllElementsFrom(TestBinding.currentRootElement!);
final root = TestBinding.currentRootElement;
if (root == null) {
return const [];
}
return collectAllElementsFrom(root);
}

Iterable<Element>? _cachedResult;
Expand Down
8 changes: 5 additions & 3 deletions packages/jaspr_test/lib/src/testers/client_tester.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ void testClient(
final binding = ClientAppBinding();
final tester = ClientTester._(binding);

addTearDown(() {
binding.detachRootComponent();
web.document.body?.replaceChildren(<web.Node>[].toJS);
});

await binding.runTest(() async {
await callback(tester);
});

// Clear all nodes
web.document.body?.replaceChildren(<web.Node>[].toJS);
},
skip: skip,
timeout: timeout,
Expand Down
10 changes: 5 additions & 5 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,10 @@ packages:
dependency: transitive
description:
name: build_web_compilers
sha256: "3489d44e7a03b68f254c75d5db6dd6172fcbb892528275c3ed968f7e72ede716"
sha256: ef4bc35e0e335f8520692a333b872446697adce0618cf23c3084715ace641721
url: "https://pub.dev"
source: hosted
version: "4.8.4"
version: "4.8.5"
built_collection:
dependency: transitive
description:
Expand Down Expand Up @@ -1179,10 +1179,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: c82594181e3312f3d0695fc95aaaf7758d75b8d4ae2bbecf223b9fd5109a059d
sha256: "307249ce4ff29d58a18e97f6345f539382eb9c9c29ecda628900f31de0443dd9"
url: "https://pub.dev"
source: hosted
version: "1.18.3"
version: "1.19.0"
mime:
dependency: transitive
description:
Expand Down Expand Up @@ -2021,5 +2021,5 @@ packages:
source: hosted
version: "2.2.4"
sdks:
dart: ">=3.13.0-107.0.dev <3.13.0-z"
dart: ">=3.13.0-107.0.dev <3.14.0-z"
flutter: ">=3.44.0"
Loading