Skip to content

Commit 5484148

Browse files
committed
Add documentation on plugin load/execute lifecycle and edit operations.
Expand "Accessing APIs" doc to list at a high level the different categories of APIs (XD, UXP, etc.)
1 parent bde34d0 commit 5484148

File tree

5 files changed

+91
-23
lines changed

5 files changed

+91
-23
lines changed

SUMMARY.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
* [Sync and async](./reference/javascript/sync-async.md)
1616
* [API environment](./reference/javascript/environment.md)
1717
* [XD concepts](./reference/core/index.md)
18+
* [Plugin lifecycle](./reference/core/lifecycle.md)
1819
* [The scenegraph](./reference/core/scenegraph.md)
19-
* [The edit context](./reference/core/edit-context.md)
20-
* [Coordinate spaces & units](./reference/core/coordinate-spaces-and-units.md)
20+
* [Edit Context rules](./reference/core/edit-context.md)
2121
* [Properties with object values](./reference/core/properties-with-object-values.md)
22+
* [Coordinate spaces & units](./reference/core/coordinate-spaces-and-units.md)
2223
* [Automatic cleanups](./reference/core/automatic-cleanups.md)
23-
* [APIs](./reference/core/apis.md)
24+
* [Accessing APIs](./reference/core/apis.md)
2425
* [Development best practices](./devbestpractices/index.md)
2526
* [1.0 Performance](./devbestpractices/1-performance.md)
2627
* [2.0 Scenegraph](./devbestpractices/2-scenegraph.md)

reference/core/apis.md

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,49 @@
11
# Available APIs
22

3-
Adobe XD provides several APIs to you, via the `require` method. You can also import your own modules and files using `require`.
3+
Adobe XD provides several categories of APIs:
44

5-
## Principal API modules
5+
* **[APIs for interacting with XD itself](#xd-specific-apis)**, especially its document model, the **scenegraph**
6+
7+
* The **UXP runtime**, which provides all the capabilities that aren't XD-specific:
8+
* A [_browser-like_ HTML and CSS engine](../uxp/ui-index.md) which drives actual XD _native UI components_ -- it is **not** a complete browser engine, but lets you build your UI using familiar web APIs and frameworks.
9+
* [Network APIs](../uxp/network-index.md) similar to the web standard XHR, `fetch`, and WebSocket found in browsers.
10+
* The [`storage` API](../uxp/storage-index.md), offering sandboxed filesystem access.
11+
12+
* The usual **[core JavaScript language APIs](../javascript/javascript-support.md)** you see in all JS runtimes, such as `setTimeout()` and `Date`.
13+
14+
* A simple **[module-loader `require()` API](../javascript/javascript-support.md#can-i-use-require)**
15+
16+
Read below for **how to access** XD and UXP APIs...
17+
18+
19+
## XD-specific APIs
20+
21+
Most XD APIs are accessed by loading a module via `require()`, but some are passed directly to your plugin's handler functions.
622

723
* [selection](../selection.md) - Indicates the selected nodes and related context
824
* This object is passed as an argument to your command handler function (see above)
925
* [scenegraph](../scenegraph.md) - APIs available on document nodes
10-
* Normally you can use these APIs by simply accessing the arguments passed to your command's handler function
26+
* Typically you use scenegraph objects by simply accessing the arguments passed to your command's handler function
1127
(`selection` and `documentRoot`).
1228
* To create _new_ nodes in the document, load this module explicitly to access the constructor functions:
1329
```js
1430
let Rectangle = require("scenegraph").Rectangle;
1531
let node = new Rectangle();
1632
```
1733
* [commands](../commands.md) - Invoke commands to change the document structure and perform other complex operations.
18-
* Load this module explicitly: `let commands = require("commands");`
34+
* `let commands = require("commands");`
1935
* [interactions](../interactions.md) - Data model for interactive prototyping features (also accessible from scenegraph nodes).
20-
* Load this module explicitly: `let interactions = require("interactions");`
21-
* [storage](../uxp/storage-index.md) - Read and write files on disk
22-
* Load this module explicitly: `const fs = require("uxp").storage.localFileSystem;`
23-
* [Network](../uxp/network-index.md) - Use browser-style `XMLHttpRequest`, `fetch()`, and `WebSocket` APIs to access the network.
24-
* These APIs are in the global namespace, so you can use them without any `require()` statements
36+
* `let interactions = require("interactions");`
2537
* [application](../application.md) - Version and locale information, and APIs for exporting content.
26-
* Load this module explicitly: `let application = require("application");`
38+
* `let application = require("application");`
2739
* [clipboard](../clipboard.md) - Copy text to the clipboard.
28-
* Load this module explicitly: `let clipboard = require("clipboard");`
40+
* `let clipboard = require("clipboard");`
41+
42+
43+
## UXP
44+
45+
* HTML DOM APIs -- access just as in a browser, via the global `document`. Each plugin in XD gets its own `document` tree.
2946

30-
## Helper classes
47+
* Network APIs -- access just as in a browser, via the global classes `XMLHttpRequest` and `WebSocket`, and the global function `fetch()`
3148

32-
* [SceneNodeList](../SceneNodeList.md) - This is the type of the `children` property on scenenodes
49+
* Storage APIs -- access via `const fs = require("uxp").storage.localFileSystem;`

reference/core/index.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# XD concepts
22

3-
Since your plugin code will run within XD, it's important to understand some concepts that are specific to the application.
3+
These important concepts are specific to plugins for XD:
44

5+
- [Plugin lifecycle](./lifecycle.md)
56
- [Scenegraph](./scenegraph.md)
6-
- [Edit context rules](./edit-context.md)
7-
- [Coordinate spaces & units](./coordinate-spaces-and-units.md)
7+
- [Edit Context rules](./edit-context.md)
88
- [Properties with object values](./properties-with-object-values.md)
9+
- [Coordinate spaces & units](./coordinate-spaces-and-units.md)
910
- [Automatic cleanups](./automatic-cleanups.md)
10-
- [APIs](./apis.md)
11+
- [Accessing APIs](./apis.md)

reference/core/lifecycle.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Plugin lifecycle
2+
3+
Here's an overview of how plugins are loaded, when plugin code runs, and how plugin "edit operations" work.
4+
5+
6+
## Plugin loading
7+
8+
Each XD document window loads a separate copy of your plugin's JavaScript code with a separate UXP UI `document` global (as if they were, say, separate browser windows). It's not yet possible for the JavaScript in one window to communicate with other windows, short of using a web server or other external channel.
9+
10+
Each plugin is loaded into an isolated context with its own set of global variables. Different plugins cannot share objects or functions with each other.
11+
12+
Your plugin's code remains resident until the document is closed (or until a developer runs the Reload Plugins command). This means you can store temporary "session" state in global or module-level variables.
13+
14+
15+
## When plugins run
16+
17+
Several different situations can cause code in your plugin to get executed:
18+
19+
* **Initialization** -- When loading, any "top-level" code in each module (JS file) is executed immediately. You can't edit the document or show UI at this point. Only perform tasks that are absolutely necessary for basic loading and initialization -- defer as much as possible until later, when the user invokes your plugin for the first time.
20+
21+
* **Command handlers** -- Each time one of your plugin's menu commands is invoked, XD calls your [_command handler function_ for the relevant `commandId`](../structure/handlers.md). Your command handler can edit the document or open a dialog box; if you return a Promise, these privileges extend until the Promise completes. See ["Edit operations"](#edit-operations) for details.
22+
23+
* **DOM events** -- Handlers you've attached to dialog box UI are triggered whenever the event occurs (while the dialog box is open). Since dialogs are typically open only during an [edit operation](#edit-operations), this event handler code can edit the document too.
24+
25+
* **Network API handlers and timers** -- Other events can happen at any time, such as a network call finishing or a `setTimeout()` firing.
26+
* If you've engineered an async edit operation's Promise to wait for these events before resolving, then these handlers can also edit the document.
27+
* You can also run network requests and timers entirely in the background, outside of any edit operation, though this is discouraged. Plugin code running in the background can make XD slow. And although you'll have read-only access to the scenegraph, this is unsafe since your background code may run _in the middle of_ some other asynchronous edit operation (whether from a built-in XD command, another plugin, etc.) -- so your code might see an incorect intermediate state of the document.
28+
29+
30+
## Edit operations
31+
32+
An edit operation is the window of time in which your plugin is making a batch of related changes to the document. One edit operation equals one Undo step.
33+
34+
Your plugin can modify multiple properties on multiple scenegraph nodes during an edit operation, and they are all automatically batched together.
35+
36+
#### Edit operation duration
37+
* An edit operation begins when your plugin's [command handler](../structure/handlers.md) is called.
38+
* If the command handler returns synchronously, the edit operation is done as soon as it returns.
39+
* If the command handler returns a Promise, the edit operation continues asynchronously until the Promise completes. _The user can't do anything else in XD_ until the operation completes, so normally a Promise is only returned if the plugin has a dialog box open that the user is interacting with or that is showing a progress indicator.
40+
41+
If the command handler throws an exception, or its Promise is rejected, the entire edit batch is atomically rolled back automatically by XD.
42+
43+
#### Modal/exclusive UI
44+
While an edit operation is in progress, XD prevents any edits from other plugins or other features. The user can't interact with any XD UI other than dialogs shown by your plugin.
45+
46+
Even if your plugin doesn't have a dialog box open during an async edit operation, the XD UI still remains frozen. If an edit operation continues for over 1 second without any UI being shown, XD shows a "Plugin is working" message which allows users to forcibly abort the edit operation. For this reason, during long-running async steps like network requests it's best to display your own nicer progress UI (users can always still cancel this too, by pressing Escape at any time).
47+
48+
#### UI updates
49+
Just as in a web browser, XD won't update the UI in the middle of your plugin code's _synchronous_ execution. As soon as there's an async gap in execution, any changes you've made to dialog box DOM or to the document scenegraph will be reflected in XD's UI.
50+
51+
For example, if your plugin makes some partial edits to the scenegraph, then waits on a network request, then uses the results to make more edits -- although the entire operation is atomic with respect to Undo, the user will see the partial edits displayed onscreen for a brief moment while your plugin code is idle waiting for the async network request to complete.

reference/javascript/javascript-support.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,4 @@ const someLib = require("somelib"); // no package.json lookup
5151

5252
## Can I use npm packages or Node.js APIs?
5353

54-
You may be able to use some npm packages without modification, but chances are good that you’ll need to use webpack or rollup in order to generate a bundle.
55-
56-
Node.js APIs themselves are not supported.
54+
XD's plugin sandbox does not include most Node.js APIs, such as unrestricted filesystem access or the ability to spawn external processes. Npm packages that only depend on the core JavaScript language APIs can work in XD, but because XD's `require()` differs (see above), you will likely have to use webpack or rollup in order to generate a single-file bundle first.

0 commit comments

Comments
 (0)