docex_editor
Version:
A powerful, cloud-based document editor for React applications
70 lines (69 loc) • 2.57 kB
JavaScript
import React from "react";
import ReactDOM from "react-dom";
// Internal cache
let bundleCache = null;
export async function createEditor(apiKey) {
if (!bundleCache) {
bundleCache = loadBundle(apiKey);
}
const bundle = await bundleCache;
return bundle.getEditor();
}
export async function createEditorComponent(controller) {
if (!bundleCache) {
throw new Error("Call createEditor first");
}
const bundle = await bundleCache;
return bundle.useEditor(controller);
}
// Internal loader function
async function loadBundle(apiKey) {
// // Set the host's React globally BEFORE loading the bundle
window.__HOST_REACT__ = React;
window.__HOST_REACT_DOM__ = ReactDOM;
// Also set as global React/ReactDOM for external imports
window.React = React;
window.ReactDOM = ReactDOM;
// Create import map to resolve bare specifiers
// Generate dynamic exports for all React properties
const reactExports = Object.keys(React)
.map((key) => `export const ${key} = React.${key};`)
.join(" ");
const reactDOMExports = Object.keys(ReactDOM)
.map((key) => `export const ${key} = ReactDOM.${key};`)
.join(" ");
const importMap = {
imports: {
react: `data:text/javascript,const React = window.React; export default React; ${reactExports}`,
"react-dom": `data:text/javascript,const ReactDOM = window.ReactDOM; export default ReactDOM; ${reactDOMExports}`,
},
};
// Add import map to document if not already present
if (!document.querySelector('script[type="importmap"]')) {
const script = document.createElement("script");
script.type = "importmap";
script.textContent = JSON.stringify(importMap);
document.head.appendChild(script);
}
// Load CSS
await loadCSS(`https://cdn-gateway-worker.iftach.workers.dev/editor/docexEditorV1.css?api_key=${apiKey}`);
// Load JS bundle
const bundle = await import(
/* webpackIgnore: true */
`https://cdn-gateway-worker.iftach.workers.dev/editor/docexEditorV1.esm.js?api_key=${apiKey}`);
return bundle;
}
async function loadCSS(href) {
return new Promise((resolve) => {
if (document.querySelector(`TenDocWidgetCSS`)) {
resolve();
return;
}
const link = document.createElement("link");
link.id = `TenDocWidgetCSS`;
link.rel = "stylesheet";
link.href = href;
link.onload = () => resolve();
document.head.appendChild(link);
});
}