Skip to content

Commit

Permalink
Fix window undefined issue (#227)
Browse files Browse the repository at this point in the history
  • Loading branch information
siefkenj authored Aug 1, 2024
1 parent 35d22e4 commit aacaca5
Show file tree
Hide file tree
Showing 10 changed files with 27 additions and 101 deletions.
83 changes: 3 additions & 80 deletions packages/docs-nextra/components/iframe-doenetml.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,11 @@
import React from "react";
import { DoenetViewer } from "@doenet/doenetml-iframe";
import "@doenet/virtual-keyboard/style.css";

/**
* Render DoenetML in an iframe so that its styling/state is completely isolated from the page.
*/
export function IframeDoenetML({ children }: React.PropsWithChildren<{}>) {
const ref = React.useRef<HTMLIFrameElement>(null);
const [height, setHeight] = React.useState("0px");

const onLoad = () => {
const iframe =
ref.current?.contentWindow?.document?.body?.parentElement;
if (!iframe) {
return;
}
setHeight(iframe.scrollHeight + "px");

const updateHeight = () => {
const iframe =
ref.current?.contentWindow?.document?.body?.parentElement;
if (!iframe) {
return;
}
const newHeight = iframe.scrollHeight + "px";
if (newHeight !== height) {
setHeight(newHeight);
}
};

const observer = new MutationObserver(updateHeight);
observer.observe(iframe, {
attributes: true,
childList: true,
subtree: true,
});

// The mutation observer might not catch all resize changes, so we poll as well.
const interval = setInterval(updateHeight, 500);

return () => {
observer.disconnect();
clearInterval(interval);
};
};
React.useEffect(() => {
return onLoad();
}, []);

if (typeof children !== "string") {
console.error(
"Error with DoenetML component. Expected a string child containing DoenetML source code, but found",
Expand All @@ -59,42 +19,5 @@ export function IframeDoenetML({ children }: React.PropsWithChildren<{}>) {
</div>
);
}
return (
<iframe
ref={ref}
srcDoc={createHtmlForDoenetML(children)}
style={{
width: "100%",
boxSizing: "content-box",
overflow: "hidden",
}}
height={height}
/>
);
}

/**
* Create HTML for a single page document that renders the given DoenetML.
*/
function createHtmlForDoenetML(doenetML: string) {
return `
<html>
<head>
<script type="module" src="/bundle/doenet-standalone.js"></script>
<link rel="stylesheet" href="/bundle/style.css">
</head>
<body>
<script type="module">
document.addEventListener("DOMContentLoaded", () => {
window.renderDoenetToContainer(document.getElementById("root"));
});
</script>
<div id="root" data-doenet-add-virtual-keyboard="false">
<script type="text/doenetml">
${doenetML}
</script>
</div>
</body>
</html>
`;
return <DoenetViewer doenetML={children} />;
}
1 change: 1 addition & 0 deletions packages/docs-nextra/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"public/bundle/**/*"
],
"dependencies": [
"../doenetml-iframe:build",
"../standalone:build",
"../doenetml:build"
]
Expand Down
2 changes: 0 additions & 2 deletions packages/docs-nextra/pages/reference/_meta.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { w } from "nextra/dist/types-BtS3w-gJ";

export default {
essentialConcepts: "Essential Concepts",
doenetML_components: "Components",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { DoenetML} from "../../../components/doenet"
import { DoenetMLExample } from "../../../components"

# Sliders

Earlier you learned how to use `<mathInput>` to allow users to input text. Sliders are another common way for readers to input values or control an on-screen activity. By default, the (self-closing) tag `<slider/>` creates the following generic slider:

<DoenetML>
<DoenetMLExample>
{`
<slider />
`}
</DoenetML>
</DoenetMLExample>

You can drag the point right and left to choose a value from 0 to 10. The default value is 0, and the "step size" is 1; in other words, the value changes by $\pm 1$ as you drag back and forth. All of these options (and more!) can be adjusted using attributes.

Expand Down
6 changes: 3 additions & 3 deletions packages/docs-nextra/pages/tutorials/quickStart.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DoenetML} from "../../components/doenet"
import { DoenetMLExample } from "../../components"
import { Callout } from 'nextra/components'

# Quick Start Tutorial Modified by Jason
Expand All @@ -8,13 +8,13 @@ DoenetML is an easy way to author interactive math activities for the web. In th

Here is an example math question with a place for students to type in and check their answers. Go ahead and answer the question and check your work.

<DoenetML>
<DoenetMLExample>
{`
Simplify
<math>3/3+3</math>
<answer symbolicEquality>4</answer>
`}
</DoenetML>
</DoenetMLExample>

Now lets look at the DoenetML you need to write to make this question.

Expand Down
2 changes: 1 addition & 1 deletion packages/docs-nextra/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"incremental": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"moduleResolution": "Bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
Expand Down
3 changes: 2 additions & 1 deletion packages/doenetml-iframe/vite.config-iframe-editor.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { defineConfig } from "vite";
import dts from "vite-plugin-dts";

// https://vitejs.dev/config/
export default defineConfig({
base: "./",
plugins: [],
plugins: [dts()],
build: {
minify: false,
sourcemap: false,
Expand Down
3 changes: 2 additions & 1 deletion packages/doenetml-iframe/vite.config-iframe-viewer.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { defineConfig } from "vite";
import dts from "vite-plugin-dts";

// https://vitejs.dev/config/
export default defineConfig({
base: "./",
plugins: [],
plugins: [dts()],
build: {
minify: false,
sourcemap: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import ReactDOM from "react-dom";
import { createPortal } from "react-dom";
import { OnClick } from "./keyboard";
import { ManagedKeyboard } from "./managed-keyboard";
import classNames from "classnames";
Expand Down Expand Up @@ -27,7 +27,7 @@ const KeyboardIcon = () => (
export function KeyboardTray({ onClick }: { onClick: OnClick }) {
const [open, setOpen] = React.useState(false);

return ReactDOM.createPortal(
return createPortal(
<div
id="virtual-keyboard-tray"
className={classNames({ open })}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ type VirtualKeyboardState = {
callbacks: OnClick[];
};

const virtualKeyboardState: VirtualKeyboardState = (window as any)
.virtualKeyboardState || {
count: 0,
keyboardDomNode: null,
keyboardReactRoot: null,
callbacks: [],
};
(window as any).virtualKeyboardState = virtualKeyboardState;
const globalThis = Function("return this")() || {};

const virtualKeyboardState: VirtualKeyboardState =
globalThis?.virtualKeyboardState || {
count: 0,
keyboardDomNode: null,
keyboardReactRoot: null,
callbacks: [],
};
globalThis.virtualKeyboardState = virtualKeyboardState;

/**
* An expandable keyboard tray that is unique among the document. If multiple instances of `UniqueKeyboardTray` are used,
Expand Down

0 comments on commit aacaca5

Please sign in to comment.