refactor: share sidebar active state detection
This commit is contained in:
@@ -93,6 +93,37 @@ test('shared DOM helpers synchronize attributes, text, and one-time listeners',
|
||||
assert.equal(clicks, 1);
|
||||
});
|
||||
|
||||
test('sidebar active helper recognizes supported state attributes and classes', () => {
|
||||
assert.equal(typeof domPatchUtils.isSidebarButtonActive, 'function');
|
||||
|
||||
const window = new Window();
|
||||
const selectors = [
|
||||
'[aria-pressed="true"]',
|
||||
'[aria-selected="true"]',
|
||||
'[data-active="true"]',
|
||||
'[data-selected="true"]',
|
||||
'.active',
|
||||
'.is-active',
|
||||
'.selected',
|
||||
'.p-highlight',
|
||||
];
|
||||
|
||||
for (const selector of selectors) {
|
||||
const button = window.document.createElement('button');
|
||||
if (selector.startsWith('[')) {
|
||||
const [attribute, value] = selector.slice(1, -1).split('=');
|
||||
button.setAttribute(attribute, value.replaceAll('"', ''));
|
||||
} else {
|
||||
button.className = selector.slice(1);
|
||||
}
|
||||
assert.equal(domPatchUtils.isSidebarButtonActive(button), true, selector);
|
||||
}
|
||||
|
||||
const inactiveButton = window.document.createElement('button');
|
||||
assert.equal(domPatchUtils.isSidebarButtonActive(inactiveButton), false);
|
||||
assert.equal(domPatchUtils.isSidebarButtonActive(null), false);
|
||||
});
|
||||
|
||||
test('instant actions handle pointer and click as one idempotent action', () => {
|
||||
assert.equal(typeof domPatchUtils.bindInstantAction, 'function');
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { $el } from "../../../../scripts/ui.js";
|
||||
import { createModuleLogger } from "../log_system/log_funcs.js";
|
||||
import { logger as frontendLogger } from "../log_system/logger.js";
|
||||
import { loadStylesWhenNeeded } from "../utils/css_loader.js";
|
||||
import { isSidebarButtonActive } from "../utils/dom_patch_utils.js";
|
||||
import { ResolverManagerDialog } from "./resolver_dialog.js";
|
||||
import { showNotification } from "../utils/notification_utils.js";
|
||||
import {
|
||||
@@ -763,26 +764,13 @@ export class ModelResolver {
|
||||
event.stopImmediatePropagation?.();
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
if (this.isSidebarButtonActive(button)) {
|
||||
if (isSidebarButtonActive(button)) {
|
||||
button.click();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
isSidebarButtonActive(button) {
|
||||
return button.matches([
|
||||
'[aria-pressed="true"]',
|
||||
'[aria-selected="true"]',
|
||||
'[data-active="true"]',
|
||||
'[data-selected="true"]',
|
||||
'.active',
|
||||
'.is-active',
|
||||
'.selected',
|
||||
'.p-highlight'
|
||||
].join(','));
|
||||
}
|
||||
|
||||
renderSidebarPanel(element) {
|
||||
element.style.height = "100%";
|
||||
element.classList.add("mr-sidebar-dock-panel");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { app } from "../../../../../scripts/app.js";
|
||||
import { $el } from "../../../../../scripts/ui.js";
|
||||
import { getSvgIcon } from "../../utils/icon_utils.js";
|
||||
import { isSidebarButtonActive } from "../utils/dom_patch_utils.js";
|
||||
import { safeStorage } from "../utils/html_utils.js";
|
||||
export const dialogShellMethods = {
|
||||
createHeader() {
|
||||
@@ -555,16 +556,7 @@ export const dialogShellMethods = {
|
||||
|
||||
const button = document.querySelector(`.${this.sidebarTabId}-tab-button`);
|
||||
if (button instanceof HTMLElement) {
|
||||
const isActive = button.matches([
|
||||
'[aria-pressed="true"]',
|
||||
'[aria-selected="true"]',
|
||||
'[data-active="true"]',
|
||||
'[data-selected="true"]',
|
||||
'.active',
|
||||
'.is-active',
|
||||
'.selected',
|
||||
'.p-highlight'
|
||||
].join(','));
|
||||
const isActive = isSidebarButtonActive(button);
|
||||
|
||||
if (!isActive) {
|
||||
button.click();
|
||||
@@ -670,16 +662,7 @@ export const dialogShellMethods = {
|
||||
const button = document.querySelector(`.${this.sidebarTabId}-tab-button`);
|
||||
if (!(button instanceof HTMLElement)) return;
|
||||
|
||||
const isActive = button.matches([
|
||||
'[aria-pressed="true"]',
|
||||
'[aria-selected="true"]',
|
||||
'[data-active="true"]',
|
||||
'[data-selected="true"]',
|
||||
'.active',
|
||||
'.is-active',
|
||||
'.selected',
|
||||
'.p-highlight'
|
||||
].join(','));
|
||||
const isActive = isSidebarButtonActive(button);
|
||||
|
||||
if (!closedByState || isActive) {
|
||||
button.click();
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
const boundEventKeys = new WeakMap();
|
||||
const SIDEBAR_ACTIVE_SELECTOR = [
|
||||
'[aria-pressed="true"]',
|
||||
'[aria-selected="true"]',
|
||||
'[data-active="true"]',
|
||||
'[data-selected="true"]',
|
||||
'.active',
|
||||
'.is-active',
|
||||
'.selected',
|
||||
'.p-highlight'
|
||||
].join(',');
|
||||
|
||||
export function syncElementAttributes(current, next) {
|
||||
if (!current || !next) return current;
|
||||
@@ -27,6 +37,10 @@ export function setTextIfChanged(element, value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
export function isSidebarButtonActive(element) {
|
||||
return Boolean(element?.matches?.(SIDEBAR_ACTIVE_SELECTOR));
|
||||
}
|
||||
|
||||
export function bindEventOnce(element, eventName, handler, key = eventName) {
|
||||
if (!element?.addEventListener || !eventName || typeof handler !== 'function') return false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user