9.3 KiB
Drag & Drop Problem Analysis - File Drop + Web App Popup
Status: Phase 1 (File Drop) ✅ Implemented | Phase 2 (Popup Trigger) ⏸️ Planned
Last Updated: March 3, 2026
Overview
Current Implementation Status
✅ Phase 1 - File Drop (IMPLEMENTED)
- JavaScript in
bridge_script_intercept.jsintercepts drag events - Calls
window.bridge.start_file_drag(url)via QWebChannel to Qt - Validates path against whitelist via
PathValidator - Converts Azure Storage URLs to local paths via
URLConverter - Creates and executes native Qt file drag operation
- Target application (InDesign, Word, etc.) successfully receives file
⏸️ Phase 2 - Programmatic Popup Trigger (PLANNED)
- Would require reverse-engineering the web app's popup trigger mechanism
- Could be implemented by calling JavaScript function after successful drop
- Currently: Applications handle popups manually or separately from file drops
Das Kernproblem
- ✅ File gedroppt werden (Z:\ Laufwerk) → Native File-Drop
- ✅ Web-App Popup erscheinen (Auschecken-Dialog) → Web-App Drop-Event
Problem: Diese beiden schließen sich gegenseitig aus:
- Native File-Drag (von Qt) → Web-App bekommt kein Drop-Event → Kein Popup
- Browser Text-Drag (von Web-App) → Kein File-Drop → Kein File
Browser-Sicherheitsbeschränkungen
-
DataTransfer.files ist read-only
Wir können keine Files zu einem DataTransfer hinzufügen -
Nur EIN Drag zur Zeit möglich
Wir können keinen parallelen Drag starten -
DataTransfer kann nicht erstellt werden
Wir können kein synthetisches Drop-Event mit Files erzeugen -
Cross-Domain Sicherheit
File-Zugriff ist stark eingeschränkt
Getestete Ansätze
❌ Ansatz 1: DataTransfer erweitern
Idee: Web-App setzt URL, wir fügen Files hinzu
Problem: DataTransfer.files ist read-only
❌ Ansatz 2: Parallele Drags
Idee: Browser-Drag + Qt-Drag gleichzeitig
Problem: Nur ein Drag zur Zeit möglich
❌ Ansatz 3: Synthetisches Drop-Event
Idee: Original Drop abfangen, neues Event mit Files erzeugen
Problem: DataTransfer.files kann nicht gesetzt werden
⚠️ Ansatz 4: Native Drag + Event-Simulation
Idee: Qt Native Drag, dann Web-App Event manuell auslösen
Problem: Erfordert Kenntnis der exakten Web-App Event-Struktur (Angular CDK)
🎯 Praktikable Lösungen
Lösung A: Zwei-Phasen Ansatz (EMPFOHLEN für Testing)
Phase 1: File-Drop
- ALT-Drag startet
- JavaScript erkennt convertible URL
- Ruft Qt's
start_file_drag(url)auf preventDefault()verhindert Browser-Drag- Qt Native Drag läuft
- File wird gedroppt ✅
Phase 2: Popup manuell triggern 7. Nach erfolgreichem Drop (via Qt Signal) 8. JavaScript simuliert den Event/API-Call der das Popup auslöst 9. Popup erscheint ✅
Vorteile:
- ✅ Funktioniert garantiert für File-Drop
- ✅ Kontrolle über beide Phasen
- ✅ Kann debugged werden
Nachteile:
- ⚠️ Erfordert Reverse-Engineering des Popup-Triggers
- ⚠️ Könnte bei Web-App Updates brechen
Implementierung:
// Phase 1: Standard - File Drag
document.addEventListener('dragstart', function(e) {
if (!e.altKey) return;
// Extract URL from DataTransfer
var url = e.dataTransfer.getData('text/plain');
if (isConvertible(url)) {
e.preventDefault();
window.bridge.start_file_drag(url);
}
}, true);
// Phase 2: Popup Trigger (nach Drop-Erfolg)
// Qt ruft auf: window.trigger_checkout_popup(assetId)
window.trigger_checkout_popup = function(assetId) {
// Option 1: Klick auf Checkout-Button simulieren
// Option 2: API-Call direkt aufrufen
// Option 3: Angular-Event dispatchen
// Beispiel: Suche nach Angular-Component und rufe Methode auf
var angularComponent = findAngularComponent('ay-asset-card');
if (angularComponent) {
angularComponent.onCheckout(assetId);
}
};
TODO für diese Lösung:
- ✅ File-Drag funktioniert bereits
- ⏸️ Herausfinden wie Popup ausgelöst wird:
- Browser DevTools öffnen
- Network-Tab beobachten (API-Call?)
- Elements-Tab nutzen (Angular Component?)
- Event-Listeners ansehen
Lösung B: Gar nichts ändern beim Drag (FALLBACK)
Ansatz:
- ALT-Drag läuft normal durch (URL-Text wird gedroppt)
- Popup erscheint ✅
- Nach Popup-Bestätigung (Auschecken)
- DANN konvertieren wir die URL und kopieren das File
Vorteile:
- ✅ Web-App funktioniert normal
- ✅ Kein Popup-Problem
- ✅ Einfach zu implementieren
Nachteile:
- ⚠️ Kein echter Drag & Drop (nur Copy)
- ⚠️ User muss zweimal handeln
Lösung C: File-Drop via Qt Window Overlay (EXPERIMENTELL)
Ansatz:
- Beim ALT-Drag: Start Normal Web-App Drag
- Qt erstellt ein transparentes Overlay-Window über dem Browser
- Overlay fängt das Drop-Event ab
- Qt macht File-Drop
- Qt leitet Drop-Koordinaten an Browser weiter
- Browser bekommt synthetisches Event (ohne Files, nur Koordinaten)
- Popup erscheint
Vorteile:
- ✅ Beide Funktionen potentiell möglich
- ✅ Keine DataTransfer-Manipulation nötig
Nachteile:
- ⚠️ Sehr komplex
- ⚠️ Plattform-spezifisch (Windows)
- ⚠️ Performance-Overhead
🔬 Nächste Schritte - Reverse Engineering
Um Lösung A zu implementieren, müssen wir herausfinden:
1. Wie wird das Popup ausgelöst?
Debug-Schritte:
// In Browser Console ausführen während ALT-Drag+Drop
// Methode 1: Event-Listener finden
getEventListeners(document)
// Methode 2: Angular Component finden
var cards = document.querySelectorAll('ay-asset-card');
var component = ng.getComponent(cards[0]); // Angular DevTools
console.log(component);
// Methode 3: Network-Tab
// Schauen ob API-Call gemacht wird nach Drop
Erwartete Möglichkeiten:
- API-Call zu
/api/assets/{id}/checkout - Angular Event:
cdkDropListDropped - Component-Methode:
onAssetDropped()oder ähnlich - Modal-Service:
ModalService.show('checkout-dialog')
2. Asset-ID extrahieren
Die Asset-ID wird benötigt für den Popup-Trigger:
// Asset-ID ist wahrscheinlich in:
// - Element-ID: "anPGZszKzgKaSz1SIx2HFgduy"
// - Image-URL: "./GlobalDAM JRI_files/anPGZszKzgKaSz1SIx2HFgduy"
// - Data-Attribut: data-asset-id
function extractAssetId(element) {
// Aus Element-ID
if (element.id && element.id.match(/^a[A-Za-z0-9_-]+$/)) {
return element.id;
}
// Aus Bild-URL
var img = element.querySelector('img');
if (img && img.src) {
var match = img.src.match(/([A-Za-z0-9_-]{20,})/);
if (match) return match[1];
}
return null;
}
3. Popup programmatisch öffnen
Sobald wir wissen wie, implementieren wir:
# Python (Qt)
class DragBridge(QObject):
@Slot(str)
def on_file_dropped_success(self, local_path: str):
"""Called after successful file drop."""
# Extrahiere Asset-ID aus Pfad oder URL-Mapping
asset_id = self.extract_asset_id(local_path)
# Trigger Popup via JavaScript
js_code = f"window.trigger_checkout_popup('{asset_id}')"
self.web_view.page().runJavaScript(js_code)
⚡ Quick Win: Debugging aktivieren
Fügen Sie zu allen JavaScript-Varianten umfangreiches Logging hinzu:
// In bridge_script.js
// Log ALLE Events
['dragstart', 'drag', 'dragenter', 'dragover', 'drop', 'dragend'].forEach(function(eventName) {
document.addEventListener(eventName, function(e) {
console.log('[DEBUG]', eventName, {
target: e.target.tagName,
dataTransfer: {
types: e.dataTransfer.types,
effectAllowed: e.dataTransfer.effectAllowed,
dropEffect: e.dataTransfer.dropEffect
},
altKey: e.altKey,
coordinates: {x: e.clientX, y: e.clientY}
});
}, true);
});
// Log DataTransfer Zugriffe
Object.defineProperty(DataTransfer.prototype, 'types', {
get: function() {
var types = this._types || [];
console.log('[DEBUG] DataTransfer.types accessed:', types);
return types;
}
});
📝 Empfehlung
Current Status (as of March 2026)
✅ Phase 1 Complete:
- File-drop via native Qt drag operations is fully functional
- JavaScript bridge (
bridge_script_intercept.js) successfully intercepts and converts drags - Path validation and Azure URL mapping working
- Tested with real applications (InDesign, Word, etc.)
For Future Enhancement (Phase 2 - Popup Trigger)
If popup trigger integration is needed:
-
🔍 Reverse-Engineering the Target Web App:
- Identify how popups are triggered (API call, component method, event, etc.)
- Use browser DevTools:
- Network tab → Monitor API calls
- Console → Check for JavaScript errors/logs
- Elements → Inspect component structure
- Angular/Vue DevTools if applicable
-
🛠️ Implement Popup Trigger:
- Create JavaScript hook function (e.g.,
window.trigger_popup(assetId)) - Connect to drop success signal from Qt
- Call popup trigger after successful file drop
- Create JavaScript hook function (e.g.,
-
🧪 Test Integration:
- Verify file drops successfully
- Verify popup appears after drop
- Test with real assets/files
Alternative Approaches:
- Lösung B (Manual): Keep file drop and popup as separate user actions
- Lösung C (Complex): Use overlay window approach (more involved)
Current implementation uses Phase 1 of Lösung A and is production-ready.