aboutsummaryrefslogtreecommitdiffstats
path: root/static/utils.js
blob: 0545d15cbe3fc5130163b9c7e155661e76fe5b8f (plain)
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
document.addEventListener('DOMContentLoaded', () => {
  initMaterializeHelper(window.materializeHelper || {})
})

function initMaterializeHelper(customOptions) {
  const options = {
    debug: false,
    selectOptions: true,
    selectTriggers: true,
    autocompletedInputLabels: true,
    ...customOptions
  }

  if (options.selectOptions)
    fixSelectOptions(options.debug)
    fixNavbarDropdown(options.debug)
  if (options.selectTriggers)
    fixSelectTriggers(options.debug)
  if (options.autocompletedInputLabels)
    fixAutocompletedInputLabels(options.debug)
}

/**
 * Issue: Select element is misbehaving on iOS.
 * When clicking one option, other one is being selected...
 */
function fixSelectOptions(debug) {
  setTimeout(() => { // To be called after M.FormSelect.init()
    let dragging = false
    const opts = { passive: false }
    const options = document.querySelectorAll('.select-wrapper ul.select-dropdown li')
  
    if (options.length && debug) {
      console.info('[Materialize Helper] Fixed select options', { options })
    }
  
    for (const option of options) {
      option.addEventListener('touchmove', () => { dragging = true }, opts)
      option.addEventListener('touchstart', () => { dragging = false }, opts)
      option.addEventListener('touchend', (e) => {
        if (dragging) return
        else e.stopPropagation()
      }, opts)
    }
  }, 0)
}

function fixNavbarDropdown(debug) {
  setTimeout(() => { // To be called after M.FormSelect.init()
    let dragging = false
    const opts = { passive: false }
    const options = document.querySelectorAll('ul.dropdown-content li')
  
    if (options.length && debug) {
      console.info('[Materialize Helper] Fixed navbar dropdown', { options })
    }
  
    for (const option of options) {
      option.addEventListener('touchmove', () => { dragging = true }, opts)
      option.addEventListener('touchstart', () => { dragging = false }, opts)
      option.addEventListener('touchend', (e) => {
        if (dragging) return
        else e.stopPropagation()
      }, opts)
    }
  }, 0)
}

/**
 * Issue: Select triggers are causing Lighthouse warnings.
 */
function fixSelectTriggers(debug) {
  setTimeout(() => { // To be called after M.FormSelect.init()
    const triggers = document.querySelectorAll('input.select-dropdown.dropdown-trigger')

    for (const trigger of triggers) {
      const wrapper = trigger.closest('.select-wrapper')
      const select = wrapper.querySelector('select')
      const option = select.options[select.selectedIndex]
      trigger.placeholder = option.text
    }

    if (triggers.length && debug) {
      console.info('[Materialize Helper] Fixed select triggers', { triggers })
    }
  }, 0)
}

/**
 * Issue: Input label is covering an input when it's autocompleted.
 */
function fixAutocompletedInputLabels(debug) {
  document.addEventListener('onautocomplete', function(e) {
    const input = e.target
    const label = input.parentNode.querySelector(`label[for="${input.id}"]`)
    const autocompleted = input.hasAttribute('autocompleted')
    
    if (autocompleted && label) {
      label.classList.add('active')
      input.classList.add('valid')

      if (debug) {
        console.info('[Materialize Helper] Fixed autocompleted input label', { input, label })
      }
    }
  })
}