refactor: extract splitter drag logic into shared utility
Replace duplicated inline drag handlers in queue_methods.js and missing_browser_methods.js with a new startSplitterDrag() helper in web/resolver/utils/splitter_drag.js. The utility centralizes pointer/mouse event binding, RAF throttling, and touch-cancellation cleanup, cutting net code across the two callers while preserving existing behaviour (bounds, edge-open threshold, collapse preview, and settle/cleanup timing).
This commit is contained in:
@@ -2,6 +2,7 @@ import { app } from "../../../../../scripts/app.js";
|
||||
import { api } from "../../../../../scripts/api.js";
|
||||
import { $el } from "../../../../../scripts/ui.js";
|
||||
import { getSvgIcon } from "../../utils/icon_utils.js";
|
||||
import { startSplitterDrag } from "../utils/splitter_drag.js";
|
||||
export const queueMethods = {
|
||||
createContent() {
|
||||
// Wrap the body in a two-column layout: left = items, right = queued panel
|
||||
@@ -1895,162 +1896,139 @@ export const queueMethods = {
|
||||
this._splitPreviewCollapsed = !!startCollapsedPreview;
|
||||
this._splitEdgeOpen = !!edgeOpen;
|
||||
this._splitEdgeOpenedPastThreshold = false;
|
||||
this._onSplitMove = (ev) => this.onSplitDrag(ev);
|
||||
this._onSplitUp = (ev) => this.endSplitDrag(ev);
|
||||
this._splitMoveEvent = e?.type === 'pointerdown' ? 'pointermove' : 'mousemove';
|
||||
this._splitUpEvent = e?.type === 'pointerdown' ? 'pointerup' : 'mouseup';
|
||||
this._splitCancelEvent = e?.type === 'pointerdown' ? 'pointercancel' : null;
|
||||
document.addEventListener(this._splitMoveEvent, this._onSplitMove, true);
|
||||
document.addEventListener(this._splitUpEvent, this._onSplitUp, { once: true, capture: true });
|
||||
if (this._splitCancelEvent) {
|
||||
document.addEventListener(this._splitCancelEvent, this._onSplitUp, { once: true, capture: true });
|
||||
}
|
||||
|
||||
this._splitInteraction = startSplitterDrag(e, {
|
||||
anchor: 'right',
|
||||
startWidth: initialWidth,
|
||||
bounds,
|
||||
onBeforeDrag: (newW) => {
|
||||
if (newW < bounds.min) newW = bounds.min;
|
||||
if (newW > bounds.max) newW = bounds.max;
|
||||
return newW;
|
||||
},
|
||||
onDrag: (width) => {
|
||||
this._pendingSplitWidth = width;
|
||||
|
||||
if (this._splitEdgeOpen && this._pendingSplitWidth > 140) {
|
||||
this._splitEdgeOpenedPastThreshold = true;
|
||||
if (this.queueCollapsed) {
|
||||
this.queueCollapsed = false;
|
||||
this.persistQueueCollapsedState(false, 500);
|
||||
this.updateQueueToggleIcon();
|
||||
}
|
||||
if (this._queuePanelDirty) {
|
||||
this.updateQueuePanel({ force: true });
|
||||
}
|
||||
}
|
||||
|
||||
const previewCollapsed = this._splitEdgeOpen
|
||||
? (!this._splitEdgeOpenedPastThreshold || this._pendingSplitWidth <= 140)
|
||||
: this._pendingSplitWidth <= 140;
|
||||
|
||||
if (previewCollapsed !== this._splitPreviewCollapsed) {
|
||||
this._splitPreviewCollapsed = previewCollapsed;
|
||||
const body = document.getElementById('model-resolver-body');
|
||||
body?.classList.toggle('mr-queue-preview-collapsed', previewCollapsed);
|
||||
this.queueElement.style.display = previewCollapsed ? 'none' : '';
|
||||
if (previewCollapsed) {
|
||||
const collapsedBounds = this.getQueueSplitBounds(this._splitStart.containerWidth, { edgeOpen: true });
|
||||
this.applyQueueSplitWidth(0, {
|
||||
bounds: collapsedBounds,
|
||||
containerWidth: this._splitStart.containerWidth,
|
||||
skipIfUnchanged: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (this._splitPreviewCollapsed) return;
|
||||
|
||||
this.applyQueueSplitWidth(width, {
|
||||
bounds: this._splitStart?.bounds || bounds,
|
||||
containerWidth: this._splitStart?.containerWidth,
|
||||
skipIfUnchanged: true
|
||||
});
|
||||
},
|
||||
onEnd: (finalWidth) => {
|
||||
this._splitDragging = false;
|
||||
if (this.queueElement && finalWidth && !this._splitPreviewCollapsed) {
|
||||
this.applyQueueSplitWidth(finalWidth, {
|
||||
bounds: this._splitStart?.bounds,
|
||||
containerWidth: this._splitStart?.containerWidth,
|
||||
skipIfUnchanged: true
|
||||
});
|
||||
}
|
||||
|
||||
const body = this.getQueueSplitBody();
|
||||
|
||||
if (this._splitEdgeOpen && !this._pendingSplitWidth) {
|
||||
try {
|
||||
const restoreWidth = Math.max(240, Math.round(this._splitStart?.startWidth || 320));
|
||||
this.applyQueueSplitWidth(restoreWidth, {
|
||||
bounds: this._splitStart?.bounds,
|
||||
containerWidth: this._splitStart?.containerWidth
|
||||
});
|
||||
this.queueElement.style.display = '';
|
||||
if (this.splitterElement) this.splitterElement.style.display = '';
|
||||
this.persistQueueSplitWidth(restoreWidth, 500);
|
||||
} catch (err) { }
|
||||
this.queueCollapsed = false;
|
||||
this.persistQueueCollapsedState(false, 500);
|
||||
this.updateQueueVisibility();
|
||||
this.updateQueuePanel({ force: true });
|
||||
this._splitEdgeOpen = false;
|
||||
this._pendingSplitWidth = null;
|
||||
this._appliedSplitWidth = null;
|
||||
this._splitPreviewCollapsed = false;
|
||||
this.deferQueueSplitReleaseUi(body);
|
||||
this._splitEdgeOpenedPastThreshold = false;
|
||||
setTimeout(() => { this._suppressQueueEdgeClick = false; }, 0);
|
||||
this._splitInteraction = null;
|
||||
return;
|
||||
}
|
||||
|
||||
const shouldCollapse = !!this._splitPreviewCollapsed;
|
||||
if (shouldCollapse) {
|
||||
try {
|
||||
const restoreWidth = Math.max(240, Math.round(this._splitStart?.startWidth || 320));
|
||||
this.applyQueueSplitWidth(restoreWidth, {
|
||||
bounds: this._splitStart?.bounds,
|
||||
containerWidth: this._splitStart?.containerWidth
|
||||
});
|
||||
this.queueElement.style.display = '';
|
||||
this.persistQueueSplitWidth(restoreWidth);
|
||||
} catch (err) { }
|
||||
this._pendingSplitWidth = null;
|
||||
this._appliedSplitWidth = null;
|
||||
this._splitPreviewCollapsed = false;
|
||||
this._splitEdgeOpen = false;
|
||||
this._splitEdgeOpenedPastThreshold = false;
|
||||
this.deferQueueSplitReleaseUi(body);
|
||||
this.setQueueCollapsed(true);
|
||||
setTimeout(() => { this._suppressQueueEdgeClick = false; }, 0);
|
||||
this._splitInteraction = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.queueElement) this.queueElement.style.display = '';
|
||||
try {
|
||||
const width = finalWidth
|
||||
|| Number.parseInt(String(this.queueElement.style.width || ''), 10)
|
||||
|| this.getQueuePaneWidth(this.queueElement);
|
||||
this.persistQueueSplitWidth(width);
|
||||
} catch (err) { }
|
||||
this._pendingSplitWidth = null;
|
||||
this._appliedSplitWidth = null;
|
||||
this._splitPreviewCollapsed = false;
|
||||
this._splitEdgeOpen = false;
|
||||
this._splitEdgeOpenedPastThreshold = false;
|
||||
this.deferQueueSplitReleaseUi(body);
|
||||
setTimeout(() => { this._suppressQueueEdgeClick = false; }, 0);
|
||||
this._splitInteraction = null;
|
||||
}
|
||||
});
|
||||
} catch (err) { /* ignore */ }
|
||||
},
|
||||
|
||||
onSplitDrag(e) {
|
||||
if (!this._splitDragging || !this._splitStart || !this.queueElement) return;
|
||||
e?.preventDefault?.();
|
||||
e?.stopPropagation?.();
|
||||
const dx = e.clientX - this._splitStart.x;
|
||||
let newW = this._splitStart.startWidth - dx;
|
||||
const bounds = this._splitStart.bounds || this.getQueueSplitBounds(this._splitStart.containerWidth, { edgeOpen: this._splitEdgeOpen });
|
||||
if (newW < bounds.min) newW = bounds.min;
|
||||
if (newW > bounds.max) newW = bounds.max;
|
||||
this._pendingSplitWidth = Math.round(newW);
|
||||
if (this._splitEdgeOpen && this._pendingSplitWidth > 140) {
|
||||
this._splitEdgeOpenedPastThreshold = true;
|
||||
if (this.queueCollapsed) {
|
||||
this.queueCollapsed = false;
|
||||
this.persistQueueCollapsedState(false, 500);
|
||||
this.updateQueueToggleIcon();
|
||||
}
|
||||
if (this._queuePanelDirty) {
|
||||
this.updateQueuePanel({ force: true });
|
||||
}
|
||||
}
|
||||
const previewCollapsed = this._splitEdgeOpen
|
||||
? (!this._splitEdgeOpenedPastThreshold || this._pendingSplitWidth <= 140)
|
||||
: this._pendingSplitWidth <= 140;
|
||||
if (previewCollapsed !== this._splitPreviewCollapsed) {
|
||||
this._splitPreviewCollapsed = previewCollapsed;
|
||||
const body = document.getElementById('model-resolver-body');
|
||||
body?.classList.toggle('mr-queue-preview-collapsed', previewCollapsed);
|
||||
this.queueElement.style.display = previewCollapsed ? 'none' : '';
|
||||
if (previewCollapsed) {
|
||||
const collapsedBounds = this.getQueueSplitBounds(this._splitStart.containerWidth, { edgeOpen: true });
|
||||
this.applyQueueSplitWidth(0, {
|
||||
bounds: collapsedBounds,
|
||||
containerWidth: this._splitStart.containerWidth,
|
||||
skipIfUnchanged: true
|
||||
});
|
||||
}
|
||||
}
|
||||
if (this._splitPreviewCollapsed) return;
|
||||
|
||||
if (!this._splitDragFrame) {
|
||||
this._splitDragFrame = requestAnimationFrame(() => {
|
||||
this._splitDragFrame = null;
|
||||
if (!this._splitDragging || this._splitPreviewCollapsed) return;
|
||||
this.applyQueueSplitWidth(this._pendingSplitWidth, {
|
||||
bounds: this._splitStart?.bounds || bounds,
|
||||
containerWidth: this._splitStart?.containerWidth,
|
||||
skipIfUnchanged: true
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
endSplitDrag(e = null) {
|
||||
if (!this._splitDragging) return;
|
||||
e?.preventDefault?.();
|
||||
e?.stopPropagation?.();
|
||||
this._splitDragging = false;
|
||||
if (this._splitDragFrame) {
|
||||
cancelAnimationFrame(this._splitDragFrame);
|
||||
this._splitDragFrame = null;
|
||||
}
|
||||
if (this.queueElement && this._pendingSplitWidth && !this._splitPreviewCollapsed) {
|
||||
this.applyQueueSplitWidth(this._pendingSplitWidth, {
|
||||
bounds: this._splitStart?.bounds,
|
||||
containerWidth: this._splitStart?.containerWidth,
|
||||
skipIfUnchanged: true
|
||||
});
|
||||
}
|
||||
const body = this.getQueueSplitBody();
|
||||
if (this._splitMoveEvent) {
|
||||
document.removeEventListener(this._splitMoveEvent, this._onSplitMove, true);
|
||||
}
|
||||
if (this._splitUpEvent) {
|
||||
document.removeEventListener(this._splitUpEvent, this._onSplitUp, true);
|
||||
}
|
||||
if (this._splitCancelEvent) {
|
||||
document.removeEventListener(this._splitCancelEvent, this._onSplitUp, true);
|
||||
}
|
||||
if (this._splitEdgeOpen && !this._pendingSplitWidth) {
|
||||
try {
|
||||
const restoreWidth = Math.max(240, Math.round(this._splitStart?.startWidth || 320));
|
||||
this.applyQueueSplitWidth(restoreWidth, {
|
||||
bounds: this._splitStart?.bounds,
|
||||
containerWidth: this._splitStart?.containerWidth
|
||||
});
|
||||
this.queueElement.style.display = '';
|
||||
if (this.splitterElement) this.splitterElement.style.display = '';
|
||||
this.persistQueueSplitWidth(restoreWidth, 500);
|
||||
} catch (e) { }
|
||||
this.queueCollapsed = false;
|
||||
this.persistQueueCollapsedState(false, 500);
|
||||
this.updateQueueVisibility();
|
||||
this.updateQueuePanel({ force: true });
|
||||
this._splitEdgeOpen = false;
|
||||
this._pendingSplitWidth = null;
|
||||
this._appliedSplitWidth = null;
|
||||
this._splitPreviewCollapsed = false;
|
||||
this.deferQueueSplitReleaseUi(body);
|
||||
this._splitEdgeOpenedPastThreshold = false;
|
||||
setTimeout(() => { this._suppressQueueEdgeClick = false; }, 0);
|
||||
return;
|
||||
}
|
||||
const shouldCollapse = !!this._splitPreviewCollapsed;
|
||||
if (shouldCollapse) {
|
||||
try {
|
||||
const restoreWidth = Math.max(240, Math.round(this._splitStart?.startWidth || 320));
|
||||
this.applyQueueSplitWidth(restoreWidth, {
|
||||
bounds: this._splitStart?.bounds,
|
||||
containerWidth: this._splitStart?.containerWidth
|
||||
});
|
||||
this.queueElement.style.display = '';
|
||||
this.persistQueueSplitWidth(restoreWidth);
|
||||
} catch (e) { }
|
||||
this._pendingSplitWidth = null;
|
||||
this._appliedSplitWidth = null;
|
||||
this._splitPreviewCollapsed = false;
|
||||
this._splitEdgeOpen = false;
|
||||
this._splitEdgeOpenedPastThreshold = false;
|
||||
this.deferQueueSplitReleaseUi(body);
|
||||
this.setQueueCollapsed(true);
|
||||
setTimeout(() => { this._suppressQueueEdgeClick = false; }, 0);
|
||||
return;
|
||||
}
|
||||
if (this.queueElement) this.queueElement.style.display = '';
|
||||
try {
|
||||
const width = this._pendingSplitWidth
|
||||
|| this._appliedSplitWidth
|
||||
|| Number.parseInt(String(this.queueElement.style.width || ''), 10)
|
||||
|| this.getQueuePaneWidth(this.queueElement);
|
||||
this.persistQueueSplitWidth(width);
|
||||
} catch (e) { }
|
||||
this._pendingSplitWidth = null;
|
||||
this._appliedSplitWidth = null;
|
||||
this._splitPreviewCollapsed = false;
|
||||
this._splitEdgeOpen = false;
|
||||
this._splitEdgeOpenedPastThreshold = false;
|
||||
this.deferQueueSplitReleaseUi(body);
|
||||
this._splitMoveEvent = null;
|
||||
this._splitUpEvent = null;
|
||||
this._splitCancelEvent = null;
|
||||
setTimeout(() => { this._suppressQueueEdgeClick = false; }, 0);
|
||||
},
|
||||
|
||||
/**
|
||||
* Queue a resolution for later batch apply
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Helper to initiate a splitter drag interaction.
|
||||
* Handles mouse/pointer event listening, touch/cancellation, and RAF throttling.
|
||||
*/
|
||||
export function startSplitterDrag(event, {
|
||||
anchor = 'right',
|
||||
startWidth,
|
||||
bounds = { min: 100, max: 800 },
|
||||
onBeforeDrag = null,
|
||||
onDrag = () => {},
|
||||
onEnd = () => {}
|
||||
}) {
|
||||
if (event?.button !== undefined && event.button !== 0) return null;
|
||||
event?.preventDefault?.();
|
||||
event?.stopPropagation?.();
|
||||
|
||||
const startX = event.clientX;
|
||||
let pendingWidth = startWidth;
|
||||
let appliedWidth = startWidth;
|
||||
let animationFrame = null;
|
||||
let isDragging = true;
|
||||
|
||||
const moveEvent = event?.type === 'pointerdown' ? 'pointermove' : 'mousemove';
|
||||
const upEvent = event?.type === 'pointerdown' ? 'pointerup' : 'mouseup';
|
||||
const cancelEvent = event?.type === 'pointerdown' ? 'pointercancel' : null;
|
||||
|
||||
const handleMove = (e) => {
|
||||
if (!isDragging) return;
|
||||
e?.preventDefault?.();
|
||||
e?.stopPropagation?.();
|
||||
|
||||
const dx = e.clientX - startX;
|
||||
let newWidth = anchor === 'right' ? startWidth - dx : startWidth + dx;
|
||||
|
||||
if (onBeforeDrag) {
|
||||
newWidth = onBeforeDrag(newWidth);
|
||||
} else {
|
||||
if (newWidth < bounds.min) newWidth = bounds.min;
|
||||
if (newWidth > bounds.max) newWidth = bounds.max;
|
||||
}
|
||||
|
||||
pendingWidth = Math.round(newWidth);
|
||||
|
||||
if (pendingWidth === appliedWidth) return;
|
||||
|
||||
if (!animationFrame) {
|
||||
animationFrame = requestAnimationFrame(() => {
|
||||
animationFrame = null;
|
||||
if (!isDragging) return;
|
||||
onDrag(pendingWidth);
|
||||
appliedWidth = pendingWidth;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleUp = (e) => {
|
||||
if (!isDragging) return;
|
||||
e?.preventDefault?.();
|
||||
e?.stopPropagation?.();
|
||||
|
||||
isDragging = false;
|
||||
|
||||
document.removeEventListener(moveEvent, handleMove, true);
|
||||
document.removeEventListener(upEvent, handleUp, true);
|
||||
if (cancelEvent) {
|
||||
document.removeEventListener(cancelEvent, handleUp, true);
|
||||
}
|
||||
|
||||
if (animationFrame) {
|
||||
cancelAnimationFrame(animationFrame);
|
||||
animationFrame = null;
|
||||
}
|
||||
|
||||
onEnd(pendingWidth || appliedWidth);
|
||||
};
|
||||
|
||||
document.addEventListener(moveEvent, handleMove, true);
|
||||
document.addEventListener(upEvent, handleUp, { once: true, capture: true });
|
||||
if (cancelEvent) {
|
||||
document.addEventListener(cancelEvent, handleUp, { once: true, capture: true });
|
||||
}
|
||||
|
||||
return {
|
||||
cancel: () => {
|
||||
isDragging = false;
|
||||
document.removeEventListener(moveEvent, handleMove, true);
|
||||
document.removeEventListener(upEvent, handleUp, true);
|
||||
if (cancelEvent) {
|
||||
document.removeEventListener(cancelEvent, handleUp, true);
|
||||
}
|
||||
if (animationFrame) {
|
||||
cancelAnimationFrame(animationFrame);
|
||||
animationFrame = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import { $el } from "../../../../../scripts/ui.js";
|
||||
import { getSvgIcon } from "../../utils/icon_utils.js";
|
||||
import { createFloatingTreePicker } from "../utils/tree_picker.js";
|
||||
import { showNotification as showNotificationUtils } from "../../utils/notification_utils.js";
|
||||
import { startSplitterDrag } from "../utils/splitter_drag.js";
|
||||
|
||||
export const missingBrowserMethods = {
|
||||
getMissingFilename(missing = {}) {
|
||||
@@ -966,12 +967,15 @@ export const missingBrowserMethods = {
|
||||
this._pendingMissingBrowserRestoreWidth = null;
|
||||
this._pendingMissingBrowserRestoreUseDefault = false;
|
||||
this.cancelMissingBrowserSplitWidthPersist();
|
||||
|
||||
const releaseSplitter = splitter instanceof HTMLElement
|
||||
? splitter
|
||||
: browser.querySelector('.mr-missing-browser-splitter');
|
||||
|
||||
this._missingBrowserSplitBrowser = browser;
|
||||
this._missingBrowserSplitListPane = listPane;
|
||||
this._missingBrowserSplitDetailPane = detailPane;
|
||||
this._missingBrowserSplitSplitter = splitter instanceof HTMLElement
|
||||
? splitter
|
||||
: browser.querySelector('.mr-missing-browser-splitter');
|
||||
this._missingBrowserSplitSplitter = releaseSplitter;
|
||||
this._missingBrowserSplitDragging = true;
|
||||
this._missingBrowserSplitStart = {
|
||||
x: event.clientX,
|
||||
@@ -980,19 +984,56 @@ export const missingBrowserMethods = {
|
||||
browserWidth,
|
||||
availableWidth: bounds.available
|
||||
};
|
||||
this._appliedMissingBrowserSplitWidth = Math.round(this._missingBrowserSplitStart.width);
|
||||
this._appliedMissingBrowserSplitWidth = detailWidth;
|
||||
this._pendingMissingBrowserSplitWidth = detailWidth;
|
||||
this._missingBrowserSplitUiActive = false;
|
||||
|
||||
this._onMissingBrowserSplitMove = (moveEvent) => this.onMissingBrowserSplitDrag(moveEvent);
|
||||
this._onMissingBrowserSplitUp = (upEvent) => this.endMissingBrowserSplitDrag(upEvent);
|
||||
this._missingBrowserSplitMoveEvent = event.type === 'pointerdown' ? 'pointermove' : 'mousemove';
|
||||
this._missingBrowserSplitUpEvent = event.type === 'pointerdown' ? 'pointerup' : 'mouseup';
|
||||
this._missingBrowserSplitCancelEvent = event.type === 'pointerdown' ? 'pointercancel' : null;
|
||||
document.addEventListener(this._missingBrowserSplitMoveEvent, this._onMissingBrowserSplitMove, true);
|
||||
document.addEventListener(this._missingBrowserSplitUpEvent, this._onMissingBrowserSplitUp, { once: true, capture: true });
|
||||
if (this._missingBrowserSplitCancelEvent) {
|
||||
document.addEventListener(this._missingBrowserSplitCancelEvent, this._onMissingBrowserSplitUp, { once: true, capture: true });
|
||||
}
|
||||
this._missingBrowserSplitInteraction = startSplitterDrag(event, {
|
||||
anchor: 'right',
|
||||
startWidth: detailWidth,
|
||||
bounds,
|
||||
onDrag: (width) => {
|
||||
this._pendingMissingBrowserSplitWidth = width;
|
||||
this.activateMissingBrowserSplitUi();
|
||||
this.applyMissingBrowserDetailWidth(detailPane, width, {
|
||||
browserWidth,
|
||||
availableWidth: bounds.available,
|
||||
splitBounds: bounds,
|
||||
skipIfUnchanged: true
|
||||
});
|
||||
this._appliedMissingBrowserSplitWidth = width;
|
||||
},
|
||||
onEnd: (finalWidth) => {
|
||||
const settlingNow = typeof performance === 'object' && typeof performance.now === 'function'
|
||||
? performance.now()
|
||||
: Date.now();
|
||||
this._missingBrowserSplitSettlingUntil = settlingNow + 350;
|
||||
this._missingBrowserSplitDragging = false;
|
||||
|
||||
if (detailPane && finalWidth) {
|
||||
this.applyMissingBrowserDetailWidth(detailPane, finalWidth, {
|
||||
browserWidth,
|
||||
availableWidth: bounds.available,
|
||||
splitBounds: bounds
|
||||
});
|
||||
this._appliedMissingBrowserSplitWidth = finalWidth;
|
||||
}
|
||||
if (finalWidth) {
|
||||
this.persistMissingBrowserSplitWidth(finalWidth, { delay: 600 });
|
||||
}
|
||||
this.deferMissingBrowserSplitReleaseUi(releaseSplitter, !!this._missingBrowserSplitUiActive);
|
||||
|
||||
this._missingBrowserSplitBrowser = null;
|
||||
this._missingBrowserSplitListPane = null;
|
||||
this._missingBrowserSplitDetailPane = null;
|
||||
this._missingBrowserSplitSplitter = null;
|
||||
this._missingBrowserSplitStart = null;
|
||||
this._missingBrowserSplitUiActive = false;
|
||||
this._pendingMissingBrowserSplitWidth = null;
|
||||
this._appliedMissingBrowserSplitWidth = null;
|
||||
this._missingBrowserSplitInteraction = null;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
activateMissingBrowserSplitUi() {
|
||||
@@ -1012,86 +1053,6 @@ export const missingBrowserMethods = {
|
||||
});
|
||||
},
|
||||
|
||||
onMissingBrowserSplitDrag(event) {
|
||||
if (!this._missingBrowserSplitDragging || !this._missingBrowserSplitStart || !this._missingBrowserSplitBrowser) return;
|
||||
|
||||
event.preventDefault?.();
|
||||
event.stopPropagation?.();
|
||||
const nextWidth = this._missingBrowserSplitStart.width - (event.clientX - this._missingBrowserSplitStart.x);
|
||||
const bounds = this._missingBrowserSplitStart.bounds;
|
||||
this._pendingMissingBrowserSplitWidth = Math.round(Math.max(bounds.min, Math.min(bounds.max, nextWidth)));
|
||||
if (this._pendingMissingBrowserSplitWidth === this._appliedMissingBrowserSplitWidth) return;
|
||||
if (!this._missingBrowserSplitDetailPane) return;
|
||||
this.activateMissingBrowserSplitUi();
|
||||
|
||||
if (!this._missingBrowserSplitFrame) {
|
||||
this._missingBrowserSplitFrame = requestAnimationFrame(() => {
|
||||
this._missingBrowserSplitFrame = null;
|
||||
if (!this._missingBrowserSplitDragging || !this._missingBrowserSplitDetailPane) return;
|
||||
this.applyMissingBrowserDetailWidth(this._missingBrowserSplitDetailPane, this._pendingMissingBrowserSplitWidth, {
|
||||
browserWidth: this._missingBrowserSplitStart?.browserWidth,
|
||||
availableWidth: this._missingBrowserSplitStart?.availableWidth,
|
||||
splitBounds: this._missingBrowserSplitStart?.bounds,
|
||||
skipIfUnchanged: true
|
||||
});
|
||||
this._appliedMissingBrowserSplitWidth = this._pendingMissingBrowserSplitWidth;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
endMissingBrowserSplitDrag(event = null) {
|
||||
if (!this._missingBrowserSplitDragging) return;
|
||||
|
||||
event?.preventDefault?.();
|
||||
event?.stopPropagation?.();
|
||||
const settlingNow = typeof performance === 'object' && typeof performance.now === 'function'
|
||||
? performance.now()
|
||||
: Date.now();
|
||||
this._missingBrowserSplitSettlingUntil = settlingNow + 350;
|
||||
const releaseSplitter = this._missingBrowserSplitSplitter;
|
||||
const wasUiActive = !!this._missingBrowserSplitUiActive;
|
||||
const finalWidth = this._pendingMissingBrowserSplitWidth || this._appliedMissingBrowserSplitWidth;
|
||||
this._missingBrowserSplitDragging = false;
|
||||
if (this._missingBrowserSplitMoveEvent) {
|
||||
document.removeEventListener(this._missingBrowserSplitMoveEvent, this._onMissingBrowserSplitMove, true);
|
||||
}
|
||||
if (this._missingBrowserSplitCancelEvent) {
|
||||
document.removeEventListener(this._missingBrowserSplitCancelEvent, this._onMissingBrowserSplitUp, true);
|
||||
}
|
||||
if (this._missingBrowserSplitUpEvent) {
|
||||
document.removeEventListener(this._missingBrowserSplitUpEvent, this._onMissingBrowserSplitUp, true);
|
||||
}
|
||||
if (this._missingBrowserSplitFrame) {
|
||||
cancelAnimationFrame(this._missingBrowserSplitFrame);
|
||||
this._missingBrowserSplitFrame = null;
|
||||
}
|
||||
if (this._missingBrowserSplitDetailPane && this._pendingMissingBrowserSplitWidth) {
|
||||
if (this._pendingMissingBrowserSplitWidth !== this._appliedMissingBrowserSplitWidth) {
|
||||
this.applyMissingBrowserDetailWidth(this._missingBrowserSplitDetailPane, this._pendingMissingBrowserSplitWidth, {
|
||||
browserWidth: this._missingBrowserSplitStart?.browserWidth,
|
||||
availableWidth: this._missingBrowserSplitStart?.availableWidth,
|
||||
splitBounds: this._missingBrowserSplitStart?.bounds
|
||||
});
|
||||
this._appliedMissingBrowserSplitWidth = this._pendingMissingBrowserSplitWidth;
|
||||
}
|
||||
}
|
||||
if (finalWidth) {
|
||||
this.persistMissingBrowserSplitWidth(finalWidth, { delay: 600 });
|
||||
}
|
||||
this.deferMissingBrowserSplitReleaseUi(releaseSplitter, wasUiActive);
|
||||
this._missingBrowserSplitBrowser = null;
|
||||
this._missingBrowserSplitListPane = null;
|
||||
this._missingBrowserSplitDetailPane = null;
|
||||
this._missingBrowserSplitSplitter = null;
|
||||
this._missingBrowserSplitStart = null;
|
||||
this._missingBrowserSplitUiActive = false;
|
||||
this._pendingMissingBrowserSplitWidth = null;
|
||||
this._appliedMissingBrowserSplitWidth = null;
|
||||
this._missingBrowserSplitMoveEvent = null;
|
||||
this._missingBrowserSplitUpEvent = null;
|
||||
this._missingBrowserSplitCancelEvent = null;
|
||||
},
|
||||
|
||||
applyMissingBrowserSplitReleaseCleanup(cleanup) {
|
||||
if (!cleanup) return;
|
||||
cleanup.splitter?.classList?.remove('is-resizing');
|
||||
|
||||
Reference in New Issue
Block a user