├── LICENSE
├── README.md
├── what_does_not_work.md
└── what_is_new.md
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Roland Dreger
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # InDesign UXP Scripting
2 | Collected resources, articles and tutorials around UXP Scripting in Adobe InDesign. Hints on further sources and corrections are very welcome!
3 |
4 | ## Adobe
5 | ### Reference
6 | - [UXP for Adobe InDesign](https://developer.adobe.com/indesign/uxp)
7 | - [JavaScript Reference](https://developer.adobe.com/indesign/uxp/uxp/reference-js/)
8 | ### Spectrum
9 | - [Reference](https://developer.adobe.com/indesign/uxp/uxp/reference-spectrum/)
10 | - [Web Components](https://opensource.adobe.com/spectrum-web-components/)
11 | - [Web Components (Storybook)](https://opensource.adobe.com/spectrum-web-components/storybook/)
12 | - [Design System](https://spectrum.adobe.com/)
13 | - [Color palette](https://spectrum.adobe.com/page/color-palette/)
14 | - [UI Icons](https://spectrum.adobe.com/page/icons/)
15 | - [Web Componentes icons-ui](https://opensource.adobe.com/spectrum-web-components/components/icons-ui/)
16 | - [Web Componentes icons-workflow](https://opensource.adobe.com/spectrum-web-components/components/icons-workflow/)
17 | - [Spectrum Web Components Discussions](https://github.com/adobe/spectrum-web-components/discussions)
18 | - [Spectrum Web Components Issues](https://github.com/adobe/spectrum-web-components/issues)
19 |
20 |
21 | # Articles
22 | - [InDesign v. 18 Ships with Scripting Powered by UXP](https://blog.developer.adobe.com/indesign-v-18-ships-with-scripting-powered-by-uxp-53e5dc008f17)
23 | - [Migrating existing JavaScript(ExtendScript) to UXP Script](https://developer.adobe.com/indesign/uxp/guides/migrating-to-UXPScript/)
24 | - [Was bringt InDesigns neue UXP Scripting API?](https://xporc.net/2022/12/02/was-bringt-indesigns-neue-uxp-scripting-api/)
25 | - [Getting Started with IDJS (InDesign UXP Scripting Format)](https://indiscripts.com/post/2023/01/getting-started-with-idjs-indesign-uxp-scripting-format)
26 | - [Plans for UXP in 2023](https://blog.developer.adobe.com/plans-for-uxp-in-2023-d06091944308) New features planned for UXP v7.0 and beyond
27 | - [Everything That Went into Creating the First-Ever UXP-Based Plugin for Adobe InDesign](https://blog.developer.adobe.com/what-went-into-creating-the-first-ever-uxp-based-plugin-for-adobe-indesign-78bc701c5cbd)
28 |
29 |
30 | # Videos
31 | - [Adobe UXP: Things you need to know! #Special The UXP Landscape Guide](
32 | https://www.youtube.com/watch?v=PjqhwGGTCjE)
33 |
34 |
35 | # Tutorials
36 | ## indesignblog.com (Gregor Fellenz)
37 | - [Quickstart UXP Scripting](https://www.indesignblog.com/2022/11/quickstart-uxp-scripting/)
38 | - [Das UXP Developer Tool](https://www.indesignblog.com/2023/01/das-uxp-developer-tool/)
39 |
40 |
41 | # Samples
42 | - [InDesign](https://github.com/AdobeDocs/uxp-indesign/tree/main/src/pages/reference/uxp-scripting-samples) (Adobe)
43 | - [Photoshop](https://github.com/AdobeDocs/uxp-photoshop-plugin-samples) (Adobe)
44 | - [InDesign](https://github.com/RolandDreger/indesign-uxp-script-snippets)
45 |
46 |
47 | # Community
48 | - [Adobe Support Community](https://community.adobe.com/t5/indesign/ct-p/ct-indesign?page=1&sort=latest_replies&lang=all&tabid=all&topics=label-uxpscripting)
49 | - [Creative Cloud Developer Forum](https://forums.creativeclouddeveloper.com/)
--------------------------------------------------------------------------------
/what_does_not_work.md:
--------------------------------------------------------------------------------
1 | # What does *not* work?
2 | A incomplete list of what is not possible with UXP Scripting (at the moment).
3 | ## HTML
4 | - Element attribute `draggable="true"`
5 | - Element attribute `contenteditable="true"`
6 | - [Unsupported Elements](https://developer.adobe.com/indesign/uxp/uxp/reference-html/General/Unsupported%20Elements/)
7 | - [Unsupported Attributes](https://developer.adobe.com/indesign/uxp/uxp/reference-html/General/Unsupported%20Attributes/)
8 |
9 | ## CSS
10 | - `display: grid`
11 | - `gap` property for Flexbox
12 | - `float`
13 | - `aspect-ratio`
14 | - Animations do not seem to work!? (transition, @keyframes)
15 | - ...
16 |
17 | ## JavaScript
18 |
19 | - Assign a value to custom property: `Element.style.setProperty('--custom-property', 'value')`
20 | - `new DOMParser()` nope ... *DOMParser is not defined*
21 | - XPath `document.evaluate(...)` *document.evaluate is not a function* and *XPathResult is not defined*
22 | - `new TextDecoder('utf-8')` *TextDecoder is not defined*
23 | - Up to v18.4: Property `properties` does not work anymore, e.g. `app.activeDocument.properties.fullName` // undefined
24 | Onwards v18.5: Since the current version it seems to work (almost) like before. Is everything okay now? That has to be shown by further tests. One of the changes: `Document.fullName` now returns a Promise: `app.activeDocument.properties.fullName` // Promise
25 | - Global function `structuredClone()` *structuredClone is not defined*
26 | - Global function `window.matchMedia()` to evaluate the result of a media query. *matchMedia is not defined*
27 | For theme changes we can use:
28 | ```
29 | document.theme.onUpdated.addListener((theme) => {
30 | console.log(theme);
31 | });
32 | ```
33 | - “new AbortController()” works. But in event listeners, “controller.abort()” with the signal has no effect.
34 | - resolve() *resolve is not defined*, e.g. `resolve("/document[0]")` does not work
35 | - ...
36 |
37 | ### Localization
38 | - `navigator.language` is undefined (-> require("uxp").host.locale works)
39 | - `(new Intl.NumberFormat()).resolvedOptions().locale` *"en-US"* (for German UI)
40 |
--------------------------------------------------------------------------------
/what_is_new.md:
--------------------------------------------------------------------------------
1 | # What's new in ...
2 |
3 | ## UXP
4 |
5 | ### JavaScript Version | Engine
6 |
7 |
8 |
9 |
10 | JSX |
11 | UXP |
12 |
13 |
14 |
15 | ECMAScript 3
16 | |
17 |
18 | ECMAScript 6 | V8
19 | |
20 |
21 |
22 |
23 |
24 | ### Variables
25 |
26 |
27 |
28 |
29 | JSX |
30 | UXP |
31 |
32 |
33 |
34 | var, const
35 | |
36 |
37 | var, let, const
38 | |
39 |
40 |
41 |
42 |
43 | ### InDesign Collection
44 |
45 | Collection objects returned by InDesign no longer support the subscript operator [] to access an element with a specific index. In UXP you have to use item() instead.
46 |
47 |
48 |
49 |
50 | JSX |
51 | UXP |
52 |
53 |
54 |
55 |
56 | ```javascript
57 | Story.paragraphs[0]
58 | ```
59 |
60 | |
61 |
62 |
63 | ```javascript
64 | Story.paragraphs.item(0)
65 | ```
66 |
67 | |
68 |
69 |
70 |
71 |
72 | ### InDesign DOM Object Constructor Name
73 |
74 |
75 |
76 |
77 | JSX |
78 | UXP |
79 |
80 |
81 |
82 |
83 | ```javascript
84 | app.activeDocument.constructor.name // Document
85 | ```
86 |
87 | |
88 |
89 |
90 | ```javascript
91 | app.activeDocument.constructorName // "Document" Prior to InDesign 18.4
92 |
93 | const app = require("indesign").app; // Onwards InDesign 18.4
94 | app.activeDocument.constructor.name // "Document"
95 | app.activeDocument.constructorName // "Document"
96 | ```
97 |
98 | |
99 |
100 |
101 |
102 |
103 | ### InDesign DOM Object Comparison Operator
104 |
105 |
106 |
107 |
108 | JSX |
109 | UXP |
110 |
111 |
112 |
113 |
114 | ```javascript
115 | app.activeDocument === app.documents[0] // true
116 | ```
117 |
118 | |
119 |
120 |
121 | ```javascript
122 | const app = require("indesign").app; // Onwards InDesign 18.4
123 | app.activeDocument.equals(app.documents.item(0)); // true
124 | ```
125 |
126 | |
127 |
128 |
129 |
130 |
131 | ### InDesign DOM Object instanceof
132 |
133 | The instanceof keyword isn't supported for InDesign DOM objects.
134 |
135 |
136 |
137 |
138 | JSX |
139 | UXP |
140 |
141 |
142 |
143 |
144 | ```javascript
145 | app.activeDocument instanceof Document // true
146 | ```
147 |
148 | |
149 |
150 |
151 | ```javascript
152 | // Instead, we have to use the Constructor Name property.
153 | ```
154 |
155 | |
156 |
157 |
158 |
159 |
160 | ### Global object `document`
161 |
162 | The global object `document` (which stood for an InDesign document) is unsupported in UXP.
163 |
164 | ### ActiveScript
165 |
166 | Prior to InDesign 18.4: `app.activeScript` returns the path of the current script as a string and a error in UXP Developer Tool (UDT).
167 |
168 | Onwards InDesign 18.4: see below.
169 |
170 |
171 |
172 |
173 | JSX |
174 | UXP |
175 |
176 |
177 |
178 |
179 | ```javascript
180 | app.activeScript // File
181 | ```
182 |
183 | |
184 |
185 |
186 | ```javascript
187 | const app = require("indesign").app; // Onwards InDesign 18.4
188 | const script = await app.activeScript
189 | script.nativePath; // "/"
190 | script.isFolder; // true
191 | script.scriptPath.url.href // "file:///"
192 | ```
193 |
194 | |
195 |
196 |
197 |
198 |
199 | ### Passing Script Arguments
200 |
201 | InDesign 18.4 onward: Arguments/parameters can be passed to UXP scripts. Read more in the recipe [Passing Arguments](https://developer.adobe.com/indesign/uxp/recipes/arguments/)
202 |
203 |
204 |
205 |
206 | JSX |
207 | UXP |
208 |
209 |
210 |
211 |
212 | ```javascript
213 | app.scriptArgs.setValue("argOne", "one);
214 | app.scriptArgs.getValue("argOne"); // "one"
215 | ```
216 |
217 | |
218 |
219 |
220 | ```javascript
221 | const script = require("uxp").script;
222 | script.args.push("one");
223 | script.args.push("two");
224 | script.args // ["one", "two"]
225 | ```
226 |
227 | |
228 |
229 |
230 |
231 |
232 | ### Logging
233 |
234 |
235 |
236 |
237 | JSX |
238 | UXP |
239 |
240 |
241 |
242 |
243 | ```
244 | $.writeln('Your log message.');
245 | ```
246 |
247 | |
248 |
249 |
250 | ```javascript
251 | console.log('Your log message.');
252 | console.warn('Your log message.');
253 | ...
254 | ```
255 |
256 | |
257 |
258 |
259 |
260 |
261 | ### File System
262 |
263 | Standard open file dialog box
264 |
265 |
266 |
267 |
268 | JSX |
269 | UXP |
270 |
271 |
272 |
273 |
274 | ```javascript
275 | var file = File.openDialog("Select file");
276 | ```
277 |
278 | |
279 |
280 |
281 | ```javascript
282 | const ufs = require('uxp').storage.localFileSystem;
283 | const file = await ufs.getFileForOpening();
284 | ```
285 |
286 | |
287 |
288 |
289 |
290 |
291 |
292 |
293 | ## InDesign App Version 18.4.0 / UXP Version 6.5.0
294 |
295 | - InDesign DOM is now available only via module:
296 |
297 | ```
298 | const app = require("indesign").app;
299 | console.log(app.activeDocument.name);
300 | ```
301 |
302 | - Indesign enumerators no longer available globally, e.g.:
303 |
304 | ```
305 | const indesign = require("indesign");
306 | const app = indesign.app;
307 | app.scriptPreferences.userInteractionLevel = indesign.UserInteractionLevels.NEVER_INTERACT;
308 | ```
309 |
310 | `constructor.name` for InDesign DOM objects now works again:
311 |
312 | ```
313 | require("indesign").app;
314 | app.activeDocument.constructor.name // "Document"
315 | ```
316 |
317 | - `doScript` works:
318 |
319 | ```
320 | const indesign = require("indesign");
321 | const app = indesign.app;
322 | app.doScript("console.log(\"Hello UXP world!\")", indesign.ScriptLanguage.UXPSCRIPT);
323 | ```
324 |
325 | - And application [events](https://developer.adobe.com/indesign/uxp/recipes/events/) and [menus](https://developer.adobe.com/indesign/uxp/recipes/menus/) are now available as well.
326 |
327 | - The prototype chain for InDesign DOM objects has changed. So you can no longer check with hasOwnProperty:
328 |
329 | ```
330 | var app = require("indesign").app;
331 | app.hasOwnProperty("activeDocument") // false
332 | Object.hasOwn(app, "activeDocument") // false
333 | ```
334 |
335 | Instead e.g.:
336 | ```
337 | ("activeDocument" in app) // true
338 | ```
339 |
340 | - The plugin folder is no longer available for UXP scripts.
341 |
342 | ```
343 | const uxpStorage = require('uxp').storage;
344 | const localFS = uxpStorage.localFileSystem;
345 | const pluginFolder = await localFS.getPluginFolder(); // InDesign 18.4 onward: Error
346 | ```
347 |
348 | - Arguments/parameters can now be passed to UXP scripts. Read more in the recipe [Passing Arguments](https://developer.adobe.com/indesign/uxp/recipes/arguments/)
349 |
350 | - InDesign now has the functionality to set result of a UXP script.
351 |
352 | ```
353 | script.setResult("Hello World!");
354 | ```
355 |
356 | - The `path` module is provided:
357 |
358 | ```
359 | path.parse("~/Desktop/image.jpg") // {root: "", dir: "~/Desktop", base: "image.jpg", ext: ".jpg", name: "image"}
360 | ```
361 |
362 | - Sectrum Web Components (BETA)
363 |
364 | In addition to the built-in *Spectrum UXP widgets*, *Spectrum Web Components* are now supported. They are currently still in the beta phase.
365 |
366 | **Manifest**
367 |
368 | ```
369 | ...
370 | "featureFlags: {
371 | "enableSWCSupport": true
372 | }
373 | ...
374 |
375 | ```
376 |
377 | **Example: SP-Button**
378 |
379 | 1. Install[^1]
380 | [^1]: Via yarn and npm, not always the same versions of the components are available. I think that since yarn is recommended by Adobe, the components here are more up-to-date.
381 |
382 | **yarn**
383 | ```
384 | yarn add @spectrum-web-components/theme
385 | yarn add @swc-uxp-wrappers/utils
386 | yarn add @swc-uxp-wrappers/button
387 | ```
388 | **npm**
389 | ```
390 | npm install @spectrum-web-components/theme
391 | npm install @swc-uxp-wrappers/utils
392 | npm install @swc-uxp-wrappers/button
393 |
394 | ```
395 |
396 | 2. Import
397 | ```
398 | import "@spectrum-web-components/theme/sp-theme.js";
399 | import "@spectrum-web-components/theme/src/themes.js";
400 | import "@swc-uxp-wrappers/button/sp-button.js";
401 |
402 | ```
403 |
404 | 3. Usage
405 | ```
406 |
407 | Click me
408 |
409 | ```
410 |
--------------------------------------------------------------------------------