Skip to content

Commit 08995d6

Browse files
committed
fix: fix hash changes from location.href.
1 parent a0878d5 commit 08995d6

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

integration_tests/specs/navigator/history.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,35 @@ describe('history API', () => {
6464
history.go(-1);
6565
});
6666
});
67+
68+
it('hashchange should fire when history back', (done) => {
69+
expect(location.pathname).toBe('/public/core.build.js');
70+
history.pushState({name: 2}, '', '#/page_1');
71+
function onHashChange(e: HashChangeEvent) {
72+
expect(new URL(e.oldURL).hash).toBe('#/page_1');
73+
expect(new URL(e.newURL).hash).toBe('#hash=hashValue');
74+
window.removeEventListener('hashchange', onHashChange);
75+
done();
76+
}
77+
window.addEventListener('hashchange', onHashChange);
78+
requestAnimationFrame(() => {
79+
history.back();
80+
});
81+
});
82+
83+
it('hashchange when go back should work', (done) => {
84+
expect(location.pathname).toBe('/public/core.build.js');
85+
history.replaceState({name: 0}, '');
86+
history.pushState({name: 2}, '', '#/page_1');
87+
function onHashChange(e: HashChangeEvent) {
88+
expect(new URL(e.oldURL).hash).toBe('#/page_1');
89+
expect(new URL(e.newURL).hash).toBe('#hash=hashValue');
90+
window.removeEventListener('popstate', onHashChange);
91+
done();
92+
}
93+
window.addEventListener('hashchange', onHashChange);
94+
requestAnimationFrame(() => {
95+
history.go(-1);
96+
});
97+
});
6798
});

webf/lib/src/launcher/controller.dart

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,9 +687,24 @@ class WebFViewController implements WidgetsBindingObserver {
687687
WebFNavigationActionPolicy policy = await _delegate.dispatchDecisionHandler(action);
688688
if (policy == WebFNavigationActionPolicy.cancel) return;
689689

690+
String targetPath = action.target;
691+
692+
if (!Uri.parse(targetPath).isAbsolute) {
693+
String base = rootController.url;
694+
targetPath = rootController.uriParser!.resolve(Uri.parse(base), Uri.parse(targetPath)).toString();
695+
}
696+
697+
if (action.target.trim().startsWith('#')) {
698+
String oldUrl = rootController.url;
699+
HistoryModule historyModule = rootController.module.moduleManager.getModule('History')!;
700+
historyModule.pushState(null, url: targetPath);
701+
window.dispatchEvent(HashChangeEvent(newUrl: targetPath, oldUrl: oldUrl));
702+
return;
703+
}
704+
690705
switch (action.navigationType) {
691706
case WebFNavigationType.navigate:
692-
await rootController.load(rootController.getPreloadBundleFromUrl(action.target) ?? WebFBundle.fromUrl(action.target));
707+
await rootController.load(rootController.getPreloadBundleFromUrl(targetPath) ?? WebFBundle.fromUrl(targetPath));
693708
break;
694709
case WebFNavigationType.reload:
695710
await rootController.reload();

webf/lib/src/module/history.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,19 @@ class HistoryModule extends BaseModule {
7070
_nextStack.removeFirst();
7171
_previousStack.addFirst(currentItem);
7272
_dispatchPopStateEvent(currentItem.state);
73+
74+
String previousUrl = currentItem.bundle.url;
75+
if (_isFragmentItem(currentItem)) {
76+
_dispatchHashChangeEvent(previousUrl, _previousStack.first.bundle.url);
77+
}
7378
}
7479
}
7580

7681
void go(num? num) {
7782
num ??= 0;
83+
84+
HistoryItem currentItem = _previousStack.first;
85+
7886
if (num >= 0) {
7987
if (_nextStack.length < num) {
8088
return;
@@ -98,6 +106,9 @@ class HistoryModule extends BaseModule {
98106
}
99107

100108
_dispatchPopStateEvent(_previousStack.first.state);
109+
if (_isFragmentItem(currentItem)) {
110+
_dispatchHashChangeEvent(currentItem.bundle.url, _previousStack.first.bundle.url);
111+
}
101112
}
102113

103114
void _dispatchPopStateEvent(state) {

0 commit comments

Comments
 (0)