Element is the unified data structure for “all visible elements” in NOTE/DOC: strokes, titles, links, TextBox elements, geometries, five-star elements, pictures, etc. are all represented as Element, and distinguished by type.
- Element types and fields:
Element - Type constants:
ElementType
- Get page elements:
PluginFileAPI.getElements - Create a new element object:
PluginCommAPI.createElement - Insert element:
PluginFileAPI.insertElements - Modify element:
PluginFileAPI.modifyElements - Replace all elements on a page:
PluginFileAPI.replaceElements
Key Concepts
1) Why call createElement first?
Some fields inElement can be very large (e.g., stroke sample points, pressure points, angle points, contour points). To avoid JS-side memory issues, the SDK uses an “accessor” design:
- On the RN side you receive an
ElementDataAccessor(a reference/handle) - Raw point data caching and read/write happen on the native side
PluginCommAPI.createElement(...) first so the native side can create and initialize the required caches and accessor references, and then fill in the content you want to write on the JS side.
2) Conventions: page and layer
page: documentation uses zero-based page numbers (aligned with UI page numbering).layer: in notes, common layers are0..3. Links/titles must be on the main layer (layer=0), otherwise validation fails. Document files only have a single layer: the main layer.
3) Document limitations
Document files do not allow inserting TextBox elements / titles / links. Forcing insertion will be rejected by validation.4) Element Caching and Release
Some fields inElement (stroke sample points, pressure points, angle points, contour points, etc.) can hold a large amount of data. Transferring all of it to the RN side at once not only creates memory pressure, but transfer/conversion time also grows noticeably as the data size grows. Because of this, the native side caches each Element by uuid, and the RN side only holds a reference (uuid + accessors), fetching data on demand.
Around this cache there is a full create → read → write → release flow:
A few things worth noting:
- Write APIs depend on the cache still existing:
insertElements/modifyElements/replaceElements/recognizeElements/convertElement2Sticker/modifyPageElements/insertPageElements/batchUpdatePageElementsall require that the passed-in element’suuidis currently present in the native cache. This is a different check from “the element already exists on the page” (for example,modifyElementsrequires the target to already exist on that page) — auuidthat can’t be found in the cache is skipped at an earlier stage, before the “does it already exist on the page” check even happens. - The cache is not guaranteed to live forever:
clearElementCache()only runs when a plugin calls it; the SDK never triggers it automatically on the plugin’s behalf. Conversely, the host environment may also automatically reclaim part or all of the cache under memory pressure, so you shouldn’t assume auuidstays valid indefinitely — release elements as soon as you’re done with them. - This is a different, coarser-grained cache than
ElementDataAccessor: large point fields such asangles/contoursSrcadd another on-demand paging accessor layer on top of the cachedElement. The accessor itself also keeps a smaller cache on the RN side — read methods such asget/getRangecache the values they fetch, while write methods such asadd/set/setRangeautomatically clear that cache on success;preload/isCached/getCacheStats/clearCacheare also available for manual warm-up, inspection, and clearing. Releasing the wholeElementalso clears its accessor caches. SeeElementDataAccessorfor details.
Get Page Elements
When you need to read all elements on a page (for display, filtering, editing, copying, etc.), usegetElements:
Create a New Element
To create a new element that will be inserted into a page, usecreateElement(type):
The
Element returned by createElement includes uuid, and fills required ElementDataAccessor fields based on the element type (e.g., angles/contoursSrc, and stroke.* for stroke elements).Insert Elements into a Page
After preparing the element array to insert (usually fromcreateElement or copied from existing elements), use insertElements to insert into a target page:
Modify Existing Elements
The key constraint is: you can only modify elements that already exist on the page. The SDK checks existence using identifiers (e.g.,numInPage). Non-existent elements will not be modified successfully.
The safest workflow:
- Call
getElementsto fetch the original element list - Find the target element (e.g., by
numInPageoruuid) - Modify fields and pass that element (or a set of elements) to
modifyElements
Replace All Elements on a Page
UsereplaceElements when you want to “clear all existing elements and replace the page with a new set”. Common scenarios: full-page re-layout, batch import, or writing edited results in one shot.