Communication APIs
The communication APIs allow you to communicate between the document model sandbox (referred to as simply "document sandbox" throughout the rest of this guide), and the iframe where your add-on is running specifically, via the add-on SDK methods available for the document sandbox.
Overview
The document sandbox and iframe runtime are two different runtime execution environments which are present on different threads in the browser. The communication APIs are based on the Comlink library and provide a mechanism to allow the JavaScript code executing in each to interact. Developers can call the apis exposed in one environment (ie: document sandbox) from another environment (ie: iframe where their add-on is running) bidirectionally.
Accessing the APIs
A default exported module from addOnSandboxSdk
is provided to enable the communication between the iframe and the document sandbox via its' instance.runtime
object. You can simply import the module into your script file code for use, and create a reference to the runtime
object. For instance:
Copied to your clipboardimport addOnSandboxSdk from "add-on-sdk-document-sandbox"; // a default importconst { runtime } = addOnSandboxSdk.instance; // runtime object provides direct access to the communication APIs
Examples
The runtime
object can then be used to access the communication methods which allow you to communicate between the two execution environments: exposeApi()
and apiProxy()
. The examples below show the methods in use from both the index.html
where the iframe is running with your add-on code, and the document sandbox environment running the contents of code.js
.
Expose APIs from the script
This example shows how to expose APIs from the document sandbox SDK (via code.js
) for use by the UI (via index.html
).
code.js
Copied to your clipboardimport addOnSandboxSdk from "add-on-sdk-document-sandbox";const { runtime } = addOnSandboxSdk.instance;const sandboxApi = {performWorkOnDocument: function (data, someFlag) {// call the Document APIs},getDataFromDocument: function () {// get some data from document},};// expose these apis to be directly consumed in the UI (ie: index.html file).runtime.exposeApi(sandboxApi);
index.html
Copied to your clipboardimport addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";addOnUISdk.ready.then(async () => {const { runtime } = addOnUISdk.instance;// Wait for the promise to resolve to get a proxy to call APIs defined in the document sandboxconst sandboxProxy = await runtime.apiProxy("documentSandbox");await sandboxProxy.performWorkOnDocument({pageNumber: 1,op: "change_background_color",data: {toColor: "blue",},},true);console.log(await sandboxProxy.getDataFromDocument());});
Expose APIs from the UI
This example shows how to expose APIs from the UI (via index.html
) for use in the document sandbox (via code.js
).
index.html
Copied to your clipboardaddOnUISdk.ready.then(async () => {console.log("addOnUISdk is ready for use.");const { runtime } = addOnUISdk.instance;const uiApi = {performWorkOnUI: function (data, someFlag) {// Do some ui operation},getDataFromUI: async function() {return new Promise(resolve => {// Example of returning a user choice from hypothetical UIresolve("button_color_blue");});}};// Expose the UI Apis to be used in the script code (ie: code.js)runtime.exposeApi(uiApi);});
code.js
Copied to your clipboardimport addOnSandboxSdk from "add-on-sdk-document-sandbox"; // default importconst { runtime } = addOnSandboxSdk.instance;async function callUIApis() {// Get a proxy to the APIs defined in the UIconst uiApis = await runtime.apiProxy("panel");await uiApis.performWorkOnUI({buttonTextFont: 20,buttonColor: "Green"},true);const result = await uiApis.getDataFromUI();console.log("Data from UI: " + result);}
DEBUGGING: Since the script code runs in a separate context from your add-on UI, the only support for debugging is via the console.*
methods.
Data Types
Data type validation is performed for both the arguments and the return types that are exchanged across the document sandbox runtimes (aka: communication API layer). A whitelist of supported data types is maintained and detailed below. All other data types will be rejected.
Supported data types
Type | Examples |
Primitive types: |
|
Simple plain objects | { data: "world" }, { value : true } |
Arrays of primitive and plain objects | [1,2],["hello", true, { data: null }] |
ArrayBuffer | new ArrayBuffer(1024) |
Blob | new Blob() |
Error | new Error() |
Some data types are not supported and may result unintended behavior. To avoid this, the type of argument/return type in the communication layer is checked and an error is thrown if not supported.
Unsupported data types
Type | Examples |
Map | new Map() |
Set | new Set() |
DataView() | new DataView(new ArrayBuffer(8)) |
Boolean | new Boolean() |
String | new String(“hello”) |
RegExp | new RegExp("pattern") |
Symbol | Symbol('symbol') |
Date | new Date() |
UserDefinedClass | new UserDefinedClass() |
Function | () => {} |
Circular objects | const obj = {} obj.key = obj; |