2023-05-23 19:50:14 +02:00
|
|
|
import { closest } from "../utils/util.js";
|
2020-05-26 10:45:05 +02:00
|
|
|
|
2020-05-11 09:15:02 +02:00
|
|
|
/**
|
|
|
|
* Manages focus when a presentation is embedded. This
|
|
|
|
* helps us only capture keyboard from the presentation
|
|
|
|
* a user is currently interacting with in a page where
|
|
|
|
* multiple presentations are embedded.
|
|
|
|
*/
|
|
|
|
|
2023-05-23 19:50:14 +02:00
|
|
|
const STATE_FOCUS = "focus";
|
|
|
|
const STATE_BLUR = "blur";
|
2020-05-11 09:15:02 +02:00
|
|
|
|
|
|
|
export default class Focus {
|
2023-05-23 19:50:14 +02:00
|
|
|
constructor(Reveal) {
|
|
|
|
this.Reveal = Reveal;
|
|
|
|
|
|
|
|
this.onRevealPointerDown = this.onRevealPointerDown.bind(this);
|
|
|
|
this.onDocumentPointerDown = this.onDocumentPointerDown.bind(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called when the reveal.js config is updated.
|
|
|
|
*/
|
|
|
|
configure(config, oldConfig) {
|
|
|
|
if (config.embedded) {
|
|
|
|
this.blur();
|
|
|
|
} else {
|
|
|
|
this.focus();
|
|
|
|
this.unbind();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bind() {
|
|
|
|
if (this.Reveal.getConfig().embedded) {
|
|
|
|
this.Reveal.getRevealElement().addEventListener(
|
|
|
|
"pointerdown",
|
|
|
|
this.onRevealPointerDown,
|
|
|
|
false
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unbind() {
|
|
|
|
this.Reveal.getRevealElement().removeEventListener(
|
|
|
|
"pointerdown",
|
|
|
|
this.onRevealPointerDown,
|
|
|
|
false
|
|
|
|
);
|
|
|
|
document.removeEventListener(
|
|
|
|
"pointerdown",
|
|
|
|
this.onDocumentPointerDown,
|
|
|
|
false
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
focus() {
|
|
|
|
if (this.state !== STATE_FOCUS) {
|
|
|
|
this.Reveal.getRevealElement().classList.add("focused");
|
|
|
|
document.addEventListener(
|
|
|
|
"pointerdown",
|
|
|
|
this.onDocumentPointerDown,
|
|
|
|
false
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.state = STATE_FOCUS;
|
|
|
|
}
|
|
|
|
|
|
|
|
blur() {
|
|
|
|
if (this.state !== STATE_BLUR) {
|
|
|
|
this.Reveal.getRevealElement().classList.remove("focused");
|
|
|
|
document.removeEventListener(
|
|
|
|
"pointerdown",
|
|
|
|
this.onDocumentPointerDown,
|
|
|
|
false
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.state = STATE_BLUR;
|
|
|
|
}
|
|
|
|
|
|
|
|
isFocused() {
|
|
|
|
return this.state === STATE_FOCUS;
|
|
|
|
}
|
|
|
|
|
|
|
|
destroy() {
|
|
|
|
this.Reveal.getRevealElement().classList.remove("focused");
|
|
|
|
}
|
|
|
|
|
|
|
|
onRevealPointerDown(event) {
|
|
|
|
this.focus();
|
|
|
|
}
|
|
|
|
|
|
|
|
onDocumentPointerDown(event) {
|
|
|
|
let revealElement = closest(event.target, ".reveal");
|
|
|
|
if (!revealElement || revealElement !== this.Reveal.getRevealElement()) {
|
|
|
|
this.blur();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|