@doenet/doenetml-iframe 0.7.23-dev.472 → 0.7.23-dev.476

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.
Files changed (4) hide show
  1. package/index.js +134 -24
  2. package/index.js.map +1 -1
  3. package/package.json +1 -1
  4. package/style.css +240 -23
package/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as React from "react";
2
2
  import React__default, { createContext, useMemo, useCallback, useLayoutEffect, useEffect, useRef, useState, useContext, isValidElement } from "react";
3
3
  import { MathJaxBaseContext, MathJax } from "better-react-mathjax";
4
- import { createRoot } from "react-dom/client";
5
4
  import { createPortal } from "react-dom";
5
+ import { createRoot } from "react-dom/client";
6
6
  const proxyMarker = /* @__PURE__ */ Symbol("Comlink.proxy");
7
7
  const createEndpoint = /* @__PURE__ */ Symbol("Comlink.endpoint");
8
8
  const releaseProxy = /* @__PURE__ */ Symbol("Comlink.releaseProxy");
@@ -41880,6 +41880,13 @@ function requireClassnames() {
41880
41880
  var classnamesExports = requireClassnames();
41881
41881
  const classNames = /* @__PURE__ */ getDefaultExportFromCjs$1(classnamesExports);
41882
41882
  const untranslated = (key, _args, fallback) => fallback ?? key;
41883
+ const VIRTUAL_KEYBOARD_TRAY_ID = "virtual-keyboard-tray";
41884
+ function getVirtualKeyboardTrayElement() {
41885
+ return document.getElementById(VIRTUAL_KEYBOARD_TRAY_ID);
41886
+ }
41887
+ function isInVirtualKeyboardTray(node) {
41888
+ return node instanceof Node && (getVirtualKeyboardTrayElement()?.contains(node) ?? false);
41889
+ }
41883
41890
  const KeyboardIcon = () => /* @__PURE__ */ React__default.createElement(
41884
41891
  "svg",
41885
41892
  {
@@ -41897,48 +41904,47 @@ const KeyboardIcon = () => /* @__PURE__ */ React__default.createElement(
41897
41904
  );
41898
41905
  function KeyboardTray({
41899
41906
  onClick,
41907
+ open,
41908
+ onOpenChange,
41900
41909
  theme,
41901
41910
  translate,
41902
41911
  direction
41903
41912
  }) {
41904
- const [open, setOpen] = React__default.useState(false);
41905
41913
  const t4 = translate ?? untranslated;
41906
41914
  const openLabel = t4("keyboard-open", void 0, "Open Keyboard");
41907
41915
  const closeLabel = t4("keyboard-close", void 0, "Close Keyboard");
41916
+ const containerRef = React__default.useRef(null);
41917
+ React__default.useLayoutEffect(() => {
41918
+ if (open && containerRef.current) {
41919
+ containerRef.current.scrollTop = 0;
41920
+ }
41921
+ }, [open]);
41908
41922
  return createPortal(
41909
41923
  /* @__PURE__ */ React__default.createElement(
41910
41924
  "div",
41911
41925
  {
41912
- id: "virtual-keyboard-tray",
41926
+ id: VIRTUAL_KEYBOARD_TRAY_ID,
41913
41927
  "data-theme": theme,
41914
41928
  dir: direction,
41915
41929
  className: classNames({ open }),
41916
- onMouseDown: () => {
41917
- onClick([
41918
- { type: "accessed", command: "", timestamp: +/* @__PURE__ */ new Date() }
41919
- ]);
41920
- },
41921
- onClick: () => {
41922
- onClick([
41923
- { type: "accessed", command: "", timestamp: +/* @__PURE__ */ new Date() }
41924
- ]);
41925
- }
41930
+ onPointerDown: (e2) => e2.preventDefault(),
41931
+ onMouseDown: (e2) => e2.preventDefault()
41926
41932
  },
41927
41933
  /* @__PURE__ */ React__default.createElement(
41928
41934
  "button",
41929
41935
  {
41930
41936
  className: "open-keyboard-button",
41931
- onClick: () => setOpen((old) => !old),
41937
+ onClick: () => onOpenChange(!open),
41932
41938
  title: open ? closeLabel : openLabel,
41933
41939
  "aria-label": open ? closeLabel : openLabel
41934
41940
  },
41935
41941
  /* @__PURE__ */ React__default.createElement(KeyboardIcon, null)
41936
41942
  ),
41937
- /* @__PURE__ */ React__default.createElement("div", { className: "keyboard-container" }, /* @__PURE__ */ React__default.createElement(
41943
+ /* @__PURE__ */ React__default.createElement("div", { className: "keyboard-container", ref: containerRef }, /* @__PURE__ */ React__default.createElement(
41938
41944
  "button",
41939
41945
  {
41940
41946
  className: "close-keyboard-button",
41941
- onClick: () => setOpen(false),
41947
+ onClick: () => onOpenChange(false),
41942
41948
  title: closeLabel,
41943
41949
  "aria-label": closeLabel
41944
41950
  },
@@ -67624,6 +67630,17 @@ function flatten_array(t4, n2) {
67624
67630
  for (var r2 = 0; r2 < t4.length; r2++) Array.isArray(t4[r2]) ? flatten_array(t4[r2], n2) : n2.push(t4[r2]);
67625
67631
  return n2;
67626
67632
  }
67633
+ const COARSE_POINTER_QUERY = "(pointer: coarse)";
67634
+ function getCoarsePointerQueryList() {
67635
+ const matchMedia = globalThis.matchMedia;
67636
+ if (typeof matchMedia !== "function") {
67637
+ return null;
67638
+ }
67639
+ return matchMedia(COARSE_POINTER_QUERY);
67640
+ }
67641
+ function hasCoarsePrimaryPointer() {
67642
+ return getCoarsePointerQueryList()?.matches ?? false;
67643
+ }
67627
67644
  var base32$1 = { exports: {} };
67628
67645
  var hasRequiredBase32;
67629
67646
  function requireBase32() {
@@ -68213,6 +68230,10 @@ requireCssesc();
68213
68230
  const globalThis$1 = Function("return this")() || {};
68214
68231
  const virtualKeyboardState = globalThis$1?.virtualKeyboardState || {
68215
68232
  count: 0,
68233
+ open: false,
68234
+ userClosedTray: false,
68235
+ openListeners: /* @__PURE__ */ new Set(),
68236
+ focusedMathInputSources: /* @__PURE__ */ new Set(),
68216
68237
  keyboardDomNode: null,
68217
68238
  keyboardReactRoot: null,
68218
68239
  registrations: [],
@@ -68228,9 +68249,6 @@ function getRegistrationById(id2) {
68228
68249
  (registration) => registration.id === id2
68229
68250
  ) ?? null;
68230
68251
  }
68231
- function getTrayElement() {
68232
- return document.getElementById("virtual-keyboard-tray");
68233
- }
68234
68252
  function getActiveRegistration() {
68235
68253
  const activeElement = document.activeElement;
68236
68254
  for (let i2 = virtualKeyboardState.registrations.length - 1; i2 >= 0; i2 -= 1) {
@@ -68241,7 +68259,7 @@ function getActiveRegistration() {
68241
68259
  return registration;
68242
68260
  }
68243
68261
  }
68244
- if (activeElement instanceof Node && getTrayElement()?.contains(activeElement)) {
68262
+ if (isInVirtualKeyboardTray(activeElement)) {
68245
68263
  return getRegistrationById(
68246
68264
  virtualKeyboardState.lastActiveRegistrationId
68247
68265
  );
@@ -68262,12 +68280,63 @@ function getTrayRegistration() {
68262
68280
  const registrations = virtualKeyboardState.registrations;
68263
68281
  return registrations[registrations.length - 1];
68264
68282
  }
68283
+ function broadcastKeyboardChoice(open) {
68284
+ const choice = [
68285
+ { type: "keyboardChoice", command: open ? "virtual" : "system" }
68286
+ ];
68287
+ for (const registration of virtualKeyboardState.registrations) {
68288
+ registration.onClick(choice);
68289
+ }
68290
+ }
68291
+ function getTrayOpen() {
68292
+ return virtualKeyboardState.open;
68293
+ }
68294
+ function subscribeToTrayOpen(listener) {
68295
+ virtualKeyboardState.openListeners.add(listener);
68296
+ return () => {
68297
+ virtualKeyboardState.openListeners.delete(listener);
68298
+ };
68299
+ }
68300
+ function setTrayOpen(open, { byUser }) {
68301
+ if (byUser) {
68302
+ virtualKeyboardState.userClosedTray = !open;
68303
+ broadcastKeyboardChoice(open);
68304
+ }
68305
+ if (virtualKeyboardState.open === open) {
68306
+ return;
68307
+ }
68308
+ virtualKeyboardState.open = open;
68309
+ for (const listener of virtualKeyboardState.openListeners) {
68310
+ listener();
68311
+ }
68312
+ }
68313
+ function reportMathInputFocus(source, mathInputFocused) {
68314
+ if (!hasCoarsePrimaryPointer()) {
68315
+ return;
68316
+ }
68317
+ const focusedSources = virtualKeyboardState.focusedMathInputSources;
68318
+ if (mathInputFocused) {
68319
+ focusedSources.add(source);
68320
+ if (!virtualKeyboardState.userClosedTray) {
68321
+ setTrayOpen(true, { byUser: false });
68322
+ }
68323
+ return;
68324
+ }
68325
+ if (isInVirtualKeyboardTray(document.activeElement)) {
68326
+ return;
68327
+ }
68328
+ focusedSources.delete(source);
68329
+ if (focusedSources.size > 0) {
68330
+ return;
68331
+ }
68332
+ setTrayOpen(false, { byUser: false });
68333
+ }
68265
68334
  function rerenderTray() {
68266
68335
  const registration = getTrayRegistration();
68267
68336
  const theme = registration?.theme;
68268
68337
  const translate = registration?.translate;
68269
68338
  const direction = registration?.direction;
68270
- const trayEl = getTrayElement();
68339
+ const trayEl = getVirtualKeyboardTrayElement();
68271
68340
  if (trayEl) {
68272
68341
  const currentTheme = trayEl.getAttribute("data-theme") ?? void 0;
68273
68342
  const currentDirection = trayEl.getAttribute("dir") ?? void 0;
@@ -68280,17 +68349,38 @@ function rerenderTray() {
68280
68349
  renderTray(theme, translate, direction)
68281
68350
  );
68282
68351
  }
68283
- function renderTray(theme, translate, direction) {
68284
- return /* @__PURE__ */ React__default.createElement(MathJaxContext, { config: mathjaxConfig, version: 4 }, /* @__PURE__ */ React__default.createElement(
68352
+ function TrayWithSharedOpenState({
68353
+ theme,
68354
+ translate,
68355
+ direction
68356
+ }) {
68357
+ const open = React__default.useSyncExternalStore(
68358
+ subscribeToTrayOpen,
68359
+ getTrayOpen,
68360
+ getTrayOpen
68361
+ );
68362
+ return /* @__PURE__ */ React__default.createElement(
68285
68363
  KeyboardTray,
68286
68364
  {
68287
68365
  theme,
68288
68366
  translate,
68289
68367
  direction,
68368
+ open,
68369
+ onOpenChange: (nextOpen) => setTrayOpen(nextOpen, { byUser: true }),
68290
68370
  onClick: (e2) => {
68291
68371
  getActiveRegistration()?.onClick(e2);
68292
68372
  }
68293
68373
  }
68374
+ );
68375
+ }
68376
+ function renderTray(theme, translate, direction) {
68377
+ return /* @__PURE__ */ React__default.createElement(MathJaxContext, { config: mathjaxConfig, version: 4 }, /* @__PURE__ */ React__default.createElement(
68378
+ TrayWithSharedOpenState,
68379
+ {
68380
+ theme,
68381
+ translate,
68382
+ direction
68383
+ }
68294
68384
  ));
68295
68385
  }
68296
68386
  function UniqueKeyboardTray({
@@ -68361,6 +68451,9 @@ function UniqueKeyboardTray({
68361
68451
  );
68362
68452
  virtualKeyboardState.keyboardDomNode = null;
68363
68453
  }
68454
+ virtualKeyboardState.open = false;
68455
+ virtualKeyboardState.userClosedTray = false;
68456
+ virtualKeyboardState.focusedMathInputSources.clear();
68364
68457
  } else {
68365
68458
  rerenderTray();
68366
68459
  }
@@ -68383,6 +68476,23 @@ function ExternalVirtualKeyboard({
68383
68476
  theme,
68384
68477
  ownerRef
68385
68478
  }) {
68479
+ React__default.useEffect(() => {
68480
+ let reportedFocused = false;
68481
+ function listener(event) {
68482
+ if (event.source !== ownerRef.current?.contentWindow || event.data?.subject !== "keyboard-focus") {
68483
+ return;
68484
+ }
68485
+ reportedFocused = event.data.mathInputFocused;
68486
+ reportMathInputFocus(ownerRef, reportedFocused);
68487
+ }
68488
+ window.addEventListener("message", listener);
68489
+ return () => {
68490
+ window.removeEventListener("message", listener);
68491
+ if (reportedFocused) {
68492
+ reportMathInputFocus(ownerRef, false);
68493
+ }
68494
+ };
68495
+ }, [ownerRef]);
68386
68496
  return /* @__PURE__ */ React__default.createElement(
68387
68497
  UniqueKeyboardTray,
68388
68498
  {
@@ -68408,7 +68518,7 @@ function ExternalVirtualKeyboard({
68408
68518
  }
68409
68519
  );
68410
68520
  }
68411
- const version = "0.7.23-dev.472";
68521
+ const version = "0.7.23-dev.476";
68412
68522
  const latestDoenetmlVersion = version;
68413
68523
  function subscribeToPinnedTheme() {
68414
68524
  return () => {