-
🌐 async-utils.jsWeb, 3.69 kB⬇
-
🌐 auth-storage.jsWeb, 735 B⬇
-
🌐 chat-helpers.jsWeb, 8.85 kB⬇
-
🌐 chat-renderer.jsWeb, 70.00 kB⬇
-
🌐 code-overlay.jsWeb, 21.77 kB⬇
-
🌐 confirm-dialog.jsWeb, 3.17 kB⬇
-
🌐 conversation-format-utils.jsWeb, 21.51 kB⬇
-
🌐 diagram-overlay.jsWeb, 7.93 kB⬇
-
🌐 dialog.jsWeb, 2.50 kB⬇
-
🌐 dom-utils.jsWeb, 8.33 kB⬇
-
🌐 drag-reorder.jsWeb, 4.82 kB⬇
-
🌐 elements.jsWeb, 11.06 kB⬇
-
🌐 export-utils.jsWeb, 1.53 kB⬇
-
🌐 format-utils.jsWeb, 29.60 kB⬇
-
🌐 history-navigation.jsWeb, 1.95 kB⬇
-
🌐 hljs-yaml.jsWeb, 5.07 kB⬇
-
🌐 inline-format.jsWeb, 7.35 kB⬇
-
🌐 instant-answer.jsWeb, 19.82 kB⬇
-
🌐 interactive-tools.jsWeb, 38.77 kB⬇
-
🌐 mermaid-fixes.jsWeb, 4.60 kB⬇
-
🌐 mermaid-render.jsWeb, 5.10 kB⬇
-
🌐 mermaid.jsWeb, 195 B⬇
-
🌐 migrations.jsWeb, 12.11 kB⬇
-
🌐 multi-choice-dialog.jsWeb, 1.33 kB⬇
-
🌐 notification-stack.jsWeb, 2.50 kB⬇
-
🌐 options-manager.jsWeb, 45.56 kB⬇
-
🌐 overlay-utils.jsWeb, 4.14 kB⬇
-
🌐 pdf-export.jsWeb, 23.59 kB⬇
-
🌐 pinch-zoom.jsWeb, 3.21 kB⬇
-
🌐 plugin-dialog.jsWeb, 2.17 kB⬇
-
🌐 read-aloud.jsWeb, 33.84 kB⬇
-
🌐 response-pipeline.jsWeb, 55.19 kB⬇
-
🌐 scratchpad-editor.jsWeb, 8.64 kB⬇
-
🌐 scratchpad-export.jsWeb, 3.56 kB⬇
-
🌐 scrollbars.jsWeb, 3.12 kB⬇
-
🌐 selection-manager.jsWeb, 3.76 kB⬇
-
🌐 settings-utils.jsWeb, 31.08 kB⬇
-
🌐 share.jsWeb, 10.75 kB⬇
-
🌐 side-drawer.jsWeb, 9.37 kB⬇
-
🌐 speech-text.jsWeb, 6.60 kB⬇
-
🌐 swipe-navigation.jsWeb, 6.16 kB⬇
-
🌐 table-overlay.jsWeb, 8.10 kB⬇
-
🌐 theme-utils.jsWeb, 8.34 kB⬇
-
🌐 thinking-panel-base.jsWeb, 14.88 kB⬇
-
🌐 ui-sets.jsWeb, 1.00 kB⬇
-
🌐 version-overlay.jsWeb, 4.63 kB⬇
import { scroller_of } from './scrollbars.js';
/**
* Shared grip-drag reorder controller used by the document, choices, and
* sticky notes editors. Owns the mechanics every editor repeats: container
* delegation of pointer events, pointer capture, drop-target highlighting
* via elementFromPoint, the requestAnimationFrame autoscroll loop, and the
* click guard that swallows the click a drag release produces.
*
* The editor supplies callbacks for the parts that differ: how a pointerdown
* resolves to a draggable element, what extra state identifies the drag
* (index, guids, kind), which scroll element autoscrolls, which element the
* pointer is over as drop target, which ancestor elements carry the drag
* chrome classes, and how a committed drop is applied to the model.
*
* @param {Object} options - The drag configuration.
* @param {Function} options.draggable_of - (e) => draggable element or null;
* decides whether a pointerdown starts a drag.
* @param {Function|null} [options.state_of=null] - (el, e) => state object
* merged into the drag record, or null to abort the drag.
* @param {Function} options.target_of - (x, y, drag) => drop target element
* or null; the helper toggles its drop-target class.
* @param {Function|null} [options.chrome_of=null] - (el) => array of
* [root, className] pairs carrying the dragging chrome (e.g. the list's
* dragging-items class) for the drag's duration.
* @param {Function} options.scroll_el_of - (el) => the element whose scroll
* container autoscrolls near the viewport edges.
* @param {Function} options.commit - (drag) => void; applies a committed
* drop. drag carries el, target_el, x, y plus the state_of fields.
* @returns {Object} { bind, take_click_guard } — bind attaches the pointer
* listeners to a container; take_click_guard reports and clears the guard
* raised by a drag release.
*/
export function create_reorder_drag(options) {
let drag = null;
let frame = 0;
let click_guard = false;
/**
* Highlights the drop target under the pointer, clearing the previous
* one.
*/
function update_target() {
const over = options.target_of(drag.x, drag.y, drag) || null;
if (over === drag.target_el) return;
drag.target_el?.classList.remove('drop-target');
drag.target_el = over;
over?.classList.add('drop-target');
}
/**
* Autoscrolls near the scroller's edges and refreshes the drop target,
* since scrolling moves content under a still pointer.
*/
function scroll_step() {
const scroll = scroller_of(options.scroll_el_of(drag.el));
if (scroll) {
const rect = scroll.getBoundingClientRect();
const edge = 48;
if (drag.y < rect.top + edge) scroll.scrollTop -= 12;
else if (drag.y > rect.bottom - edge) scroll.scrollTop += 12;
}
update_target();
frame = requestAnimationFrame(scroll_step);
}
/**
* Restores the editor chrome and, when committed, hands the drag record
* to the editor's commit callback. The click guard is always raised so
* the drag release cannot trigger other actions.
* @param {boolean} commit - Whether to apply the drop.
*/
function end(commit) {
if (!drag) return;
cancelAnimationFrame(frame);
frame = 0;
drag.target_el?.classList.remove('drop-target');
drag.el.classList.remove('dragging');
(options.chrome_of(drag.el) || []).forEach(([root, cls]) => root?.classList.remove(cls));
const finished = drag;
drag = null;
click_guard = true;
if (commit) options.commit(finished);
}
return {
/**
* Attaches the delegated pointer listeners to a container.
* @param {HTMLElement} container - The surface the draggable elements
* render into.
*/
bind(container) {
container.addEventListener('pointerdown', (e) => {
click_guard = false;
const el = options.draggable_of(e);
if (!el) return;
const state = options.state_of ? options.state_of(el, e) : null;
if (!state) return;
e.preventDefault();
drag = Object.assign({ el, target_el: null, x: e.clientX, y: e.clientY }, state);
try {
e.target.setPointerCapture(e.pointerId);
} catch {
// synthetic or already-released pointers cannot capture
}
el.classList.add('dragging');
(options.chrome_of(el) || []).forEach(([root, cls]) => root?.classList.add(cls));
update_target();
frame = requestAnimationFrame(scroll_step);
});
container.addEventListener('pointermove', (e) => {
if (!drag) return;
drag.x = e.clientX;
drag.y = e.clientY;
update_target();
});
container.addEventListener('pointerup', () => end(true));
container.addEventListener('pointercancel', () => end(false));
},
/**
* Reports whether a drag release consumed the last click, clearing
* the guard.
* @returns {boolean} True when the click should be swallowed.
*/
take_click_guard() {
if (!click_guard) return false;
click_guard = false;
return true;
}
};
}
drag-reorder.js
×
Type: Web, text/x-java
4.82 Kilobytes
Last Modified 2026-11-04 09:48:28
⬇ Download File
Type: Web, text/x-java
4.82 Kilobytes
Last Modified 2026-11-04 09:48:28
⬇ Download File