You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { closest } from '../utils/util.js'
  2. /**
  3. * Manages focus when a presentation is embedded. This
  4. * helps us only capture keyboard from the presentation
  5. * a user is currently interacting with in a page where
  6. * multiple presentations are embedded.
  7. */
  8. const STATE_FOCUS = 'focus';
  9. const STATE_BLUR = 'blur';
  10. export default class Focus {
  11. constructor( Reveal ) {
  12. this.Reveal = Reveal;
  13. this.onRevealPointerDown = this.onRevealPointerDown.bind( this );
  14. this.onDocumentPointerDown = this.onDocumentPointerDown.bind( this );
  15. }
  16. /**
  17. * Called when the reveal.js config is updated.
  18. */
  19. configure( config, oldConfig ) {
  20. if( config.embedded ) {
  21. this.blur();
  22. }
  23. else {
  24. this.focus();
  25. this.unbind();
  26. }
  27. }
  28. bind() {
  29. if( this.Reveal.getConfig().embedded ) {
  30. this.Reveal.getRevealElement().addEventListener( 'pointerdown', this.onRevealPointerDown, false );
  31. }
  32. }
  33. unbind() {
  34. this.Reveal.getRevealElement().removeEventListener( 'pointerdown', this.onRevealPointerDown, false );
  35. document.removeEventListener( 'pointerdown', this.onDocumentPointerDown, false );
  36. }
  37. focus() {
  38. if( this.state !== STATE_FOCUS ) {
  39. this.Reveal.getRevealElement().classList.add( 'focused' );
  40. document.addEventListener( 'pointerdown', this.onDocumentPointerDown, false );
  41. }
  42. this.state = STATE_FOCUS;
  43. }
  44. blur() {
  45. if( this.state !== STATE_BLUR ) {
  46. this.Reveal.getRevealElement().classList.remove( 'focused' );
  47. document.removeEventListener( 'pointerdown', this.onDocumentPointerDown, false );
  48. }
  49. this.state = STATE_BLUR;
  50. }
  51. isFocused() {
  52. return this.state === STATE_FOCUS;
  53. }
  54. destroy() {
  55. this.Reveal.getRevealElement().classList.remove( 'focused' );
  56. }
  57. onRevealPointerDown( event ) {
  58. this.focus();
  59. }
  60. onDocumentPointerDown( event ) {
  61. let revealElement = closest( event.target, '.reveal' );
  62. if( !revealElement || revealElement !== this.Reveal.getRevealElement() ) {
  63. this.blur();
  64. }
  65. }
  66. }