diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js
index d14b086405..8d738019a5 100644
--- a/frappe/public/js/frappe/list/list_view.js
+++ b/frappe/public/js/frappe/list/list_view.js
@@ -1098,17 +1098,20 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
if (
$target.hasClass("filterable") ||
$target.hasClass("icon-heart") ||
- $target.is(":checkbox") ||
- $target.is("a")
+ $target.is(":checkbox")
) {
e.stopPropagation();
return;
}
- // open form
+
+ // link, let the event be handled via set_route
+ if ($target.is("a")) { return; }
+
+ // clicked on the row, open form
const $row = $(e.currentTarget);
const link = $row.find(".list-subject a").get(0);
if (link) {
- window.location.href = link.href;
+ frappe.set_route(link.pathname);
return false;
}
});
diff --git a/frappe/public/js/frappe/router.js b/frappe/public/js/frappe/router.js
index 7b1ffba5ce..a4e8bc081f 100644
--- a/frappe/public/js/frappe/router.js
+++ b/frappe/public/js/frappe/router.js
@@ -24,37 +24,41 @@ $(window).on('hashchange', function() {
}
});
-window.addEventListener('popstate', () => {
+window.addEventListener('popstate', (e) => {
// forward-back button, just re-render based on current route
frappe.router.route();
+ e.preventDefault();
+ return false;
});
// routing v2, capture all clicks so that the target is managed with push-state
$('body').on('click', 'a', function(e) {
- let override = (e, route) => {
+ let override = (route) => {
e.preventDefault();
frappe.set_route(route);
return false;
};
// click handled, but not by href
- if (e.currentTarget.getAttribute('onclick')) return;
+ if (e.currentTarget.getAttribute('onclick')) {
+ return;
+ }
const href = e.currentTarget.getAttribute('href');
if (href==='#') return;
if (href==='') {
- return override(e, '/app');
+ return override('/app');
}
// target has "#" ,this is a v1 style route, so remake it.
if (e.currentTarget.hash) {
- return override(e, e.currentTarget.hash);
+ return override(e.currentTarget.hash);
}
// target has "/app, this is a v2 style route.
- if (e.currentTarget.pathname && frappe.router.is_app_route()) {
- return override(e, e.currentTarget.pathname);
+ if (e.currentTarget.pathname && frappe.router.is_app_route(e.currentTarget.pathname)) {
+ return override(e.currentTarget.pathname);
}
});
@@ -65,9 +69,8 @@ frappe.router = {
list_views: ['list', 'kanban', 'report', 'calendar', 'tree', 'gantt', 'dashboard', 'image', 'inbox'],
layout_mapped: {},
- is_app_route() {
+ is_app_route(path) {
// desk paths must begin with /app or doctype route
- let path = window.location.pathname;
if (path.substr(0, 1) === '/') path = path.substr(1);
path = path.split('/');
if (path[0]) {
diff --git a/frappe/www/app.py b/frappe/www/app.py
index d65c483bdd..6a5139aa62 100644
--- a/frappe/www/app.py
+++ b/frappe/www/app.py
@@ -34,7 +34,10 @@ def get_context(context):
boot_json = frappe.as_json(boot)
# remove script tags from boot
- boot_json = re.sub("\", "", boot_json)
+ boot_json = re.sub("\", "", boot_json)
context.update({
"no_cache": 1,