focus/blur listeners on side panel

This commit is contained in:
dragonwocky 2021-10-19 16:38:48 +11:00
parent 860a943437
commit fe42600ab8
3 changed files with 40 additions and 20 deletions

View File

@ -29,10 +29,12 @@ export { feather } from './feather.mjs';
/** /**
* adds a view to the enhancer's side panel * adds a view to the enhancer's side panel
* @param {object} panel - information used to construct and render the panel * @param {object} panel - information used to construct and render the panel
* @param {string} [panel.id] - a uuid, used to restore the last open view on reload * @param {string} panel.id - a uuid, used to restore the last open view on reload
* @param {string} panel.icon - an svg string * @param {string} panel.icon - an svg string
* @param {string} panel.title - the name of the view * @param {string} panel.title - the name of the view
* @param {Element} panel.$content - an element containing the content of the view * @param {Element} panel.$content - an element containing the content of the view
* @param {function} panel.onBlur - runs when the view is selected/focused
* @param {function} panel.onFocus - runs when the view is unfocused/closed
*/ */
export { addPanelView } from './panel.mjs'; export { addPanelView } from './panel.mjs';

View File

@ -170,6 +170,7 @@ const $panel = web.html`<div id="enhancer--panel"></div>`,
} }
}, },
renderView = (view) => { renderView = (view) => {
const prevView = _views.find(({ $content }) => document.contains($content));
web.render( web.render(
web.empty($panelTitle), web.empty($panelTitle),
web.render( web.render(
@ -178,10 +179,13 @@ const $panel = web.html`<div id="enhancer--panel"></div>`,
view.$title view.$title
) )
); );
view.onFocus();
web.render(web.empty($panelContent), view.$content); web.render(web.empty($panelContent), view.$content);
if (prevView) prevView.onBlur();
}; };
async function createPanel() { async function createPanel() {
await web.whenReady(['.notion-frame']);
$notionFrame = document.querySelector('.notion-frame'); $notionFrame = document.querySelector('.notion-frame');
const notionRightSidebarSelector = '.notion-cursor-listener > div[style*="flex-end"]', const notionRightSidebarSelector = '.notion-cursor-listener > div[style*="flex-end"]',
@ -239,22 +243,35 @@ async function createViews() {
/** /**
* adds a view to the enhancer's side panel * adds a view to the enhancer's side panel
* @param {object} panel - information used to construct and render the panel * @param {object} panel - information used to construct and render the panel
* @param {string} [panel.id] - a uuid, used to restore the last open view on reload * @param {string} panel.id - a uuid, used to restore the last open view on reload
* @param {string} panel.icon - an svg string * @param {string} panel.icon - an svg string
* @param {string} panel.title - the name of the view * @param {string} panel.title - the name of the view
* @param {Element} panel.$content - an element containing the content of the view * @param {Element} panel.$content - an element containing the content of the view
* @param {function} panel.onBlur - runs when the view is selected/focused
* @param {function} panel.onFocus - runs when the view is unfocused/closed
*/ */
export const addPanelView = async ({ id = fmt.uuidv4(), icon, title, $content }) => { export const addPanelView = async ({
id,
icon,
title,
$content,
onFocus = () => {},
onBlur = () => {},
}) => {
const view = { const view = {
id, id,
$icon: web.html`<span class="enhancer--panel-view-title-icon"> $icon: web.render(
${icon} web.html`<span class="enhancer--panel-view-title-icon"></span>`,
</span>`, icon instanceof Element ? icon : web.html`${icon}`
$title: web.html`<span class="enhancer--panel-view-title-text"> ),
${web.escape(title)} $title: web.render(
<span class="enhancer--panel-view-title-fade-edge"> </span> web.html`<span class="enhancer--panel-view-title-text"></span>`,
</span>`, title,
web.html`<span class="enhancer--panel-view-title-fade-edge"></span>`
),
$content, $content,
onFocus,
onBlur,
}; };
_views.push(view); _views.push(view);
if (_views.length === 1) await createPanel(); if (_views.length === 1) await createPanel();

View File

@ -194,17 +194,18 @@ export const addDocumentObserver = (callback, selectors = []) => {
if (!_documentObserver) { if (!_documentObserver) {
const handle = (queue) => { const handle = (queue) => {
while (queue.length) { while (queue.length) {
const event = queue.shift(); const event = queue.shift(),
for (const listener of _documentObserverListeners) { matchesAddedNode = ($node, selector) =>
if ( $node instanceof Element &&
!listener.selectors.length || ($node.matches(selector) ||
listener.selectors.some( $node.matches(`${selector} *`) ||
(selector) => $node.querySelector(selector)),
matchesTarget = (selector) =>
event.target.matches(selector) || event.target.matches(selector) ||
event.target.matches(`${selector} *`) || event.target.matches(`${selector} *`) ||
event.target.querySelector(selector) [...event.addedNodes].some(($node) => matchesAddedNode($node, selector));
) for (const listener of _documentObserverListeners) {
) { if (!listener.selectors.length || listener.selectors.some(matchesTarget)) {
listener.callback(event); listener.callback(event);
} }
} }