code.pablomurad.com

htmlepessoas.com

Brazilian Portuguese translation of the book HTML for People

src/assets/js/app.js raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
document.addEventListener('DOMContentLoaded', () => {
  const settings = document.querySelector('.settings');
  if (settings) {
    settings.removeAttribute('hidden');
  }
  fitVids();
});

/* Theme toggle */
customElements.define(
  'theme-toggle',
  class extends HTMLElement {
    #theme = 'light';

    constructor() {
      super();
      this.#theme = localStorage.getItem('user-color-scheme') || 'light';
    }

    connectedCallback() {
      this.querySelector('input').checked = this.#theme === 'dark';

      this.querySelector('input').addEventListener('change', () => {
        this.#theme = this.#theme === 'light' ? 'dark' : 'light';
        window.applyThemeSetting(this.#theme);
      });
    }
  },
);

/* Code wrap */
customElements.define(
  'code-wrap',
  class extends HTMLElement {
    #wrapCode = true;

    constructor() {
      super();
      const value = localStorage.getItem('wrap-code');
      this.#wrapCode = value !== 'false';
    }

    connectedCallback() {
      this.querySelector('input').checked = this.#wrapCode;
      document.body.classList.toggle('wrap-code', this.#wrapCode);

      this.querySelector('input').addEventListener('change', () => {
        this.#wrapCode = !this.#wrapCode;
        localStorage.setItem('wrap-code', this.#wrapCode);
        document.body.classList.toggle('wrap-code', this.#wrapCode);
      });
    }
  },
);

/* Elevator button */
customElements.define(
  'elevator-button',
  class extends HTMLElement {
    #a = null;
    #target = null;

    constructor() {
      super();
      this.addEventListener('click', () => {
        const detailsEl = document.querySelector('.main-menu');
        detailsEl.open = true;
      });

      document.addEventListener('scroll', () => {
        if (this.isTargetInViewport()) {
          this.#a.classList.remove('active');
          return;
        }
        this.#a.classList.add('active');
      });
    }

    connectedCallback() {
      this.#a = this.querySelector('a');
      this.#target = document.querySelector(this.#a.getAttribute('href'));
    }

    isTargetInViewport() {
      return isInViewport(this.#target);
    }
  },
);

// Determine if an element is in the visible viewport
function isInViewport(el, partiallyVisible = false) {
  const { top, left, bottom, right } = el.getBoundingClientRect();
  const { innerHeight, innerWidth } = window;
  return partiallyVisible
    ? ((top > 0 && top < innerHeight) ||
        (bottom > 0 && bottom < innerHeight)) &&
        ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
    : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
}

function fitVids() {
  const videoSources = ['iframe[src*="youtube"]', 'iframe[src*="vimeo"]'];

  document.querySelectorAll(videoSources.join(',')).forEach((video) => {
    video.style.width = '100%';
    video.style.height = 'auto';
    video.style.aspectRatio = `${video.getAttribute(
      'width',
    )} / ${video.getAttribute('height')}`;
  });
}