Fix and improved hasher routing

This commit is contained in:
the-djmaze 2022-03-03 16:28:05 +01:00
parent 06e2dc722d
commit fafe56ecb4
16 changed files with 41 additions and 83 deletions

View file

@ -78,7 +78,7 @@ class AppUser extends AbstractApp {
const currentTime = Date.now(); const currentTime = Date.now();
if (currentTime > (lastTime + interval + 1000)) { if (currentTime > (lastTime + interval + 1000)) {
Remote.request('Version', Remote.request('Version',
iError => (100 < iError) && this.reload(), iError => (100 < iError) && (Settings.app('inIframe') ? parent : window).location.reload(),
{ Version: Settings.app('version') } { Version: Settings.app('version') }
); );
} }
@ -91,10 +91,6 @@ class AppUser extends AbstractApp {
shortcuts.add('escape,enter', '', () => rl.Dropdowns.detectVisibility()); shortcuts.add('escape,enter', '', () => rl.Dropdowns.detectVisibility());
} }
reload() {
(Settings.app('inIframe') ? parent : window).location.reload();
}
/** /**
* @param {number} iDeleteType * @param {number} iDeleteType
* @param {string} sFromFolderFullName * @param {string} sFromFolderFullName

View file

@ -2,7 +2,6 @@ import { pString, pInt } from 'Common/Utils';
import { Settings } from 'Common/Globals'; import { Settings } from 'Common/Globals';
const const
ROOT = './',
HASH_PREFIX = '#/', HASH_PREFIX = '#/',
SERVER_PREFIX = './?', SERVER_PREFIX = './?',
VERSION = Settings.app('version'), VERSION = Settings.app('version'),
@ -24,7 +23,7 @@ export const
/** /**
* @returns {string} * @returns {string}
*/ */
logoutLink = () => adminPath() ? prefix() : ROOT, logoutLink = () => adminPath() ? prefix() : './',
/** /**
* @param {string} type * @param {string} type

View file

@ -173,7 +173,7 @@ const
// Close all popups // Close all popups
for (let vm of visiblePopups) { for (let vm of visiblePopups) {
vm.closeCommand(); false === vm.onClose() || vm.closeCommand();
} }
if (screenName) { if (screenName) {

View file

@ -85,7 +85,7 @@ export class AbstractSettingsScreen extends AbstractScreen {
}, 1); }, 1);
} }
} else { } else {
rl.route.setHash(settings(), false, true); hasher.replaceHash(settings());
} }
} }

View file

@ -31,7 +31,12 @@ import { SettingsUserStore } from 'Stores/User/Settings';
import Remote from 'Remote/User/Fetch'; import Remote from 'Remote/User/Fetch';
const const
isChecked = item => item.checked(); isChecked = item => item.checked(),
replaceHash = hash => {
rl.route.off();
hasher.replaceHash(hash);
rl.route.on();
}
export const MessagelistUserStore = ko.observableArray().extend({ debounce: 0 }); export const MessagelistUserStore = ko.observableArray().extend({ debounce: 0 });
@ -69,7 +74,7 @@ addComputablesTo(MessagelistUserStore, {
mainSearch: { mainSearch: {
read: MessagelistUserStore.listSearch, read: MessagelistUserStore.listSearch,
write: value => rl.route.setHash( write: value => hasher.setHash(
mailBox(FolderUserStore.currentFolderFullNameHash(), 1, mailBox(FolderUserStore.currentFolderFullNameHash(), 1,
value.toString().trim(), MessagelistUserStore.threadUid()) value.toString().trim(), MessagelistUserStore.threadUid())
) )
@ -156,15 +161,13 @@ MessagelistUserStore.reload = (bDropPagePosition = false, bDropCurrenFolderCache
MessagelistUserStore.pageBeforeThread(1); MessagelistUserStore.pageBeforeThread(1);
iOffset = 0; iOffset = 0;
rl.route.setHash( replaceHash(
mailBox( mailBox(
FolderUserStore.currentFolderFullNameHash(), FolderUserStore.currentFolderFullNameHash(),
MessagelistUserStore.page(), MessagelistUserStore.page(),
MessagelistUserStore.listSearch(), MessagelistUserStore.listSearch(),
MessagelistUserStore.threadUid() MessagelistUserStore.threadUid()
), )
true,
true
); );
} }
@ -400,14 +403,12 @@ MessagelistUserStore.removeMessagesFromList = (
setHash = 1; setHash = 1;
} else { } else {
MessagelistUserStore.threadUid(0); MessagelistUserStore.threadUid(0);
rl.route.setHash( replaceHash(
mailBox( mailBox(
FolderUserStore.currentFolderFullNameHash(), FolderUserStore.currentFolderFullNameHash(),
MessagelistUserStore.pageBeforeThread(), MessagelistUserStore.pageBeforeThread(),
MessagelistUserStore.listSearch() MessagelistUserStore.listSearch()
), )
true,
true
); );
} }
} else if (MessagelistUserStore.threadUid() != message.uid) { } else if (MessagelistUserStore.threadUid() != message.uid) {
@ -415,15 +416,13 @@ MessagelistUserStore.removeMessagesFromList = (
setHash = 1; setHash = 1;
} }
if (setHash) { if (setHash) {
rl.route.setHash( replaceHash(
mailBox( mailBox(
FolderUserStore.currentFolderFullNameHash(), FolderUserStore.currentFolderFullNameHash(),
MessagelistUserStore.page(), MessagelistUserStore.page(),
MessagelistUserStore.listSearch(), MessagelistUserStore.listSearch(),
MessagelistUserStore.threadUid() MessagelistUserStore.threadUid()
), )
true,
true
); );
} }
} }

View file

@ -15,7 +15,7 @@ const HTML5Notification = window.Notification,
if (data.Folder && data.Uid) { if (data.Folder && data.Uid) {
fireEvent('mailbox.message.show', data); fireEvent('mailbox.message.show', data);
} else if (data.Url) { } else if (data.Url) {
rl.route.setHash(data.Url); hasher.setHash(data.Url);
} }
}; };

View file

@ -766,8 +766,6 @@ export class ComposePopupView extends AbstractViewPopup {
this.to.focused(false); this.to.focused(false);
rl.route.on();
(getFullscreenElement() === this.oContent) && exitFullscreen(); (getFullscreenElement() === this.oContent) && exitFullscreen();
} }
@ -830,8 +828,6 @@ export class ComposePopupView extends AbstractViewPopup {
* @param {string=} sCustomPlainText = null * @param {string=} sCustomPlainText = null
*/ */
onShow(type, oMessageOrArray, aToEmails, aCcEmails, aBccEmails, sCustomSubject, sCustomPlainText) { onShow(type, oMessageOrArray, aToEmails, aCcEmails, aBccEmails, sCustomSubject, sCustomPlainText) {
rl.route.off();
this.autosaveStart(); this.autosaveStart();
this.viewModelDom.dataset.wysiwyg = SettingsUserStore.editorDefaultType(); this.viewModelDom.dataset.wysiwyg = SettingsUserStore.editorDefaultType();

View file

@ -494,14 +494,10 @@ export class ContactsPopupView extends AbstractViewPopup {
onShow(bBackToCompose, sLastComposeFocusedField) { onShow(bBackToCompose, sLastComposeFocusedField) {
this.bBackToCompose = !!bBackToCompose; this.bBackToCompose = !!bBackToCompose;
this.sLastComposeFocusedField = sLastComposeFocusedField; this.sLastComposeFocusedField = sLastComposeFocusedField;
rl.route.off();
this.reloadContactList(true); this.reloadContactList(true);
} }
onHide() { onHide() {
rl.route.on();
this.currentContact(null); this.currentContact(null);
this.emptySelection(true); this.emptySelection(true);
this.search(''); this.search('');

View file

@ -115,7 +115,6 @@ export class LoginUserView extends AbstractViewLogin {
this.submitErrorAddidional((oData && oData.ErrorMessageAdditional) || ''); this.submitErrorAddidional((oData && oData.ErrorMessageAdditional) || '');
} else { } else {
rl.setData(oData.Result); rl.setData(oData.Result);
// rl.route.reload();
} }
}, },
data data

View file

@ -105,7 +105,7 @@ export class MailFolderList extends AbstractViewLeft {
setFolderHash(folder.fullName, ''); setFolderHash(folder.fullName, '');
} }
rl.route.setHash( hasher.setHash(
mailBox(folder.fullNameHash, 1, mailBox(folder.fullNameHash, 1,
(event.target.matches('.flag-icon') && !folder.isFlagged()) ? 'flagged' : '' (event.target.matches('.flag-icon') && !folder.isFlagged()) ? 'flagged' : ''
) )
@ -206,7 +206,7 @@ export class MailFolderList extends AbstractViewLeft {
} }
configureFolders() { configureFolders() {
rl.route.setHash(settings('folders')); hasher.setHash(settings('folders'));
} }
contactsClick() { contactsClick() {

View file

@ -230,14 +230,14 @@ export class MailMessageList extends AbstractViewRight {
); );
if ('INBOX' === sFolder) { if ('INBOX' === sFolder) {
rl.route.setHash(mailBox(sFolder)); hasher.setHash(mailBox(sFolder));
} }
if (message) { if (message) {
this.selector.selectMessageItem(message); this.selector.selectMessageItem(message);
} else { } else {
if ('INBOX' !== sFolder) { if ('INBOX' !== sFolder) {
rl.route.setHash(mailBox(sFolder)); hasher.setHash(mailBox(sFolder));
} }
if (sFolder && iUid) { if (sFolder && iUid) {
MessageUserStore.message(MessageModel.fromMessageListItem(null)); MessageUserStore.message(MessageModel.fromMessageListItem(null));
@ -420,7 +420,7 @@ export class MailMessageList extends AbstractViewRight {
cancelThreadUid() { cancelThreadUid() {
// history.go(-1) better? // history.go(-1) better?
rl.route.setHash( hasher.setHash(
mailBox( mailBox(
FolderUserStore.currentFolderFullNameHash(), FolderUserStore.currentFolderFullNameHash(),
MessagelistUserStore.pageBeforeThread(), MessagelistUserStore.pageBeforeThread(),
@ -590,7 +590,7 @@ export class MailMessageList extends AbstractViewRight {
} }
gotoPage(page) { gotoPage(page) {
page && rl.route.setHash( page && hasher.setHash(
mailBox( mailBox(
FolderUserStore.currentFolderFullNameHash(), FolderUserStore.currentFolderFullNameHash(),
page.value, page.value,
@ -604,7 +604,7 @@ export class MailMessageList extends AbstractViewRight {
if (message && 0 < message.threadsLen()) { if (message && 0 < message.threadsLen()) {
MessagelistUserStore.pageBeforeThread(MessagelistUserStore.page()); MessagelistUserStore.pageBeforeThread(MessagelistUserStore.page());
rl.route.setHash( hasher.setHash(
mailBox(FolderUserStore.currentFolderFullNameHash(), 1, MessagelistUserStore.listSearch(), message.uid) mailBox(FolderUserStore.currentFolderFullNameHash(), 1, MessagelistUserStore.listSearch(), message.uid)
); );
} }

View file

@ -18,6 +18,6 @@ export class MenuSettingsUserView extends AbstractViewLeft {
} }
backToMailBoxClick() { backToMailBoxClick() {
rl.route.setHash(mailbox(getFolderInboxName())); hasher.setHash(mailbox(getFolderInboxName()));
} }
} }

View file

@ -26,6 +26,6 @@ export class PaneSettingsUserView extends AbstractViewRight {
} }
backToMailBoxClick() { backToMailBoxClick() {
rl.route.setHash(mailbox(getFolderInboxName())); hasher.setHash(mailbox(getFolderInboxName()));
} }
} }

View file

@ -4,7 +4,7 @@ import { MessageUserStore } from 'Stores/User/Message';
//import { FolderUserStore } from 'Stores/User/Folder'; //import { FolderUserStore } from 'Stores/User/Folder';
import { Capa, Scope } from 'Common/Enums'; import { Capa, Scope } from 'Common/Enums';
import { root, settings } from 'Common/Links'; import { settings } from 'Common/Links';
import { showScreenPopup } from 'Knoin/Knoin'; import { showScreenPopup } from 'Knoin/Knoin';
import { AbstractViewRight } from 'Knoin/AbstractViews'; import { AbstractViewRight } from 'Knoin/AbstractViews';
@ -82,9 +82,7 @@ export class SystemDropDownUserView extends AbstractViewRight {
}); });
AccountUserStore.loading(false); AccountUserStore.loading(false);
*/ */
// rl.route.reload(); rl.route.reload();
location.href = root();
location.reload();
} }
}, {Email:account.email} }, {Email:account.email}
); );
@ -97,7 +95,7 @@ export class SystemDropDownUserView extends AbstractViewRight {
} }
settingsClick() { settingsClick() {
rl.route.setHash(settings()); hasher.setHash(settings());
} }
settingsHelp() { settingsHelp() {

20
dev/bootstrap.js vendored
View file

@ -27,31 +27,15 @@ export default App => {
rl.route = { rl.route = {
root: () => { root: () => {
rl.route.setHash(root(), true);
rl.route.off(); rl.route.off();
hasher.setHash(root());
}, },
reload: () => { reload: () => {
rl.route.root(); rl.route.root();
setTimeout(() => (Settings.app('inIframe') ? parent : window).location.reload(), 100); setTimeout(() => (Settings.app('inIframe') ? parent : window).location.reload(), 100);
}, },
off: () => hasher.active = false, off: () => hasher.active = false,
on: () => hasher.active = true, on: () => hasher.active = true
/**
* @param {string} sHash
* @param {boolean=} silence = false
* @param {boolean=} replace = false
* @returns {void}
*/
setHash: (hash, silence = false, replace = false) => {
hash = hash.replace(/^[#/]+/, '');
hasher.active = !silence;
hasher[replace ? 'replaceHash' : 'setHash'](hash);
if (silence) {
hasher.active = true;
} else {
hasher.setHash(hash);
}
}
}; };
rl.fetch = (resource, init, postData) => { rl.fetch = (resource, init, postData) => {

View file

@ -13,12 +13,11 @@
const const
_hashValRegexp = /#(.*)$/, _hashValRegexp = /#(.*)$/,
_hashRegexp = /^#/, _hashRegexp = /^[#/]+/,
_hashTrim = /^\/|\$/g, _hashTrim = /^\/|\$/g,
_trimHash = hash => hash ? hash.replace(_hashTrim, '') : '', _trimHash = hash => hash ? hash.replace(_hashTrim, '') : '',
_getWindowHash = () => { _getWindowHash = () => {
//parsed full URL instead of getting window.location.hash because Firefox decode hash value (and all the other browsers don't) //parsed full URL instead of getting window.location.hash because Firefox decode hash value (and all the other browsers don't)
//also because of IE8 bug with hash query in local file [issue #6]
var result = _hashValRegexp.exec( location.href ); var result = _hashValRegexp.exec( location.href );
return (result && result[1]) ? decodeURIComponent(result[1]) : ''; return (result && result[1]) ? decodeURIComponent(result[1]) : '';
}, },
@ -26,17 +25,10 @@
if (_hash !== newHash) { if (_hash !== newHash) {
var oldHash = _hash; var oldHash = _hash;
_hash = newHash; //should come before event dispatch to make sure user can get proper value inside event handler _hash = newHash; //should come before event dispatch to make sure user can get proper value inside event handler
hasher.dispatch(_trimHash(newHash), _trimHash(oldHash)); _dispatch(_trimHash(newHash), _trimHash(oldHash));
}
},
_checkHistory = () => {
var windowHash = _getWindowHash();
if (windowHash !== _hash) {
_registerChange(windowHash);
} }
}, },
_setHash = (path, replace) => { _setHash = (path, replace) => {
path = path.join('/');
path = path ? '/' + path.replace(_hashRegexp, '') : path; path = path ? '/' + path.replace(_hashRegexp, '') : path;
if (path !== _hash){ if (path !== _hash){
// we should store raw value // we should store raw value
@ -51,6 +43,7 @@
} }
} }
}, },
_dispatch = (...args) => hasher.active && _bindings.forEach(callback => callback(...args)),
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Public (API) // Public (API)
@ -69,7 +62,6 @@
*/ */
active : true, active : true,
add : callback => _bindings.push(callback), add : callback => _bindings.push(callback),
dispatch : (...args) => hasher.active && _bindings.forEach(callback => callback(...args)),
/** /**
* Start listening/dispatching changes in the hash/history. * Start listening/dispatching changes in the hash/history.
@ -77,28 +69,27 @@
* <li>hasher won't dispatch CHANGE events by manually typing a new value or pressing the back/forward buttons before calling this method.</li> * <li>hasher won't dispatch CHANGE events by manually typing a new value or pressing the back/forward buttons before calling this method.</li>
* </ul> * </ul>
*/ */
init : () => hasher.dispatch(_trimHash(_hash)), init : () => _dispatch(_trimHash(_hash)),
/** /**
* Set Hash value, generating a new history record. * Set Hash value, generating a new history record.
* @param {...string} path Hash value without '#'. * @param {...string} path Hash value without '#'.
* @example hasher.setHash('lorem', 'ipsum', 'dolor') -> '#/lorem/ipsum/dolor' * @example hasher.setHash('lorem/ipsum/dolor') -> '#/lorem/ipsum/dolor'
*/ */
setHash : (...path) => _setHash(path), setHash : path => _setHash(path),
/** /**
* Set Hash value without keeping previous hash on the history record. * Set Hash value without keeping previous hash on the history record.
* Similar to calling `window.location.replace("#/hash")` but will also work on IE6-7.
* @param {...string} path Hash value without '#'. * @param {...string} path Hash value without '#'.
* @example hasher.replaceHash('lorem', 'ipsum', 'dolor') -> '#/lorem/ipsum/dolor' * @example hasher.replaceHash('lorem/ipsum/dolor') -> '#/lorem/ipsum/dolor'
*/ */
replaceHash : (...path) => _setHash(path, true) replaceHash : path => _setHash(path, true)
}; };
var _hash = _getWindowHash(), var _hash = _getWindowHash(),
_bindings = []; _bindings = [];
addEventListener('hashchange', _checkHistory); addEventListener('hashchange', () => _registerChange(_getWindowHash()));
global.hasher = hasher; global.hasher = hasher;
})(this); })(this);