Skip to content

Commit

Permalink
Merge pull request Doenet#24 from dqnykamp/virtkey
Browse files Browse the repository at this point in the history
detect if the accessing keyboard caused mathinput blur
  • Loading branch information
siefkenj authored Jun 18, 2024
2 parents 2e87e0e + e3c0dfb commit 8b1e0ed
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 47 deletions.
64 changes: 21 additions & 43 deletions packages/doenetml/src/Viewer/renderers/mathInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ export default function MathInput(props) {
const [focused, setFocused] = useState(null);
const textareaRef = useRef(null); // Ref to keep track of the mathInput's disabled state

const lastKeyboardAccessTime = useRef(0);
const keyboardCausedBlur = useRef(false);

const setRendererState = useSetRecoilState(rendererState(rendererName));

const { showAnswerTitles } = useContext(PageContext) || {};
Expand Down Expand Up @@ -102,28 +105,22 @@ export default function MathInput(props) {
}
};

const handleVirtualKeyboardClick = (text) => {
if (!mathField) {
const handleVirtualKeyboardClick = ({ type, command, timestamp }) => {
lastKeyboardAccessTime.current = timestamp;

if (!mathField || !keyboardCausedBlur.current) {
return;
}
mathField.focus();
if (!text) {
console.log("Empty value");

return;
}
const splitCommand = text.split(" ");
const command = splitCommand[0];
const input = text.substring(command.length + 1);

if (command == "cmd") {
mathField.cmd(input);
} else if (command == "write") {
mathField.write(input);
} else if (command == "keystroke") {
mathField.keystroke(input);
} else if (command == "type") {
mathField.typedText(input);
if (type == "cmd") {
mathField.cmd(command);
} else if (type == "write") {
mathField.write(command);
} else if (type == "keystroke") {
mathField.keystroke(command);
} else if (type == "type") {
mathField.typedText(command);
}
};

Expand Down Expand Up @@ -165,6 +162,12 @@ export default function MathInput(props) {
});
// console.log(">>>", e.relatedTarget.id, checkWorkButton.props.id);
setFocused(false);

// If the keyboard blur was immediately preceded by a keyboard access,
// then the blur was likely caused by clicking on the keyboard.
// (The mousedown event on the keyboard seems to be processed before the blur event.)
keyboardCausedBlur.current =
Math.abs(lastKeyboardAccessTime.current - new Date()) < 100;
};

const onChangeHandler = (text) => {
Expand Down Expand Up @@ -398,31 +401,6 @@ export default function MathInput(props) {
textareaRef.current =
document.createElement("textarea");
textareaRef.current.disabled = SVs.disabled;
textareaRef.current.addEventListener(
"focusout",
(e) => {
// apparently there are array-like things in javascript that
// can be converted to real arrays with Array.from()
// https://stackoverflow.com/a/22754453
let keyboards = Array.from(
document.getElementsByClassName(
"keyboardcontainer",
),
);
keyboards.forEach((keyboard) => {
if (
keyboard?.contains(
e.relatedTarget,
)
) {
e.target.focus();
} else {
// remove focus
}
});
},
false,
);
return textareaRef.current;
},
}} //more commands go here
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,26 @@ export function KeyboardTray({ onClick }: { onClick: OnClick }) {
const [open, setOpen] = React.useState(false);

return ReactDOM.createPortal(
<div id="virtual-keyboard-tray" className={classNames({ open })}>
<div
id="virtual-keyboard-tray"
className={classNames({ open })}
onMouseDown={() => {
// The mousedown event appears to precede a blur event on a mathInput,
// so this access event will set the accessed timestamp to be
// just before the time of the blur if keyboard is clicked while the mathInput is focused.
onClick([
{ type: "accessed", command: "", timestamp: +new Date() },
]);
}}
onClick={() => {
// If the keyboard is clicked but a key is not clicked, then we send
// this accessed event to make sure the math input is still re-focused after the click.
// (The click event appears to occur after the blur event on a mathInput.)
onClick([
{ type: "accessed", command: "", timestamp: +new Date() },
]);
}}
>
<button
className="open-keyboard-button"
onClick={() => setOpen((old) => !old)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,13 @@ function Key({
return (
<button
className={`key key-${keyInfo.name} ${keyInfo.isMath ? "math" : ""}`}
onClick={() => onClick(keyInfo.commands)}
onClick={(e) => {
// Prevent the click event on the keyboard itself from triggering
// so that its "accessed" event doesn't cancel the propagation
// of the key click event.
e.stopPropagation();
onClick(keyInfo.commands);
}}
title={`Type ${keyInfo.name}`}
>
{content}
Expand Down
3 changes: 2 additions & 1 deletion packages/virtual-keyboard/src/virtual-keyboard-new/keys.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export type KeyCommand = {
type: "keystroke" | "type" | "write" | "cmd";
type: "keystroke" | "type" | "write" | "cmd" | "accessed";
command: string;
timestamp?: number;
};

export type KeyDescription = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ export function translateKeyboardEvent(commands: KeyCommand[]) {
return { focusedMathFieldReturn: "" };
}

return { focusedMathField: `${command.type} ${command.command}` };
return { focusedMathField: command };
});
}

0 comments on commit 8b1e0ed

Please sign in to comment.