PageSourceSearch

https://www.la-traction.ch/DesignSystem/1_foundations/foundations.js

js la-traction.ch collected 2026-10-02 21:24:28 UTC 4,934 bytes, 150 lines download raw bytes

1import createProps from '../js/createProps.js'
2import { replaceTags } from '../js/replaceTags.js'
3
4class Foundations extends HTMLElement {
5    constructor() {
6        super()
7        // Properties
8        this.hasSelectors = false
9        this.replace = ''
10        //Events
11        this.boundOnLoad = this.onLoad.bind(this)
12    }
13
14    connectedCallback() {
15        createProps(this)
16        this.init()
17        this.bindEvent()
18        this.checkSelectors()
19        this.replaceTags()
20    }
21
22    init() {
23        document.documentElement.classList.add('mU')
24    }
25
26    onClick() {
27        document.documentElement.classList.remove('kU')
28        document.documentElement.classList.remove('tU')
29        document.documentElement.classList.add('mU')
30    }
31
32    onKeyTab(e) {
33        if (e.key === 'Tab') {
34            document.documentElement.classList.add('kU')
35        }
36    }
37
38    onTouch() {
39        document.documentElement.classList.remove('mU')
40        document.documentElement.classList.remove('kU')
41        document.documentElement.classList.add('tU')
42
43        // Disable mouse event during 300ms to not fire mousedown after touchstart
44        // 300ms delay is not enough, 350ms is working fine
45        // To know more about delay between touchstart and mousedown: https://web.dev/mobile-touchandmouse/
46        document.removeEventListener('mousedown', this.onClick)
47        setTimeout(() => {
48            document.addEventListener('mousedown', this.onClick)
49        }, 350)
50    }
51
52    replaceTags() {
53        if (this.replace === '') {
54            return
55        }
56        const tags = this.replace.split(',')
57        const main = document.querySelector('main')
58        tags.forEach(tag => {
59            replaceTags(tag.trim(), main)
60        })
61    }
62
63    checkSelectors() {
64        // This is needed until :has css selector is fully supported
65        if (!this.hasSelectors) {
66            return
67        }
68        this.hasSelectors = this.hasSelectors.split(',')
69        this.existingSelectors()
70        this.observeSelectors()
71    }
72
73    existingSelectors () {
74        // This is needed until :has css selector is fully supported
75        this.hasSelectors.forEach( selector => {
76            if (document.querySelector(selector)) {
77                this.foundedSelector(selector)
78            }
79        })
80    }
81
82    foundedSelector(selector) {
83        // This is needed until :has css selector is fully supported
84        let index = this.hasSelectors.indexOf(selector)
85        this.hasSelectors.splice(index, 1)
86        document.documentElement.classList.add('has-' + this.classClean(selector))
87    }
88
89    classClean(selector) {
90        // This is needed until :has css selector is fully supported
91        return selector.trim().replace('.', '')
92    }
93
94    observeSelectors() {
95        // This is needed until :has css selector is fully supported
96        const nb_selectors = this.hasSelectors.length
97        let nb_founds = 0
98        if (nb_founds === nb_selectors) {
99            return
100        }
101
102        const self = this
103        this.observer = new MutationObserver(mutations => {
104            mutations.forEach(function (mutation) {
105                mutation.addedNodes.forEach(function (added_node) {
106                    if (added_node.nodeType === 1) {
107                        self.hasSelectors.forEach( selector => {
108                            if (document.querySelector(selector)) {
109                                self.foundedSelector(selector)
110                                nb_founds += 1
111                                if (nb_founds === nb_selectors) {
112                                    self.observer.disconnect()
113                                }
114                            }
115                        })
116                    }
117                })
118            })
119        })
120        this.observer.observe(document.body, { subtree: true, childList: true })
121    }
122
123    onLoad() {
124        // This is needed until :has css selector is fully supported
125        this.observer?.disconnect()
126    }
127
128    bindEvent() {
129        this.unbindEvent()
130        document.addEventListener('mousedown', this.onClick)
131        document.addEventListener('keydown', this.onKeyTab)
132        document.addEventListener('touchstart', this.onTouch, false)
133        window.addEventListener('load', this.boundOnLoad)
134    }
135
136    unbindEvent() {
137        document.removeEventListener('mousedown', this.onClick)
138        document.removeEventListener('keydown', this.onKeyTab)
139        document.removeEventListener('touchstart', this.onTouch, false)
140        window.removeEventListener('load', this.boundOnLoad)
141    }
142
143    disconnectedCallback() {
144        this.unbindEvent()
145    }
146}
147
148customElements.get('u-foundations') || customElements.define('u-foundations', Foundations)
149
150export default Foundations

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.