runtimeDelegationJs top-level constant
String
const runtimeDelegationJs
Implementation
const String runtimeDelegationJs = r'''
function findActionTarget(el, attr) {
let cur = el;
while (cur && cur !== document) {
if (cur.nodeType === 1 && cur.hasAttribute(attr)) return cur;
cur = cur.parentNode;
}
return null;
}
function shouldHandleClick(el) {
if (!el) return false;
if (el.hasAttribute('data-arcane-disabled')) return false;
if (el.hasAttribute('disabled')) return false;
return true;
}
function autoDismissAfterAction(trigger) {
if (!trigger) return;
if (trigger.getAttribute('data-arcane-keep-open') === 'true') return;
const surf = withinSurface(trigger);
if (!surf) return;
const stype = surfaceType(surf);
if (stype !== 'menu' && stype !== 'context-menu' && stype !== 'popover') return;
if (surf.getAttribute('data-arcane-keep-open-on-action') === 'true') return;
const sid = surfaceId(surf);
setTimeout(function() { closeSurface(stype, sid); }, 0);
}
function onDocumentClick(e) {
if (e.defaultPrevented) return;
const trigger = findActionTarget(e.target, 'data-arcane-action');
if (trigger && shouldHandleClick(trigger)) {
if (trigger.tagName === 'A' && trigger.getAttribute('href')) {
const href = trigger.getAttribute('href');
if (href.indexOf('#') !== 0 && trigger.target !== '_blank') {
e.preventDefault();
}
}
if (trigger.tagName === 'BUTTON' || trigger.getAttribute('role') === 'button') {
e.preventDefault();
}
runActions(trigger.getAttribute('data-arcane-action'), { trigger: trigger, event: e });
autoDismissAfterAction(trigger);
return;
}
if (ARCANE.stack.length > 0) {
const top = ARCANE.stack[ARCANE.stack.length - 1];
const surfaceEl = top.el;
if (surfaceEl && !surfaceEl.contains(e.target)) {
const scrimCloses = surfaceEl.getAttribute('data-arcane-scrim-closes') !== 'false';
const dismissible = surfaceEl.getAttribute('data-arcane-dismissible') !== 'false';
if (scrimCloses && dismissible) {
if ((top.type === 'popover' || top.type === 'menu' || top.type === 'context-menu' || top.type === 'tooltip') ||
e.target.classList.contains('arcane-overlay-scrim') ||
e.target.hasAttribute('data-arcane-scrim') ||
(top.type === 'dialog' || top.type === 'sheet' || top.type === 'drawer')) {
if (top.type === 'dialog' || top.type === 'sheet' || top.type === 'drawer') {
if (e.target.classList.contains('arcane-overlay-scrim') ||
e.target.hasAttribute('data-arcane-scrim') ||
e.target === surfaceEl.parentElement) {
closeSurface(top.type, top.id);
}
} else {
closeSurface(top.type, top.id);
}
}
}
}
}
}
function onDocumentChange(e) {
const target = findActionTarget(e.target, 'data-arcane-change');
if (target) {
runActions(target.getAttribute('data-arcane-change'), { trigger: target, event: e });
}
if (e.target.matches && e.target.matches('[data-arcane-form] [data-arcane-field]')) {
const formEl = findClosest(e.target, '[data-arcane-form]');
if (formEl) {
const fid = formEl.getAttribute('data-arcane-form');
const fname = e.target.getAttribute('data-arcane-field');
if (fid && fname) validateField(fid, fname);
}
}
}
function onDocumentInput(e) {
const target = findActionTarget(e.target, 'data-arcane-input');
if (target) {
runActions(target.getAttribute('data-arcane-input'), { trigger: target, event: e });
}
}
function onDocumentSubmit(e) {
const formEl = findActionTarget(e.target, 'data-arcane-form');
if (formEl) {
e.preventDefault();
const fid = formEl.getAttribute('data-arcane-form');
if (fid) submitForm(fid);
}
const target = findActionTarget(e.target, 'data-arcane-submit');
if (target) {
runActions(target.getAttribute('data-arcane-submit'), { trigger: target, event: e });
}
}
function onDocumentDblClick(e) {
const target = findActionTarget(e.target, 'data-arcane-dblclick');
if (target) {
runActions(target.getAttribute('data-arcane-dblclick'), { trigger: target, event: e });
}
}
function onDocumentContextMenu(e) {
const target = findActionTarget(e.target, 'data-arcane-contextmenu');
if (target) {
e.preventDefault();
runActions(target.getAttribute('data-arcane-contextmenu'), { trigger: target, event: e });
}
}
function onDocumentKeyDown(e) {
if (e.key === 'Escape') {
if (ARCANE.stack.length > 0) {
const top = ARCANE.stack[ARCANE.stack.length - 1];
const surfaceEl = top.el;
if (surfaceEl && surfaceEl.getAttribute('data-arcane-escape-closes') !== 'false') {
closeSurface(top.type, top.id);
e.preventDefault();
e.stopPropagation();
return;
}
}
}
if (e.key === 'Tab' && ARCANE.stack.length > 0) {
const top = ARCANE.stack[ARCANE.stack.length - 1];
const surfaceEl = top.el;
if (surfaceEl && (top.type === 'dialog' || top.type === 'sheet' ||
surfaceEl.getAttribute('data-arcane-focus-trap') === 'true')) {
trapFocus(surfaceEl, e);
}
}
if (e.key === 'Enter' || e.key === ' ') {
const target = e.target;
if (target && target.matches && target.matches('[data-arcane-action]') &&
target.tagName !== 'BUTTON' && target.tagName !== 'A' &&
target.tagName !== 'INPUT' && target.tagName !== 'TEXTAREA' &&
target.tagName !== 'SELECT') {
e.preventDefault();
runActions(target.getAttribute('data-arcane-action'), { trigger: target, event: e });
}
}
if (e.key === 'ArrowLeft' || e.key === 'ArrowRight' ||
e.key === 'ArrowUp' || e.key === 'ArrowDown') {
handleArrowKey(e);
}
const keyTarget = findActionTarget(e.target, 'data-arcane-keydown');
if (keyTarget) {
runActions(keyTarget.getAttribute('data-arcane-keydown'), { trigger: keyTarget, event: e });
}
}
function handleArrowKey(e) {
const tab = findClosest(e.target, '[role="tab"][data-arcane-tab]');
if (tab) {
const groupId = tab.getAttribute('data-arcane-tabs-group');
const orientation = (findClosest(tab, '[data-arcane-tabs-orientation]') || {}).getAttribute &&
findClosest(tab, '[data-arcane-tabs-orientation]').getAttribute('data-arcane-tabs-orientation') || 'horizontal';
const isHorizontal = orientation === 'horizontal';
const forward = isHorizontal ? e.key === 'ArrowRight' : e.key === 'ArrowDown';
const backward = isHorizontal ? e.key === 'ArrowLeft' : e.key === 'ArrowUp';
if (forward || backward) {
e.preventDefault();
const triggers = Array.prototype.slice.call(document.querySelectorAll(
'[data-arcane-tabs-group="' + cssEscape(groupId) + '"][data-arcane-tab]'
));
const idx = triggers.indexOf(tab);
let next = forward ? idx + 1 : idx - 1;
if (next < 0) next = triggers.length - 1;
if (next >= triggers.length) next = 0;
const nextTab = triggers[next];
if (nextTab) {
activateTab(groupId, nextTab.getAttribute('data-arcane-tab'));
nextTab.focus();
}
return;
}
}
const opt = findClosest(e.target, '[data-arcane-group][data-arcane-value]');
if (opt) {
const surf = withinSurface(opt);
if (surf && (surfaceType(surf) === 'menu' || surfaceType(surf) === 'context-menu' ||
surfaceType(surf) === 'popover' || surfaceType(surf) === 'command')) {
const forward = e.key === 'ArrowDown';
const backward = e.key === 'ArrowUp';
if (forward || backward) {
e.preventDefault();
const groupId = opt.getAttribute('data-arcane-group');
const items = Array.prototype.slice.call(surf.querySelectorAll(
'[data-arcane-group="' + cssEscape(groupId) + '"][data-arcane-value]:not([data-arcane-disabled="true"])'
));
const idx = items.indexOf(opt);
let next = forward ? idx + 1 : idx - 1;
if (next < 0) next = items.length - 1;
if (next >= items.length) next = 0;
if (items[next]) items[next].focus();
return;
}
}
}
}
function onPointerOver(e) {
const trigger = findActionTarget(e.target, 'data-arcane-mouseenter');
if (trigger) {
runActions(trigger.getAttribute('data-arcane-mouseenter'), { trigger: trigger, event: e });
}
const hoverTrigger = findActionTarget(e.target, 'data-arcane-hover-target');
if (hoverTrigger) {
const targetId = hoverTrigger.getAttribute('data-arcane-hover-target');
const surfaceType = hoverTrigger.getAttribute('data-arcane-hover-surface') || 'tooltip';
const delay = parseInt(hoverTrigger.getAttribute('data-arcane-hover-delay') || '120', 10);
if (hoverTrigger._arcaneHoverTimer) clearTimeout(hoverTrigger._arcaneHoverTimer);
hoverTrigger._arcaneHoverTimer = setTimeout(function() {
openSurface(surfaceType, targetId, { trigger: hoverTrigger });
}, delay);
}
}
function onPointerOut(e) {
const trigger = findActionTarget(e.target, 'data-arcane-mouseleave');
if (trigger && !trigger.contains(e.relatedTarget)) {
runActions(trigger.getAttribute('data-arcane-mouseleave'), { trigger: trigger, event: e });
}
const hoverTrigger = findActionTarget(e.target, 'data-arcane-hover-target');
if (hoverTrigger && !hoverTrigger.contains(e.relatedTarget)) {
if (hoverTrigger._arcaneHoverTimer) clearTimeout(hoverTrigger._arcaneHoverTimer);
const targetId = hoverTrigger.getAttribute('data-arcane-hover-target');
const surfaceType = hoverTrigger.getAttribute('data-arcane-hover-surface') || 'tooltip';
const delay = parseInt(hoverTrigger.getAttribute('data-arcane-hover-close-delay') || '60', 10);
hoverTrigger._arcaneHoverTimer = setTimeout(function() {
const surf = querySurface(surfaceType, targetId);
if (surf && !surf.matches(':hover')) {
closeSurface(surfaceType, targetId);
}
}, delay);
}
}
function onFocusIn(e) {
const trigger = findActionTarget(e.target, 'data-arcane-focus');
if (trigger) {
runActions(trigger.getAttribute('data-arcane-focus'), { trigger: trigger, event: e });
}
}
function onFocusOut(e) {
const trigger = findActionTarget(e.target, 'data-arcane-blur');
if (trigger) {
runActions(trigger.getAttribute('data-arcane-blur'), { trigger: trigger, event: e });
}
}
ARCANE.delegation = {
click: onDocumentClick,
change: onDocumentChange,
input: onDocumentInput,
submit: onDocumentSubmit,
dblclick: onDocumentDblClick,
contextmenu: onDocumentContextMenu,
keydown: onDocumentKeyDown,
pointerover: onPointerOver,
pointerout: onPointerOut,
focusin: onFocusIn,
focusout: onFocusOut
};
''';