From 243d5f788950c433993dc80fdc797aa8523d4438 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 10 Nov 2020 16:27:54 +0530 Subject: [PATCH] feat(wip): clean routes, not hashes --- frappe/public/js/frappe/desk.js | 2 +- frappe/public/js/frappe/form/form.js | 2 +- frappe/public/js/frappe/router.js | 113 ++++++++++-------- frappe/public/js/frappe/ui/dialog.js | 11 ++ .../js/frappe/ui/toolbar/awesome_bar.js | 6 - frappe/public/js/frappe/views/container.js | 2 +- 6 files changed, 77 insertions(+), 59 deletions(-) diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js index 0e425abf25..153beabf3d 100644 --- a/frappe/public/js/frappe/desk.js +++ b/frappe/public/js/frappe/desk.js @@ -75,7 +75,7 @@ frappe.Application = Class.extend({ if (frappe.boot) { if (localStorage.getItem("session_last_route")) { - window.location.hash = localStorage.getItem("session_last_route"); + frappe.set_route(localStorage.getItem("session_last_route")); localStorage.removeItem("session_last_route"); } diff --git a/frappe/public/js/frappe/form/form.js b/frappe/public/js/frappe/form/form.js index 27de748c95..837fa09b1f 100644 --- a/frappe/public/js/frappe/form/form.js +++ b/frappe/public/js/frappe/form/form.js @@ -1007,7 +1007,7 @@ frappe.ui.form.Form = class FrappeForm { return; } - frappe.re_route[window.location.hash] = '#Form/' + encodeURIComponent(this.doctype) + '/' + encodeURIComponent(name); + frappe.re_route[frappe.get_sub_path()] = 'Form/' + encodeURIComponent(this.doctype) + '/' + encodeURIComponent(name); frappe.set_route('Form', this.doctype, name); } diff --git a/frappe/public/js/frappe/router.js b/frappe/public/js/frappe/router.js index 3c729f4af2..a4315ec359 100644 --- a/frappe/public/js/frappe/router.js +++ b/frappe/public/js/frappe/router.js @@ -13,39 +13,59 @@ frappe.view_factory = {}; frappe.view_factories = []; frappe.route_options = null; frappe.route_hooks = {}; +frappe._cur_route = null; + +$(window).on('hashchange', function() { + // save the title + + if (window.location.hash) { + console.log(window.location.hash); + let sub_path = frappe.get_sub_path(window.location.hash); + window.location.hash = ''; + frappe.push_state(sub_path); + } +}); frappe.route = function() { // Application is not yet initiated if (!frappe.app) return; - if(frappe.re_route[window.location.hash] !== undefined) { + let sub_path = frappe.get_route_str(); + + if (frappe.re_route[sub_path] !== undefined) { // after saving a doc, for example, // "New DocType 1" and the renamed "TestDocType", both exist in history // now if we try to go back, // it doesn't allow us to go back to the one prior to "New DocType 1" // Hence if this check is true, instead of changing location hash, // we just do a back to go to the doc previous to the "New DocType 1" - var re_route_val = frappe.get_route_str(frappe.re_route[window.location.hash]); - var cur_route_val = frappe.get_route_str(frappe._cur_route); - if (decodeURIComponent(re_route_val) === decodeURIComponent(cur_route_val)) { + var re_route_val = frappe.get_route_str(frappe.re_route[sub_path]); + if (decodeURIComponent(re_route_val) === decodeURIComponent(sub_path)) { window.history.back(); return; } else { - window.location.hash = frappe.re_route[window.location.hash]; + frappe.set_route(re_route_val); + return; } } - frappe._cur_route = window.location.hash; + frappe._cur_route = sub_path; - var route = frappe.get_route(); + let route = frappe.get_route(); if (route === false) { return; } frappe.route_history.push(route); - if(route[0]) { + // set title + frappe.route_titles[sub_path] = frappe._original_title || document.title; + + // hide open dialog + frappe.ui.hide_open_dialog(); + + if (route[0]) { const title_cased_route = frappe.utils.to_title_case(route[0]); if (title_cased_route === 'Workspace') { frappe.views.pageview.show(''); @@ -71,18 +91,17 @@ frappe.route = function() { } - if(frappe.route_titles[window.location.hash]) { - frappe.utils.set_title(frappe.route_titles[window.location.hash]); + if (frappe.route_titles[sub_path]) { + frappe.utils.set_title(frappe.route_titles[sub_path]); } else { setTimeout(function() { frappe.route_titles[frappe.get_route_str()] = frappe._original_title || document.title; }, 1000); } - if(window.mixpanel) { - window.mixpanel.track(route.slice(0, 2).join(' ')); - } -} + frappe.route.trigger('change'); + +}; frappe.get_route = function(route) { // for app @@ -91,7 +110,7 @@ frappe.get_route = function(route) { var parts = null; var doc_name = route[route.length - 1]; // if the last part contains ? then check if it is valid query string - if(doc_name.indexOf("?") < doc_name.indexOf("=")){ + if (doc_name.indexOf("?") < doc_name.indexOf("=")) { parts = doc_name.split("?"); route[route.length - 1] = parts[0]; } else { @@ -112,7 +131,7 @@ frappe.get_route = function(route) { } frappe.get_prev_route = function() { - if(frappe.route_history && frappe.route_history.length > 1) { + if (frappe.route_history && frappe.route_history.length > 1) { return frappe.route_history[frappe.route_history.length - 2]; } else { return []; @@ -122,7 +141,7 @@ frappe.get_prev_route = function() { frappe._decode_str = function(r) { try { return decodeURIComponent(r); - } catch(e) { + } catch (e) { if (e instanceof URIError) { return r; } else { @@ -132,30 +151,37 @@ frappe._decode_str = function(r) { } frappe.get_raw_route_str = function(route) { - if(!route) + if (!route) { route = window.location.hash; + } - if(route.substr(0,1)=='#') route = route.substr(1); - if(route.substr(0,1)=='!') route = route.substr(1); + if (!route && window.location.pathname.startsWith('/desk')) { + // route is without hash + route = window.location.pathname.substr(5); + } + + if (route.substr(0, 1)=='/') route = route.substr(1); + if (route.substr(0, 1)=='#') route = route.substr(1); + if (route.substr(0, 1)=='!') route = route.substr(1); return route; -} +}; -frappe.get_route_str = function(route) { +frappe.get_sub_path = frappe.get_route_str = function(route) { var rawRoute = frappe.get_raw_route_str(route); route = $.map(rawRoute.split('/'), frappe._decode_str).join('/'); return route; -} +}; frappe.set_route = function() { return new Promise(resolve => { var params = arguments; - if(params.length===1 && $.isArray(params[0])) { + if (params.length===1 && $.isArray(params[0])) { params = params[0]; } var route = $.map(params, function(a) { - if($.isPlainObject(a)) { + if ($.isPlainObject(a)) { frappe.route_options = a; return null; } else { @@ -174,18 +200,28 @@ frappe.set_route = function() { url.hash = route; window.location.replace(url); } else { - window.location.hash = route; + // + // window.location.hash = route; + + // routing v2 + frappe.push_state(route); } // Set favicon (app.js) frappe.provide('frappe.app'); frappe.app.set_favicon && frappe.app.set_favicon(); + setTimeout(() => { frappe.after_ajax && frappe.after_ajax(() => { resolve(); }); }, 100); }); +}; + +frappe.push_state = function (route) { + history.pushState(null, null, `/desk/${route}`); + frappe.route(); } frappe.set_re_route = function() { @@ -196,29 +232,6 @@ frappe.set_re_route = function() { frappe.has_route_options = function() { return Boolean(Object.keys(frappe.route_options || {}).length); -} - -frappe._cur_route = null; - -$(window).on('hashchange', function() { - // save the title - frappe.route_titles[frappe._cur_route] = frappe._original_title || document.title; - - if(window.location.hash==frappe._cur_route) - return; - - // hide open dialog - if(window.cur_dialog) { - if (!cur_dialog.minimizable) { - cur_dialog.hide(); - } else if (!cur_dialog.is_minimized) { - cur_dialog.toggle_minimize(); - } - } - - frappe.route(); - - frappe.route.trigger('change'); -}); +}; frappe.utils.make_event_emitter(frappe.route); diff --git a/frappe/public/js/frappe/ui/dialog.js b/frappe/public/js/frappe/ui/dialog.js index c8cef56420..bbed14730b 100644 --- a/frappe/public/js/frappe/ui/dialog.js +++ b/frappe/public/js/frappe/ui/dialog.js @@ -229,3 +229,14 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { this.header.find('.modal-title').toggleClass('cursor-pointer'); } }; + +frappe.ui.hide_open_dialog = () => { + // hide open dialog + if (window.cur_dialog) { + if (!cur_dialog.minimizable) { + cur_dialog.hide(); + } else if (!cur_dialog.is_minimized) { + cur_dialog.toggle_minimize(); + } + } +} diff --git a/frappe/public/js/frappe/ui/toolbar/awesome_bar.js b/frappe/public/js/frappe/ui/toolbar/awesome_bar.js index e11adcfb66..556e1fbb97 100644 --- a/frappe/public/js/frappe/ui/toolbar/awesome_bar.js +++ b/frappe/public/js/frappe/ui/toolbar/awesome_bar.js @@ -107,13 +107,7 @@ frappe.search.AwesomeBar = Class.extend({ if(item.onclick) { item.onclick(item.match); } else { - var previous_hash = window.location.hash; frappe.set_route(item.route); - - // hashchange didn't fire! - if (window.location.hash == previous_hash) { - frappe.route(); - } } $input.val(""); }); diff --git a/frappe/public/js/frappe/views/container.js b/frappe/public/js/frappe/views/container.js index a5227b4271..ae4aaba570 100644 --- a/frappe/public/js/frappe/views/container.js +++ b/frappe/public/js/frappe/views/container.js @@ -82,7 +82,7 @@ frappe.views.Container = Class.extend({ $(document).trigger("page-change"); - this.page._route = window.location.hash; + this.page._route = frappe.get_sub_path(); $(this.page).trigger('show'); !this.page.disable_scroll_to_top && frappe.utils.scroll_to(0); frappe.breadcrumbs.update();