@doenet/doenetml-iframe 0.7.21-dev.352 → 0.7.21-dev.353
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -1
- package/index.d.ts +28 -1
- package/index.js +32 -3
- package/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -80,7 +80,7 @@ the inner viewer applies them with the same semantics as the in-process
|
|
|
80
80
|
|
|
81
81
|
| Prop change | Effect |
|
|
82
82
|
| -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
83
|
-
| `render`, `darkMode`, `flags`, `answerResponseCounts`, callbacks, …
|
|
83
|
+
| `render`, `darkMode`, `styleOverrides`, `flags`, `answerResponseCounts`, callbacks, … | applied live, no reload (flipping `render` false→true starts the document in the already-loaded realm) |
|
|
84
84
|
| `doenetML`, `activityId`, `docId`, `attemptNumber`, `requestedVariantIndex` | the document's core re-initializes **inside the same iframe realm** — the multi-MB bundle is not re-parsed |
|
|
85
85
|
| `initialState`, `forceDisable` and the other `force*` props, `userId` | read at (re-)initialization only, exactly like the in-process viewer — change `docId`/`attemptNumber` or remount via `key=` to apply |
|
|
86
86
|
| `standaloneUrl`, `cssUrl`, `doenetmlVersion` (or a version change detected in `doenetML`), `useSharedCoreWorker` | a different bundle/realm is required, so the iframe reloads |
|
|
@@ -88,6 +88,91 @@ the inner viewer applies them with the same semantics as the in-process
|
|
|
88
88
|
To force a full remount (fresh realm and worker), change the component's
|
|
89
89
|
React `key`.
|
|
90
90
|
|
|
91
|
+
### Reader style overrides (`styleOverrides`)
|
|
92
|
+
|
|
93
|
+
Hosts can let a **reader** remap what each style number looks like — for
|
|
94
|
+
example a color-blind user picking colors they can better tell apart — by
|
|
95
|
+
passing a `styleOverrides` prop (type `ReaderStyleOverrides`, re-exported
|
|
96
|
+
from this package). Overrides win over everything authored in the document
|
|
97
|
+
(`<styleDefinition>` and `<stylePalette>` alike) and update live when the
|
|
98
|
+
prop changes:
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
<DoenetViewer
|
|
102
|
+
doenetML={source}
|
|
103
|
+
styleOverrides={{
|
|
104
|
+
styles: {
|
|
105
|
+
1: { lineColor: "#0072b2", markerColor: "#0072b2" },
|
|
106
|
+
2: { lineColor: "#d55e00", lineWidth: 6 },
|
|
107
|
+
},
|
|
108
|
+
}}
|
|
109
|
+
/>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
A reader can also switch the whole document to one of the built-in style
|
|
113
|
+
palettes by name (case-insensitive) — for example `grayscale`, four grays
|
|
114
|
+
laddered for maximum luminance separation, for readers who distinguish
|
|
115
|
+
styles by lightness alone, or `okabeito` for common color vision
|
|
116
|
+
deficiencies:
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
<DoenetViewer
|
|
120
|
+
doenetML={source}
|
|
121
|
+
styleOverrides={{ palette: "grayscale" }}
|
|
122
|
+
/>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
A reader-selected palette replaces the document's base styles everywhere:
|
|
126
|
+
authored `<stylePalette>` selections and `<styleDefinition>` customizations
|
|
127
|
+
are discarded (they were tuned against different colors), style numbers
|
|
128
|
+
beyond the reader palette's size wrap around onto it, and any `styles`
|
|
129
|
+
overrides apply on top of the reader's palette. Unregistered palette names
|
|
130
|
+
are ignored, so offer readers the palette list as fixed choices.
|
|
131
|
+
|
|
132
|
+
Every style-definition key is overridable except the `*Word` descriptors:
|
|
133
|
+
all colors (including the `*DarkMode` variants), opacities, `lineWidth`,
|
|
134
|
+
`lineStyle`, `markerStyle`, `markerSize`, `markerFilled`, and the fill
|
|
135
|
+
settings. Human-readable color/style words are always re-derived from the
|
|
136
|
+
overridden values, so text style descriptions (e.g. "the blue line") stay
|
|
137
|
+
truthful, and a missing dark-mode color is derived from the reader's
|
|
138
|
+
light-mode color with the same accessibility-aware derivation authored
|
|
139
|
+
styles get. Pass `null` (or omit the prop) to clear all overrides.
|
|
140
|
+
|
|
141
|
+
The same prop exists on `<DoenetEditor>`, where it applies to the editor's
|
|
142
|
+
rendered preview (the code pane and context help keep showing the authored
|
|
143
|
+
values).
|
|
144
|
+
|
|
145
|
+
#### Listing the available palettes (`onStylePalettes`)
|
|
146
|
+
|
|
147
|
+
To build a palette picker, a host needs the palettes that the DoenetML
|
|
148
|
+
version **inside the iframe** supports — this wrapper and the standalone
|
|
149
|
+
bundle ship separately, and a host may pin an older `doenetmlVersion`. The
|
|
150
|
+
`onStylePalettes` callback fires once the bundle has booted, with that
|
|
151
|
+
bundle's palettes:
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
const [palettes, setPalettes] = React.useState(null);
|
|
155
|
+
|
|
156
|
+
<DoenetViewer
|
|
157
|
+
doenetML={source}
|
|
158
|
+
onStylePalettes={setPalettes}
|
|
159
|
+
styleOverrides={chosenPalette ? { palette: chosenPalette } : undefined}
|
|
160
|
+
/>;
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Each entry is `{ name, description, styles }`, where `styles` is keyed by
|
|
164
|
+
style number (contiguous from 1, always at least four) and each style is a
|
|
165
|
+
fully-resolved style definition — `lineColor`, `markerColor`, `fillColor`,
|
|
166
|
+
`textColor` and their `*DarkMode` variants for swatches in either theme,
|
|
167
|
+
plus `lineWidth`, `lineStyle`, `markerStyle`, and `markerSize` for the
|
|
168
|
+
non-color distinctions palettes also carry, and the `*Word` fields (e.g.
|
|
169
|
+
`"blue"`) for labelling swatches accessibly. Feed a chosen `name` back in as
|
|
170
|
+
the `palette` field of `styleOverrides`.
|
|
171
|
+
|
|
172
|
+
The callback receives `null` when the booted bundle predates palette
|
|
173
|
+
discovery, which is the host's cue to hide the picker. The same prop exists
|
|
174
|
+
on `<DoenetEditor>`.
|
|
175
|
+
|
|
91
176
|
Function props (callbacks) are forwarded across the iframe boundary via
|
|
92
177
|
Comlink proxies and always follow the latest identity passed — parents may
|
|
93
178
|
pass inline arrow functions freely; identity churn does not re-render the
|
package/index.d.ts
CHANGED
|
@@ -15,6 +15,9 @@ import { MediaLicenseDisplay } from '../packages/utils/dist';
|
|
|
15
15
|
import { MediaLicenseInfo } from '../packages/utils/dist';
|
|
16
16
|
import { MediaLicenseKind } from '../packages/utils/dist';
|
|
17
17
|
import { mediaLicenses } from '../packages/utils/dist';
|
|
18
|
+
import { ReaderStyleOverrides } from '../packages/utils/dist';
|
|
19
|
+
import { ReaderStyleValueOverrides } from '../packages/utils/dist';
|
|
20
|
+
import { StylePaletteInfo } from '../packages/utils/dist';
|
|
18
21
|
import { WarningRecord } from '../packages/utils/dist';
|
|
19
22
|
|
|
20
23
|
export { CreativeCommonsVersion }
|
|
@@ -32,6 +35,15 @@ export declare const DoenetEditor: default_2.ForwardRefExoticComponent<Omit<Doen
|
|
|
32
35
|
export { DoenetEditorHandle }
|
|
33
36
|
|
|
34
37
|
export declare type DoenetEditorIframeProps = DoenetEditorProps & {
|
|
38
|
+
/**
|
|
39
|
+
* Called once the standalone bundle inside the iframe has booted, with
|
|
40
|
+
* the style palettes THAT bundle supports — the source of truth for a
|
|
41
|
+
* host rendering a palette picker, since the iframe may run a pinned or
|
|
42
|
+
* older DoenetML version than this wrapper. Receives `null` when the
|
|
43
|
+
* booted bundle predates palette discovery. Feed a chosen palette name
|
|
44
|
+
* back in as the `palette` field of `styleOverrides`.
|
|
45
|
+
*/
|
|
46
|
+
onStylePalettes?: (palettes: StylePaletteInfo[] | null) => void;
|
|
35
47
|
doenetML: string;
|
|
36
48
|
/**
|
|
37
49
|
* The URL of a standalone DoenetML bundle. This may be from the CDN.
|
|
@@ -86,10 +98,19 @@ declare type DoenetEditorProps = Omit<React.ComponentProps<typeof DoenetEditor_2
|
|
|
86
98
|
* v0.7.18 cannot re-render in place; for those the wrapper falls back to
|
|
87
99
|
* reloading the iframe on any prop change, its historical behavior.)
|
|
88
100
|
*/
|
|
89
|
-
export declare function DoenetViewer({ doenetML, standaloneUrl: specifiedStandaloneUrl, cssUrl: specifiedCssUrl, doenetmlVersion: specifiedDoenetmlVersion, autodetectVersion, useSharedCoreWorker, mountPolicy, keepLive, ...doenetViewerProps }: DoenetViewerIframeProps): default_2.JSX.Element | null;
|
|
101
|
+
export declare function DoenetViewer({ doenetML, standaloneUrl: specifiedStandaloneUrl, cssUrl: specifiedCssUrl, doenetmlVersion: specifiedDoenetmlVersion, autodetectVersion, useSharedCoreWorker, mountPolicy, keepLive, onStylePalettes, ...doenetViewerProps }: DoenetViewerIframeProps): default_2.JSX.Element | null;
|
|
90
102
|
|
|
91
103
|
export declare type DoenetViewerIframeProps = DoenetViewerProps & {
|
|
92
104
|
doenetML: string;
|
|
105
|
+
/**
|
|
106
|
+
* Called once the standalone bundle inside the iframe has booted, with
|
|
107
|
+
* the style palettes THAT bundle supports — the source of truth for a
|
|
108
|
+
* host rendering a palette picker, since the iframe may run a pinned or
|
|
109
|
+
* older DoenetML version than this wrapper. Receives `null` when the
|
|
110
|
+
* booted bundle predates palette discovery. Feed a chosen palette name
|
|
111
|
+
* back in as the `palette` field of `styleOverrides`.
|
|
112
|
+
*/
|
|
113
|
+
onStylePalettes?: (palettes: StylePaletteInfo[] | null) => void;
|
|
93
114
|
/**
|
|
94
115
|
* The URL of a standalone DoenetML bundle. This may be from the CDN.
|
|
95
116
|
* If autodetectVersion is `true` and a version is detected, this URL is ignored.
|
|
@@ -250,6 +271,12 @@ export declare type MountPolicy = {
|
|
|
250
271
|
maxConcurrentBoots?: number;
|
|
251
272
|
};
|
|
252
273
|
|
|
274
|
+
export { ReaderStyleOverrides }
|
|
275
|
+
|
|
276
|
+
export { ReaderStyleValueOverrides }
|
|
277
|
+
|
|
278
|
+
export { StylePaletteInfo }
|
|
279
|
+
|
|
253
280
|
export declare const version: string;
|
|
254
281
|
|
|
255
282
|
export { WarningRecord }
|
package/index.js
CHANGED
|
@@ -26957,7 +26957,7 @@ function requireCssesc$1() {
|
|
|
26957
26957
|
return cssesc_1$1;
|
|
26958
26958
|
}
|
|
26959
26959
|
requireCssesc$1();
|
|
26960
|
-
const viewerIframeJsSource = '(function() {\n "use strict";\n let lastAugmentedProps = null;\n let currentFunctionProps = {};\n const functionPropDispatchers = {};\n function getFunctionPropDispatcher(key) {\n let dispatcher = functionPropDispatchers[key];\n if (!dispatcher) {\n if (key === "reportScoreAndStateCallback" && typeof doenetWindowedViewer !== "undefined" && doenetWindowedViewer) {\n dispatcher = (report) => messageParentFromViewer({\n type: "reportScoreAndState",\n report\n });\n } else {\n dispatcher = (...callArgs) => currentFunctionProps[key]?.(...callArgs);\n }\n functionPropDispatchers[key] = dispatcher;\n }\n return dispatcher;\n }\n function functionPropArgsToMap(args) {\n const map = {};\n for (let i = 0; i < args.length; i += 2) {\n const key = args[i];\n const fn = args[i + 1];\n if (typeof key === "string" && typeof fn === "function") {\n map[key] = fn;\n }\n }\n return map;\n }\n function releaseFunctionProxy(fn) {\n try {\n fn?.[ComlinkViewer.releaseProxy]?.();\n } catch (e) {\n console.warn(\n "iframe DoenetViewer: failed to release stale Comlink proxy",\n e\n );\n }\n }\n function setCurrentFunctionProps(incoming) {\n for (const [key, fn] of Object.entries(currentFunctionProps)) {\n if (incoming[key] !== fn) {\n releaseFunctionProxy(fn);\n }\n }\n currentFunctionProps = incoming;\n }\n function defaultRequestScrollTo(offset) {\n messageParentFromViewer({ type: "scrollTo", offset });\n }\n function syncAugmentedFunctionProps() {\n if (!lastAugmentedProps) {\n return;\n }\n const next = {};\n for (const [key, val] of Object.entries(lastAugmentedProps)) {\n if (typeof val !== "function") {\n next[key] = val;\n }\n }\n for (const key of Object.keys(currentFunctionProps)) {\n next[key] = getFunctionPropDispatcher(key);\n }\n if (!("requestScrollTo" in next)) {\n next.requestScrollTo = defaultRequestScrollTo;\n }\n lastAugmentedProps = next;\n }\n let currentDoenetMLSource = null;\n function resolveDoenetMLSource(root) {\n if (currentDoenetMLSource !== null) {\n return currentDoenetMLSource;\n }\n const scriptTag = root.querySelector(\'script[type="text/doenetml"]\');\n currentDoenetMLSource = scriptTag?.innerHTML ?? "";\n return currentDoenetMLSource;\n }\n async function waitForStandaloneBundle(timeoutMs) {\n if (typeof window.renderDoenetViewerToContainer === "function") {\n return true;\n }\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n await new Promise((resolve) => setTimeout(resolve, 50));\n if (typeof window.renderDoenetViewerToContainer === "function") {\n return true;\n }\n }\n return false;\n }\n ComlinkViewer.expose(\n {\n renderViewerWithFunctionProps,\n updateViewerProps(updatedSerializableProps) {\n if (!lastAugmentedProps) {\n console.warn(\n "iframe DoenetViewer: updateViewerProps arrived before renderViewerWithFunctionProps completed — likely a bug in the iframe wrapper\'s queue/replay sequencing."\n );\n return;\n }\n const { doenetML, ...rest } = updatedSerializableProps;\n if (typeof doenetML === "string") {\n currentDoenetMLSource = doenetML;\n }\n lastAugmentedProps = {\n ...lastAugmentedProps,\n ...rest\n };\n renderWithLastAugmentedProps();\n },\n updateViewerFunctionProps(...args) {\n if (!lastAugmentedProps) {\n console.warn(\n "iframe DoenetViewer: updateViewerFunctionProps arrived before renderViewerWithFunctionProps completed — likely a bug in the iframe wrapper\'s queue/replay sequencing."\n );\n return;\n }\n const incoming = functionPropArgsToMap(args);\n const prevKeys = Object.keys(currentFunctionProps).sort();\n const nextKeys = Object.keys(incoming).sort();\n const keysChanged = prevKeys.length !== nextKeys.length || prevKeys.some((key, i) => key !== nextKeys[i]);\n setCurrentFunctionProps(incoming);\n if (keysChanged) {\n syncAugmentedFunctionProps();\n renderWithLastAugmentedProps();\n }\n }\n },\n ComlinkViewer.windowEndpoint(globalThis.parent)\n );\n function renderViewerWithFunctionProps(...args) {\n setCurrentFunctionProps(functionPropArgsToMap(args));\n const augmentedDoenetViewerProps = { ...doenetViewerProps };\n augmentedDoenetViewerProps.externalVirtualKeyboardProvided = true;\n for (const propName of doenetViewerPropsSpecified) {\n if (!(propName in doenetViewerProps) && propName in currentFunctionProps) {\n augmentedDoenetViewerProps[propName] = getFunctionPropDispatcher(propName);\n }\n }\n if (!doenetViewerPropsSpecified.includes("requestScrollTo")) {\n augmentedDoenetViewerProps.requestScrollTo = defaultRequestScrollTo;\n }\n lastAugmentedProps = augmentedDoenetViewerProps;\n renderWithLastAugmentedProps();\n }\n function renderWithLastAugmentedProps() {\n const root = document.getElementById("root");\n window.renderDoenetViewerToContainer(\n root,\n resolveDoenetMLSource(root),\n lastAugmentedProps\n );\n }\n function installSharedCorePortProvider() {\n let coreCounter = 0;\n window.doenetGlobalConfig.createExternalCoreWorkerPort = () => {\n const coreId = `${viewerId}-core-${++coreCounter}`;\n const channel = new MessageChannel();\n window.parent.postMessage(\n { origin: viewerId, data: { type: "createSharedCore", coreId } },\n window.parent.origin,\n [channel.port2]\n );\n return {\n port: channel.port1,\n destroy: (suspectWedge) => {\n messageParentFromViewer({\n type: "destroySharedCore",\n coreId,\n suspectWedge: Boolean(suspectWedge)\n });\n }\n };\n };\n }\n (async () => {\n if (await waitForStandaloneBundle(6e4)) {\n if (typeof doenetSharedCoreWorker !== "undefined" && doenetSharedCoreWorker) {\n installSharedCorePortProvider();\n }\n messageParentFromViewer({
|
|
26960
|
+
const viewerIframeJsSource = '(function() {\n "use strict";\n let lastAugmentedProps = null;\n let currentFunctionProps = {};\n const functionPropDispatchers = {};\n function getFunctionPropDispatcher(key) {\n let dispatcher = functionPropDispatchers[key];\n if (!dispatcher) {\n if (key === "reportScoreAndStateCallback" && typeof doenetWindowedViewer !== "undefined" && doenetWindowedViewer) {\n dispatcher = (report) => messageParentFromViewer({\n type: "reportScoreAndState",\n report\n });\n } else {\n dispatcher = (...callArgs) => currentFunctionProps[key]?.(...callArgs);\n }\n functionPropDispatchers[key] = dispatcher;\n }\n return dispatcher;\n }\n function functionPropArgsToMap(args) {\n const map = {};\n for (let i = 0; i < args.length; i += 2) {\n const key = args[i];\n const fn = args[i + 1];\n if (typeof key === "string" && typeof fn === "function") {\n map[key] = fn;\n }\n }\n return map;\n }\n function releaseFunctionProxy(fn) {\n try {\n fn?.[ComlinkViewer.releaseProxy]?.();\n } catch (e) {\n console.warn(\n "iframe DoenetViewer: failed to release stale Comlink proxy",\n e\n );\n }\n }\n function setCurrentFunctionProps(incoming) {\n for (const [key, fn] of Object.entries(currentFunctionProps)) {\n if (incoming[key] !== fn) {\n releaseFunctionProxy(fn);\n }\n }\n currentFunctionProps = incoming;\n }\n function defaultRequestScrollTo(offset) {\n messageParentFromViewer({ type: "scrollTo", offset });\n }\n function syncAugmentedFunctionProps() {\n if (!lastAugmentedProps) {\n return;\n }\n const next = {};\n for (const [key, val] of Object.entries(lastAugmentedProps)) {\n if (typeof val !== "function") {\n next[key] = val;\n }\n }\n for (const key of Object.keys(currentFunctionProps)) {\n next[key] = getFunctionPropDispatcher(key);\n }\n if (!("requestScrollTo" in next)) {\n next.requestScrollTo = defaultRequestScrollTo;\n }\n lastAugmentedProps = next;\n }\n let currentDoenetMLSource = null;\n function resolveDoenetMLSource(root) {\n if (currentDoenetMLSource !== null) {\n return currentDoenetMLSource;\n }\n const scriptTag = root.querySelector(\'script[type="text/doenetml"]\');\n currentDoenetMLSource = scriptTag?.innerHTML ?? "";\n return currentDoenetMLSource;\n }\n async function waitForStandaloneBundle(timeoutMs) {\n if (typeof window.renderDoenetViewerToContainer === "function") {\n return true;\n }\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n await new Promise((resolve) => setTimeout(resolve, 50));\n if (typeof window.renderDoenetViewerToContainer === "function") {\n return true;\n }\n }\n return false;\n }\n ComlinkViewer.expose(\n {\n renderViewerWithFunctionProps,\n updateViewerProps(updatedSerializableProps) {\n if (!lastAugmentedProps) {\n console.warn(\n "iframe DoenetViewer: updateViewerProps arrived before renderViewerWithFunctionProps completed — likely a bug in the iframe wrapper\'s queue/replay sequencing."\n );\n return;\n }\n const { doenetML, ...rest } = updatedSerializableProps;\n if (typeof doenetML === "string") {\n currentDoenetMLSource = doenetML;\n }\n lastAugmentedProps = {\n ...lastAugmentedProps,\n ...rest\n };\n renderWithLastAugmentedProps();\n },\n updateViewerFunctionProps(...args) {\n if (!lastAugmentedProps) {\n console.warn(\n "iframe DoenetViewer: updateViewerFunctionProps arrived before renderViewerWithFunctionProps completed — likely a bug in the iframe wrapper\'s queue/replay sequencing."\n );\n return;\n }\n const incoming = functionPropArgsToMap(args);\n const prevKeys = Object.keys(currentFunctionProps).sort();\n const nextKeys = Object.keys(incoming).sort();\n const keysChanged = prevKeys.length !== nextKeys.length || prevKeys.some((key, i) => key !== nextKeys[i]);\n setCurrentFunctionProps(incoming);\n if (keysChanged) {\n syncAugmentedFunctionProps();\n renderWithLastAugmentedProps();\n }\n }\n },\n ComlinkViewer.windowEndpoint(globalThis.parent)\n );\n function renderViewerWithFunctionProps(...args) {\n setCurrentFunctionProps(functionPropArgsToMap(args));\n const augmentedDoenetViewerProps = { ...doenetViewerProps };\n augmentedDoenetViewerProps.externalVirtualKeyboardProvided = true;\n for (const propName of doenetViewerPropsSpecified) {\n if (!(propName in doenetViewerProps) && propName in currentFunctionProps) {\n augmentedDoenetViewerProps[propName] = getFunctionPropDispatcher(propName);\n }\n }\n if (!doenetViewerPropsSpecified.includes("requestScrollTo")) {\n augmentedDoenetViewerProps.requestScrollTo = defaultRequestScrollTo;\n }\n lastAugmentedProps = augmentedDoenetViewerProps;\n renderWithLastAugmentedProps();\n }\n function renderWithLastAugmentedProps() {\n const root = document.getElementById("root");\n window.renderDoenetViewerToContainer(\n root,\n resolveDoenetMLSource(root),\n lastAugmentedProps\n );\n }\n function installSharedCorePortProvider() {\n let coreCounter = 0;\n window.doenetGlobalConfig.createExternalCoreWorkerPort = () => {\n const coreId = `${viewerId}-core-${++coreCounter}`;\n const channel = new MessageChannel();\n window.parent.postMessage(\n { origin: viewerId, data: { type: "createSharedCore", coreId } },\n window.parent.origin,\n [channel.port2]\n );\n return {\n port: channel.port1,\n destroy: (suspectWedge) => {\n messageParentFromViewer({\n type: "destroySharedCore",\n coreId,\n suspectWedge: Boolean(suspectWedge)\n });\n }\n };\n };\n }\n (async () => {\n if (await waitForStandaloneBundle(6e4)) {\n if (typeof doenetSharedCoreWorker !== "undefined" && doenetSharedCoreWorker) {\n installSharedCorePortProvider();\n }\n messageParentFromViewer({\n iframeReady: true,\n stylePalettes: readStylePalettesFromBundle()\n });\n } else {\n messageParentFromViewer({\n error: "Invalid DoenetML version or DoenetML package not found"\n });\n }\n })().catch((err) => {\n console.error(\n "iframe DoenetViewer: unexpected failure while signalling iframeReady",\n err\n );\n try {\n messageParentFromViewer({\n error: "iframe viewer failed to initialize"\n });\n } catch {\n }\n });\n function readStylePalettesFromBundle() {\n try {\n return window.getDoenetStylePalettes?.() ?? null;\n } catch (err) {\n console.error(\n "iframe DoenetML: failed to read style palettes from the standalone bundle",\n err\n );\n return null;\n }\n }\n function messageParentFromViewer(data) {\n window.parent.postMessage(\n {\n origin: viewerId,\n data\n },\n window.parent.origin\n );\n }\n})();\n';
|
|
26961
26961
|
const editorIframeJsSource = `(function() {
|
|
26962
26962
|
"use strict";
|
|
26963
26963
|
let editorControlHandle = null;
|
|
@@ -27126,7 +27126,10 @@ const editorIframeJsSource = `(function() {
|
|
|
27126
27126
|
}
|
|
27127
27127
|
(async () => {
|
|
27128
27128
|
if (await waitForStandaloneBundle(6e4)) {
|
|
27129
|
-
messageParentFromEditor({
|
|
27129
|
+
messageParentFromEditor({
|
|
27130
|
+
iframeReady: true,
|
|
27131
|
+
stylePalettes: readStylePalettesFromBundle()
|
|
27132
|
+
});
|
|
27130
27133
|
} else {
|
|
27131
27134
|
messageParentFromEditor({
|
|
27132
27135
|
error: "Invalid DoenetML version or DoenetML package not found"
|
|
@@ -27144,6 +27147,17 @@ const editorIframeJsSource = `(function() {
|
|
|
27144
27147
|
} catch {
|
|
27145
27148
|
}
|
|
27146
27149
|
});
|
|
27150
|
+
function readStylePalettesFromBundle() {
|
|
27151
|
+
try {
|
|
27152
|
+
return window.getDoenetStylePalettes?.() ?? null;
|
|
27153
|
+
} catch (err) {
|
|
27154
|
+
console.error(
|
|
27155
|
+
"iframe DoenetML: failed to read style palettes from the standalone bundle",
|
|
27156
|
+
err
|
|
27157
|
+
);
|
|
27158
|
+
return null;
|
|
27159
|
+
}
|
|
27160
|
+
}
|
|
27147
27161
|
function messageParentFromEditor(data) {
|
|
27148
27162
|
window.parent.postMessage(
|
|
27149
27163
|
{
|
|
@@ -66089,7 +66103,7 @@ function ExternalVirtualKeyboard({
|
|
|
66089
66103
|
}
|
|
66090
66104
|
);
|
|
66091
66105
|
}
|
|
66092
|
-
const version = "0.7.21-dev.
|
|
66106
|
+
const version = "0.7.21-dev.353";
|
|
66093
66107
|
const latestDoenetmlVersion = version;
|
|
66094
66108
|
function subscribeToPinnedTheme() {
|
|
66095
66109
|
return () => {
|
|
@@ -66113,6 +66127,7 @@ function DoenetViewer({
|
|
|
66113
66127
|
useSharedCoreWorker = false,
|
|
66114
66128
|
mountPolicy,
|
|
66115
66129
|
keepLive = false,
|
|
66130
|
+
onStylePalettes,
|
|
66116
66131
|
...doenetViewerProps
|
|
66117
66132
|
}) {
|
|
66118
66133
|
const [id2, _2] = React__default.useState(() => Math.random().toString(36).slice(2));
|
|
@@ -66123,6 +66138,8 @@ function DoenetViewer({
|
|
|
66123
66138
|
const lastSentFunctionPropsRef = React__default.useRef(null);
|
|
66124
66139
|
const doenetViewerPropsRef = React__default.useRef(doenetViewerProps);
|
|
66125
66140
|
doenetViewerPropsRef.current = doenetViewerProps;
|
|
66141
|
+
const onStylePalettesRef = React__default.useRef(onStylePalettes);
|
|
66142
|
+
onStylePalettesRef.current = onStylePalettes;
|
|
66126
66143
|
const doenetMLRef = React__default.useRef(doenetML);
|
|
66127
66144
|
doenetMLRef.current = doenetML;
|
|
66128
66145
|
const windowed = mountPolicy?.mode === "windowed";
|
|
@@ -66369,6 +66386,9 @@ function DoenetViewer({
|
|
|
66369
66386
|
}
|
|
66370
66387
|
return setInErrorState(data.error);
|
|
66371
66388
|
} else if (data.iframeReady) {
|
|
66389
|
+
onStylePalettesRef.current?.(
|
|
66390
|
+
data.stylePalettes ?? null
|
|
66391
|
+
);
|
|
66372
66392
|
if (ref.current) {
|
|
66373
66393
|
const viewerIframe = wrap$3(
|
|
66374
66394
|
windowEndpoint(ref.current.contentWindow)
|
|
@@ -66721,6 +66741,9 @@ function serializePropsSnapshot(seed, props) {
|
|
|
66721
66741
|
snapshot[key] = val;
|
|
66722
66742
|
}
|
|
66723
66743
|
}
|
|
66744
|
+
if (snapshot.styleOverrides === void 0) {
|
|
66745
|
+
snapshot.styleOverrides = null;
|
|
66746
|
+
}
|
|
66724
66747
|
return JSON.stringify(snapshot);
|
|
66725
66748
|
}
|
|
66726
66749
|
function logComlinkError(component, method) {
|
|
@@ -66736,6 +66759,7 @@ const DoenetEditor = React__default.forwardRef(function DoenetEditor2({
|
|
|
66736
66759
|
width = "100%",
|
|
66737
66760
|
height = "500px",
|
|
66738
66761
|
autodetectVersion = true,
|
|
66762
|
+
onStylePalettes,
|
|
66739
66763
|
...doenetEditorProps
|
|
66740
66764
|
}, forwardedRef) {
|
|
66741
66765
|
const [id2, _2] = React__default.useState(() => Math.random().toString(36).slice(2));
|
|
@@ -66746,6 +66770,8 @@ const DoenetEditor = React__default.forwardRef(function DoenetEditor2({
|
|
|
66746
66770
|
const lastSentFunctionPropsRef = React__default.useRef(null);
|
|
66747
66771
|
const doenetEditorPropsRef = React__default.useRef(doenetEditorProps);
|
|
66748
66772
|
doenetEditorPropsRef.current = doenetEditorProps;
|
|
66773
|
+
const onStylePalettesRef = React__default.useRef(onStylePalettes);
|
|
66774
|
+
onStylePalettesRef.current = onStylePalettes;
|
|
66749
66775
|
const [inErrorState, setInErrorState] = React__default.useState(null);
|
|
66750
66776
|
const [ignoreDetectedVersion, setIgnoreDetectedVersion] = React__default.useState(false);
|
|
66751
66777
|
const [initialDiagnostics, setInitialDiagnostics] = React__default.useState([]);
|
|
@@ -66852,6 +66878,9 @@ const DoenetEditor = React__default.forwardRef(function DoenetEditor2({
|
|
|
66852
66878
|
if (data.error) {
|
|
66853
66879
|
return setInErrorState(data.error);
|
|
66854
66880
|
} else if (data.iframeReady) {
|
|
66881
|
+
onStylePalettesRef.current?.(
|
|
66882
|
+
data.stylePalettes ?? null
|
|
66883
|
+
);
|
|
66855
66884
|
if (ref.current) {
|
|
66856
66885
|
const editorIframe = wrap$3(
|
|
66857
66886
|
windowEndpoint(ref.current.contentWindow)
|