Editor embedding
Methods
The five methods save, close, destroy, setReadOnly, getInfo: return values, timeouts and examples.
The object returned by new O3O.Editor(...) has five methods.
| Method | Returns | Behaviour |
|---|---|---|
save() | Promise<{saved, version}> | Requests an immediate save. saved: false when there is nothing to save or in view. After 30 seconds: rejects with save_timeout. |
close() | Promise<void> | Saves pending changes (waits up to 10 seconds), then destroy(), then fires onClose. |
destroy() | void | Removes the iframe and banner, detaches listeners, tells the gate to close the session. Does NOT save. Safe to call repeatedly. |
setReadOnly(readOnly) | Promise<{mode}> | Switches between view and edit: saves pending changes, switches mode on the gate, then RELOADS the frame. |
getInfo() | object | Synchronous, no network call. |
save()#
Sends a save command to the editor frame without ending the editing session and without saving an unchanged document. The promise resolves when the gate has a new version.
document.getElementById("btn-save").onclick = async () => {
try {
const r = await editor.save(); // { saved: boolean, version }
alert(r.saved ? "Saved version " + r.version : "Nothing new to save");
} catch (err) {
console.error(err); // e.g. more than 30 seconds: save_timeout
}
};close()#
document.getElementById("btn-close").onclick = async () => {
await editor.close(); // saves pending changes (waits up to 10 seconds), removes the iframe, then fires onClose
};destroy()#
Calls DELETE /o3o/embed/session/{id} with keepalive, so it is safe even while the page unloads. The session is marked closed, but the editor server's final save is still accepted by the gate.
// Single-page app: tear the editor down when leaving the view. It does NOT save.
router.beforeEach(() => {
editor.destroy(); // safe to call more than once
});setReadOnly(readOnly)#
Switching to edit applies the connection cap exactly like session creation: if the cap is reached, the session stays in view, the promise returns {mode: "view"} and onLimitReached fires.
document.getElementById("toggle").onchange = async (ev) => {
const { mode } = await editor.setReadOnly(!ev.target.checked); // saves pending changes, then reloads the frame
if (ev.target.checked && mode === "view") {
ev.target.checked = false; // cap reached: still read-only, onLimitReached has fired
}
};getInfo()#
getInfo() fields
sessionIdstring | nullrequirednulluntil the session is created.keystringrequireddocument.keydocIdstringrequiredInternal document iddoc_….mode"edit" | "view"requiredActual mode.requestedMode"edit" | "view"requiredMode the page asked for.limitedbooleanrequiredtrueif downgraded to read-only by the cap.loadedbooleanrequiredThe document is visible.modifiedbooleanrequiredUnsaved changes exist.versionintegerrequiredLatest known version.editorOriginstringrequiredOrigin of the O3O server, derived from thesrcofapi.js.
const info = editor.getInfo();
console.log(info);
// {
// sessionId: "ses_5b1d0c2a9f3e4d6a8b7c0d1e", key: "contract-42-v7", docId: "doc_9835f61009fc659dfedab8696f2d2665",
// mode: "edit", requestedMode: "edit", limited: false, loaded: true, modified: false, version: 3,
// editorOrigin: "http://localhost:8080"
// }
console.log(O3O.version); // api.js versionPage exercising all five methods#
<!doctype html>
<meta charset="utf-8">
<p>
<button id="btn-save">save()</button>
<label><input type="checkbox" id="toggle" checked> editable</label>
<button id="btn-info">getInfo()</button>
<button id="btn-close">close()</button>
<button id="btn-destroy">destroy()</button>
</p>
<div id="o3o-editor" style="height: 80vh"></div>
<script src="http://localhost:8080/o3o/api.js"></script>
<script>
const editor = new O3O.Editor("o3o-editor", {
document: { url: "http://localhost:8080/o3o/demo/sample.docx", title: "sample.docx", fileType: "docx", key: "methods-demo-1" },
editor: { mode: "edit", lang: "en-US", user: { id: "dev-1", name: "Dev" } },
events: { onClose: () => console.log("onClose"), onError: (e) => console.error(e.code, e.message) }
});
document.getElementById("btn-save").onclick = async () => console.log(await editor.save());
document.getElementById("toggle").onchange = async (ev) => console.log(await editor.setReadOnly(!ev.target.checked));
document.getElementById("btn-info").onclick = () => console.log(editor.getInfo());
document.getElementById("btn-close").onclick = () => editor.close();
document.getElementById("btn-destroy").onclick = () => editor.destroy();
</script>