Fix file picker double-open across all remaining tools
Same defensive guard as legal-analysis + summarize, now applied to the upload-zone and audio-zone handlers in tools.js. Affects redact, timeline, and transcribe (which all share these zones via tools.js's setupUpload / setupAudioUpload). Stops native label-for clicks and the input's own click from bubbling into the zone handler that would otherwise programmatically re-open the picker. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+16
-3
@@ -1180,9 +1180,16 @@ function setupUpload() {
|
|||||||
if (e.dataTransfer?.files?.length) handleFiles(e.dataTransfer.files);
|
if (e.dataTransfer?.files?.length) handleFiles(e.dataTransfer.files);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Stop label-for and the input itself from bubbling into the zone click
|
||||||
|
// handler — otherwise the picker opens twice (native + programmatic).
|
||||||
|
const _uploadLabel = els.uploadZone.querySelector('label[for="' + els.uploadInput.id + '"]');
|
||||||
|
if (_uploadLabel) _uploadLabel.addEventListener('click', (e) => e.stopPropagation());
|
||||||
|
els.uploadInput.addEventListener('click', (e) => e.stopPropagation());
|
||||||
els.uploadZone.addEventListener('click', (e) => {
|
els.uploadZone.addEventListener('click', (e) => {
|
||||||
if (e.target === els.uploadClear || els.uploadClear?.contains(e.target)) return;
|
if (e.target === els.uploadClear || els.uploadClear?.contains(e.target)) return;
|
||||||
if (e.target.tagName === 'LABEL') return;
|
if (e.target === els.uploadInput) return;
|
||||||
|
const lbl = e.target.closest && e.target.closest('label');
|
||||||
|
if (lbl && lbl.getAttribute('for') === els.uploadInput.id) return;
|
||||||
els.uploadInput.click();
|
els.uploadInput.click();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2268,11 +2275,17 @@ function setupAudio() {
|
|||||||
if (e.dataTransfer?.files?.length) handleAudioFiles(e.dataTransfer.files);
|
if (e.dataTransfer?.files?.length) handleAudioFiles(e.dataTransfer.files);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Stop label-for and the input itself from bubbling into the zone click
|
||||||
|
// handler — otherwise the picker opens twice (native + programmatic).
|
||||||
|
const _audioLabel = els.audioZone.querySelector('label[for="' + els.audioInput.id + '"]');
|
||||||
|
if (_audioLabel) _audioLabel.addEventListener('click', (e) => e.stopPropagation());
|
||||||
|
els.audioInput.addEventListener('click', (e) => e.stopPropagation());
|
||||||
els.audioZone.addEventListener('click', (e) => {
|
els.audioZone.addEventListener('click', (e) => {
|
||||||
if (e.target === els.audioClear || els.audioClear?.contains(e.target)) return;
|
if (e.target === els.audioClear || els.audioClear?.contains(e.target)) return;
|
||||||
if (e.target === els.audioInput) return;
|
if (e.target === els.audioInput) return;
|
||||||
if (e.target.tagName === 'LABEL') return;
|
const lbl = e.target.closest && e.target.closest('label');
|
||||||
if (e.target.closest('#audioFileInfo') && e.target.tagName !== 'LABEL') return;
|
if (lbl && lbl.getAttribute('for') === els.audioInput.id) return;
|
||||||
|
if (e.target.closest('#audioFileInfo')) return;
|
||||||
els.audioInput.click();
|
els.audioInput.click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user