Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 62 additions & 6 deletions packages/doenetml-iframe/src/test-main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,72 @@ const STANDALONE_CSS_BLOB_URL = URL.createObjectURL(
new Blob([STANDALONE_CSS], { type: "text/css" }),
);

const SOURCE_STORAGE_KEY = "doenetml-iframe-dev-source";
const SAVE_DEBOUNCE_MS = 500;

const DEFAULT_EDITOR_SOURCE = `<mathInput /><p><mathInput />Use this to test DoenetML<mathInput /></p>
<problem copy="doenet:abcdef" />
<graph />
<graph />
<graph />
<mathInput />`;

let saveTimer: number | null = null;

function getInitialSource(): string {
try {
return (
localStorage.getItem(SOURCE_STORAGE_KEY) ?? DEFAULT_EDITOR_SOURCE
);
} catch {
return DEFAULT_EDITOR_SOURCE;
}
}

// Wired to the editor's immediate (per-keystroke) change callback, so debounce
// the writes: calling localStorage.setItem synchronously on every keystroke can
// noticeably block the UI for larger documents.
let pendingSource: string | null = null;

window.addEventListener("pagehide", () => {
if (pendingSource === null) {
return;
}
if (saveTimer !== null) {
window.clearTimeout(saveTimer);
saveTimer = null;
}
try {
localStorage.setItem(SOURCE_STORAGE_KEY, pendingSource);
} catch {
// Ignore localStorage failures in constrained environments.
}
pendingSource = null;
});

function saveSource(source: string) {
pendingSource = source;
if (saveTimer !== null) {
window.clearTimeout(saveTimer);
}
saveTimer = window.setTimeout(() => {
saveTimer = null;
try {
localStorage.setItem(SOURCE_STORAGE_KEY, source);
} catch {
// Ignore localStorage failures in constrained environments.
}
pendingSource = null;
}, SAVE_DEBOUNCE_MS);
}

const root = ReactDOM.createRoot(document.getElementById("root")!);
root.render(<App />);

function App() {
const DOENET_LEGACY_VERSION = "0.6.5";
const editorRef = useRef<DoenetEditorHandle>(null);
const [initialEditorSource] = React.useState(getInitialSource);

return (
<React.Fragment>
Expand Down Expand Up @@ -95,18 +155,14 @@ function App() {
</div>
<DoenetEditor
ref={editorRef}
doenetML={`<mathInput /><p><mathInput />Use this to test DoenetML<mathInput /></p>
<problem copy="doenet:abcdef" />
<graph />
<graph />
<graph />
<mathInput />`}
doenetML={initialEditorSource}
standaloneUrl={STANDALONE_BLOB_URL}
cssUrl={STANDALONE_CSS_BLOB_URL}
activityId={"a"}
showDiagnostics={true}
showResponses={false}
fetchExternalDoenetML={fetchExternalDoenetML}
immediateDoenetmlChangeCallback={saveSource}
/>
</React.Fragment>
);
Expand Down
3 changes: 3 additions & 0 deletions packages/doenetml-iframe/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ export default defineConfig({
}),
suppressLogPlugin(),
],
server: {
host: "0.0.0.0",
},
build: {
minify: false,
outDir: "dist/component",
Expand Down
36 changes: 18 additions & 18 deletions packages/standalone/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,41 @@
<script></script>
<div class="doenetml-viewer">
<script type="text/doenetml">
<m>\frac{5}{6}</m>
<p>1+1=<answer>2</answer></p>
<graph>
<m>\frac{5}{6}</m>
<p>1+1=<answer>2</answer></p>
<graph>

<line through="(-8,8) (9,6)" />
<line through="(0,4)" slope="1/2" styleNumber="2" />
<line through="(-8,8) (9,6)" />
<line through="(0,4)" slope="1/2" styleNumber="2" />

<line equation="y=2x-8" styleNumber="3" />
<line equation="x=-6" styleNumber="4" />
<line equation="y=2x-8" styleNumber="3" />
<line equation="x=-6" styleNumber="4" />

</graph>
</graph>
</script>
</div>
<div class="doenetml-viewer" data-doenet-read-only="true">
<script type="text/doenetml">
<m>\frac{4}{5}</m>
<p>1+2=<answer>3</answer></p>
<m>\frac{4}{5}</m>
<p>1+2=<answer>3</answer></p>

<graph>
<graph>

<line through="(0,4)" slope="1/2" styleNumber="2" />
<line through="(0,4)" slope="1/2" styleNumber="2" />

</graph>
</graph>
</script>
</div>

<div class="doenetml-editor" data-doenet-height="600px">
<script type="text/doenetml">
<m>\frac{3}{4}</m>
<p>1+3=<answer>4</answer></p>
<graph showNavigation="false">
<m>\frac{3}{4}</m>
<p>1+3=<answer>4</answer></p>
<graph showNavigation="false">

<line through="(-8,8) (9,6)" />
<line through="(-8,8) (9,6)" />

</graph>
</graph>
</script>
</div>
</body>
Expand Down
50 changes: 46 additions & 4 deletions packages/standalone/src/test-main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,55 @@ import {
renderDoenetEditorToContainer,
} from "./index";

const SOURCE_STORAGE_KEY_PREFIX = "doenetml-standalone-dev-source-";
const SAVE_DEBOUNCE_MS = 500;

const saveTimers = new Map<string, ReturnType<typeof window.setTimeout>>();

// Wired to the editor's immediate (per-keystroke) change callback, so debounce
// the writes: calling localStorage.setItem synchronously on every keystroke can
// noticeably block the UI for larger documents.
function saveSource(key: string, source: string) {
const pending = saveTimers.get(key);
if (pending !== undefined) {
window.clearTimeout(pending);
}
saveTimers.set(
Comment on lines +18 to +23
key,
window.setTimeout(() => {
saveTimers.delete(key);
try {
localStorage.setItem(key, source);
} catch {
// Ignore localStorage failures in constrained environments.
}
}, SAVE_DEBOUNCE_MS),
);
}

document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".doenetml-viewer").forEach((container) => {
console.log("Rendering doenet viewer to container", container);
renderDoenetViewerToContainer(container);
});
document.querySelectorAll(".doenetml-editor").forEach((container) => {
console.log("Rendering doenet editor to container", container);
renderDoenetEditorToContainer(container);
});
document
.querySelectorAll(".doenetml-editor")
.forEach((container, index) => {
console.log("Rendering doenet editor to container", container);
const storageKey = `${SOURCE_STORAGE_KEY_PREFIX}${index}`;
let storedSource: string | null = null;
try {
storedSource = localStorage.getItem(storageKey);
} catch {
// Ignore localStorage failures in constrained environments.
}
renderDoenetEditorToContainer(
container,
storedSource ?? undefined,
{
Comment thread
siefkenj marked this conversation as resolved.
immediateDoenetmlChangeCallback: (source: string) =>
saveSource(storageKey, source),
},
);
});
});
3 changes: 3 additions & 0 deletions packages/standalone/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ export default defineConfig({
}),
suppressLogPlugin(),
],
server: {
host: "0.0.0.0",
},
build: {
minify: true,
sourcemap: true,
Expand Down