diff --git a/cypress/integration/navigation.js b/cypress/integration/navigation.js new file mode 100644 index 0000000000..3fe12f3547 --- /dev/null +++ b/cypress/integration/navigation.js @@ -0,0 +1,15 @@ +context('Navigation', () => { + before(() => { + cy.login(); + cy.visit('/app/website'); + }); + it('Navigate to route with hash in document name', () => { + cy.insert_doc('ToDo', {'__newname': 'ABC#123', 'description': 'Test this', 'ignore_duplicate': true}); + cy.visit('/app/todo/ABC#123'); + cy.title().should('eq', 'Test this - ABC#123'); + cy.get_field('description', 'Text Editor').contains('Test this'); + cy.go('back'); + cy.title().should('eq', 'Website'); + cy.remove_doc('ToDo', 'ABC#123'); + }); +}); \ No newline at end of file diff --git a/frappe/public/js/frappe/router.js b/frappe/public/js/frappe/router.js index 1e04c84482..3f8ce7fee2 100644 --- a/frappe/public/js/frappe/router.js +++ b/frappe/public/js/frappe/router.js @@ -14,11 +14,10 @@ frappe.view_factories = []; frappe.route_options = null; frappe.route_hooks = {}; -$(window).on('hashchange', function() { +$(window).on('hashchange', function(e) { // v1 style routing, route is in hash - if (window.location.hash) { + if (window.location.hash && !frappe.router.is_app_route(e.currentTarget.pathname)) { let sub_path = frappe.router.get_sub_path(window.location.hash); - window.location.hash = ''; frappe.router.push_state(sub_path); return false; } @@ -48,18 +47,18 @@ $('body').on('click', 'a', function(e) { return; } - if (href==='') { + if (href === '') { return override('/app'); } - // target has "#" ,this is a v1 style route, so remake it. - if (e.currentTarget.hash) { + if (href.startsWith('#')) { + // target startswith "#", this is a v1 style route, so remake it. return override(e.currentTarget.hash); } - // target has "/app, this is a v2 style route. - if (e.currentTarget.pathname && frappe.router.is_app_route(e.currentTarget.pathname)) { - return override(e.currentTarget.pathname); + if (frappe.router.is_app_route(e.currentTarget.pathname)) { + // target has "/app, this is a v2 style route. + return override(e.currentTarget.pathname + e.currentTarget.hash); } }); @@ -355,8 +354,6 @@ frappe.router = { push_state(url) { // change the URL and call the router if (window.location.pathname !== url) { - // cleanup any remenants of v1 routing - window.location.hash = ''; // push state so the browser looks fine history.pushState(null, null, url); @@ -370,7 +367,11 @@ frappe.router = { // return clean sub_path from hash or url // supports both v1 and v2 routing if (!route) { - route = window.location.hash || (window.location.pathname + window.location.search); + route = window.location.pathname + window.location.hash + window.location.search; + if (route.includes('app#')) { + // to support v1 + route = window.location.hash; + } } return this.strip_prefix(route);