I can select range with visual feedback

This commit is contained in:
2026-02-10 23:00:45 +01:00
parent 79c37493af
commit 520a8914fc
7 changed files with 353 additions and 25 deletions

View File

@@ -671,12 +671,8 @@
const element = document.getElementById(candidate.elementId);
const dynamicValues = func(event, element, candidate.node.combinationStr);
if (dynamicValues && typeof dynamicValues === 'object') {
// Suffix each key with _mousedown
const suffixed = {};
for (const [key, value] of Object.entries(dynamicValues)) {
suffixed[key + '_mousedown'] = value;
}
mousedownJsValues[candidate.elementId] = suffixed;
// Store raw values - _mousedown suffix added at mouseup time
mousedownJsValues[candidate.elementId] = dynamicValues;
}
}
} catch (e) {
@@ -699,12 +695,39 @@
// Clear pending state
MouseRegistry.mousedownPending = null;
// Remove mousemove listener (no longer needed)
// Remove mousemove listener (threshold detection no longer needed)
if (MouseRegistry.mousemoveHandler) {
document.removeEventListener('mousemove', MouseRegistry.mousemoveHandler);
MouseRegistry.mousemoveHandler = null;
}
// Attach on_move handler if any candidate has 'on-move' config
const onMoveCandidates = MouseRegistry.mousedownState.candidates.filter(
c => c.node.config && c.node.config['on-move']
);
if (onMoveCandidates.length > 0) {
let rafId = null;
MouseRegistry.mousemoveHandler = (moveEvent) => {
if (rafId) return;
rafId = requestAnimationFrame(() => {
for (const candidate of onMoveCandidates) {
const funcName = candidate.node.config['on-move'];
try {
const func = window[funcName];
if (typeof func === 'function') {
const mousedownValues = mousedownJsValues[candidate.elementId] || null;
func(moveEvent, candidate.node.combinationStr, mousedownValues);
}
} catch (e) {
console.error('Error calling on_move function:', e);
}
}
rafId = null;
});
};
document.addEventListener('mousemove', MouseRegistry.mousemoveHandler);
}
// For right button: prevent context menu during drag
if (pendingData.button === 2) {
const preventContextMenu = (e) => {
@@ -907,9 +930,11 @@
Object.assign(values, config['hx-vals']);
}
// 2. Merge mousedown JS values (already suffixed with _mousedown)
// 2. Merge mousedown JS values with _mousedown suffix
if (match.mousedownJsValues) {
Object.assign(values, match.mousedownJsValues);
for (const [key, value] of Object.entries(match.mousedownJsValues)) {
values[key + '_mousedown'] = value;
}
}
// 3. Call JS function at mouseup time, suffix with _mouseup

View File

@@ -186,8 +186,10 @@ function bindTooltipsWithDelegation(elementId) {
// Add a single mouseenter and mouseleave listener to the parent element
element.addEventListener("mouseenter", (event) => {
// Early exit - check mf-no-tooltip FIRST (before any DOM work)
if (element.hasAttribute("mf-no-tooltip")) {
const target = event.target;
// Early exit - check mf-no-tooltip on the registered element OR any ancestor of the target
if (element.hasAttribute("mf-no-tooltip") || target.closest("[mf-no-tooltip]")) {
return;
}
@@ -196,7 +198,7 @@ function bindTooltipsWithDelegation(elementId) {
return;
}
const cell = event.target.closest("[data-tooltip]");
const cell = target.closest("[data-tooltip]");
if (!cell) {
return;
}
@@ -207,7 +209,7 @@ function bindTooltipsWithDelegation(elementId) {
tooltipRafScheduled = false;
// Check again in case tooltip was disabled during RAF delay
if (element.hasAttribute("mf-no-tooltip")) {
if (element.hasAttribute("mf-no-tooltip") || target.closest("[mf-no-tooltip]")) {
return;
}