Das UXP Developer Tool

Bevor es aber losgeht, ein Lesetipp: Marc Autret hat gerade in einem Blogbeitrag auf indiscripts.com die aktuellen Ressourcen zum InDesign-UXP-Scripting zusammengestellt.

Nach den ersten UXP-Schritten möchte ich nun das UXP Developer Tool für das Debugging von Skripten vorstellen. Wer noch das veraltete ExtendScript Toolkit bzw. das nachfolgende Plugin für Visual Studio Code kennt, wünscht sich vermutlich die gleiche Anbindung für die Entwicklung von UXP-Skripten. Visual Studio Code selbst hat bereits einen integrierten JavaScript-Debugger, der für V8-Engine-Kontexte funktioniert. Rein technisch gesehen müsste Visual Studio Code also in der Lage sein, UXP sofort zu debuggen. Das klappt aber (noch?) nicht. Leider habe ich auch keine Informationen, ob diese Anbindung geplant ist.

Stattdessen bietet Adobe das sogenannte UXP Developer Tool (UDT) an. Der Fokus des Tools ist die Verwaltung von Plugins, wie sie bereits für Photoshop oder Adobe XD entwickelt werden können. InDesign unterstützt aktuell aber nur UXP Scripting, d.h. wir benötigen vom UDT auch nur den Bereich zum Debugging von Skripten.

Installation

Das Adobe UXP Developer Tool kann über die Adobe Creative Cloud-Anwendung installiert werden. Die Systemvoraussetzungen sind vermutlich bei den Meisten erfüllt. Eine ausführliche Anleitung findet ihr bei Adobe. In Kürze:

  • Creative Cloud Desktop Anwendung starten.
  • Alle Applikationen auswählen.
  • In der Liste sollte das UDT auftauchen.
  • Installieren auswählen.

WICHTIG: Das Adobe UXP Developer Tool benötigt Administratorrechte, um korrekt zu funktionieren. Wenn dein Administrator dir keine erweiterten Rechte einräumt, kannst du dieses Tool nicht verwenden.

Und los…

Nacht der Installation startest du InDesign und dann das UXP Developer Tool. Wenn im Bereich Connected Apps kein Eintrag für InDesign zu sehen ist, überprüfe, ob InDesign auch gestartet ist. In meinen Tests hat das UDT sowohl Photoshop als auch InDesign einwandfrei erkannt.

Das UDT-Fenster

In InDesign 2023 können wir noch keine echten Plugins (mit einem eigenen Bedienfeld) erstellen. Deswegen ist für uns nur der Button Debug Script relevant. Klicke den Button Debug Script und wähle dann das Skript helloWord.idjs aus dem letzten Beitrag oder ein eigenes UXP-Script.

Wähle dann den Button Debug.

Nun startet der eigentliche Debugger in einem neuen Fenster. Die Ansicht ist dem ein oder anderen vielleicht schon aus der Web-Entwicklung als Chrome Developer Tools bekannt. Für uns ist aber erst einmal nur der Tab Sources relevant. Der Debugger hat das von uns gewählte Skript geladen, aber noch nicht ausgeführt.

Das ausgewählte Skript wird automatisch mit einer asynchronen Funktion umschlossen. Dadurch steht die erste Zeile des Skripts etwas unübersichtlich nach dem Funktionsaufruf, hat aber noch die gleiche Zeilennummer.

(async function (exports, require, module, __filename, __dirname) { 
//...
});

Das bedeutet hier zunächst einmal nur, dass InDesign auch während der Debug Session reagiert. Die alten ExtendScript-Skripte waren immer synchron, d.h. während eines Skriptlaufs konnte InDesign nicht angesprochen werden.

Klicke jetzt im rechten Bereich auf den Pfeil Button (oder die Taste F8), um den Debugger zu starten.

Da wir aber keine Breakpoint gesetzt haben und das Skript keinen Fehler enthält, läuft der Code einfach durch und in InDesign sollte das Dokument mit dem Textrahmen erstellt worden sein. Das Developer-Tools-Fenster wird automatisch geschlossen. Das Gleiche passiert sogar, wenn ein Fehler im Skript enthalten ist. Deswegen empfehle ich dringend, die Default-Einstellungen zu verändern:

Nur mit dieser Einstellung wird ein möglicher Fehler angezeigt und die Developer Tools bleiben mit der V8 JavavScript Engine von InDesign verbunden. Verändere im Skript helloWord.idjs in Zeile 3 add() zu axdd() und starte eine neue Debug-Session. Nach der Einstellung von Pause on caught exceptions und dem Start des Skripts sollte es dann so aussehen:

Die Funktion axdd() existiert nicht und wirft, wie zu erwarten, eine Exception. Wir können uns nun auf die Fehlersuche begeben. Als Erstes suchen wir im rechten Bereichs des Fensters unter Scope die möglichen Funktionen der Eigenschaft textFrames:

Hier finden wir alle Eigenschaften und Funktionen und auch die korrekte Schreibweise add(). Leider können wir den Code nicht live korrigieren, sondern müssen zurück in Visual Studio Code (oder einen anderen Texteditor) und die Debug-Session neu starten.

Bevor wir das allerdings erledigen, sollten wir in der Console testen, ob der Befehl funktioniert. Dazu empfehle ich, die Console unterhalb des Sources Tabs einzublenden. Klicke auf das Menü ganz rechts oben und wähle Show console drawer. Alternativ könne ihr auch den Tab Console links neben Sources aktivieren.

Danach erscheint unterhalb des Fensters ein Eingabebereich, in dem man den Befehl page.textFrames.add() ausprobieren kann. Es funktioniert:

Wenn man jetzt das Developer-Tools-Fenster schließt, erscheint die Warnmeldung mit der Exception in InDesign als modaler Dialog. Diesen muss man noch einmal extra wegklicken, sehr nervig.

Weitere Tipps für die Developer Tools

Mit dem Step Over Button bzw. F10 kann man Schritt für Schritt durch den Code schreiten.

Die nächste Zeile, die ausgeführt werden wird, ist grün hinterlegt. Im folgenden Beispiel sind Zeile 1 bis 3 bereits ausgeführt:

In diesem Zustand ist das Dev-Tools-Fenster mit der V8 JavavScript Engine von InDesign verbunden. D.h. wir können in der Console den Zustand der Variablen zur Laufzeit auswerten.

Nach dem Eintrag page. erscheint ein Autocompletion-Feld mit den möglichen Eigenschaften des Objekts. Das gefällt mir super und ist eine tolle Verbesserung. Wenn man ein den Befehl mit Return bestätigt, erscheint in der Console das Ergebnis. Hier ein absichtlich eingetragener Fehler und der zweite, korrekte Versuch:

Beim Experimentieren mit der Console ist mir eine ärgerliche Änderung in UXP aufgefallen. UXP erlaubt die Zuweisung von beliebigen Eigenschaften an ein Objekt. Tippfehler können schnell übersehen werden und Code-Teile werden unerwarteterweise nicht ausgeführt! Schau dir das folgende Beispiel mit der fehlerhaften Eigenschaft geometrixBounds an:

Fehlt eigentlich nur noch ein Breakpoint. Das ist auch ganz einfach: Im Bereich Sources setzen wir diesen vor der Ausführung des Skripts neben die Zeilennummer:

Während das Skript beim Breakpoint zum Halten gekommen ist, kann natürlich wieder der Code inspiziert werden.

Fazit

Alles in allem ist der Prozess noch nicht optimal. Bei jedem neuen Testlauf muss das Skript manuell ausgewählt und gestartet werden! Bei einem Fehler muss das Tool zunächst geschlossen werden und das Skript in einem anderen Editor korrigiert werden. Besser wäre es, wenn man das Skript im Dev Tool korrigieren und direkt neu starten könnte. Wie üblich beim Thema UXP: Wir stehen noch am Anfang!