notion-enhancer/repo/menu/router.mjs

89 lines
2.6 KiB
JavaScript

/**
* notion-enhancer: menu
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (https://notion-enhancer.github.io/) under the MIT license
*/
'use strict';
import { web } from '../../api/index.mjs';
const _queryListeners = new Set();
export function addView(name, loadFunc) {
const handlerFunc = (newView) => {
if (newView === name) return loadFunc();
return false;
};
_queryListeners.add({ param: 'view', viewName: name, handlerFunc });
handlerFunc(web.queryParams().get('view'), null);
}
export function removeView(name) {
const view = [..._queryListeners].find((view) => view.viewName === name);
if (view) _queryListeners.delete(view);
}
export async function setDefaultView(viewName) {
const viewList = [..._queryListeners].filter((q) => q.viewName).map((v) => v.viewName);
if (!viewList.includes(web.queryParams().get('view'))) {
updateQuery(`?view=${viewName}`, true);
}
}
export function addQueryListener(param, handlerFunc) {
_queryListeners.add({ param: param, handlerFunc });
handlerFunc(web.queryParams().get(param), null);
}
export function removeQueryListener(handlerFunc) {
const listener = [..._queryListeners].find((view) => view.handlerFunc === handlerFunc);
if (listener) _queryListeners.delete(listener);
}
export const updateQuery = (search, replace = false) => {
let query = web.queryParams();
for (const [key, val] of new URLSearchParams(search)) {
query.set(key, val);
}
query = `?${query.toString()}`;
if (location.search !== query) {
if (replace) {
window.history.replaceState(null, null, query);
} else {
window.history.pushState(null, null, query);
}
triggerQueryListeners();
}
};
function router(event) {
event.preventDefault();
const anchor = event.path
? event.path.find((anchor) => anchor.nodeName === 'A')
: event.target;
updateQuery(anchor.getAttribute('href'));
}
let queryCache = '';
async function triggerQueryListeners() {
if (location.search === queryCache) return;
const newQuery = web.queryParams(),
oldQuery = new URLSearchParams(queryCache);
queryCache = location.search;
for (const listener of _queryListeners) {
const newParam = newQuery.get(listener.param),
oldParam = oldQuery.get(listener.param);
if (newParam !== oldParam) listener.handlerFunc(newParam, oldParam);
}
}
window.addEventListener('popstate', triggerQueryListeners);
web.addDocumentObserver(
(mutation) => {
mutation.target.querySelectorAll('a[href^="?"]').forEach((a) => {
a.removeEventListener('click', router);
a.addEventListener('click', router);
});
},
['a[href^="?"]']
);