summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/utils/dom.js
blob: 0cae85cbc87850e182297ec1d7464a6b90b81595 (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
/**
 * DOM Utils
 */

let globalLeftClickTargets = {};

function $(selector, context = document) { // Get the first matching element
    const element = context.querySelector(selector);

    return element || null;
}

function $$(selector, context = document) { // Get every matching element as an array
    const elements = context.querySelectorAll(selector);

    return [].slice.call(elements);
}

function showEl(...elements) {
    [].concat(...elements).forEach(el => el.classList.remove('hidden'));
}

function hideEl(...elements) {
    [].concat(...elements).forEach(el => el.classList.add('hidden'));
}

function toggleEl(...elements) {
    [].concat(...elements).forEach(el => el.classList.toggle('hidden'));
}

function clearEl(...elements) {
    [].concat(...elements).forEach(el => { while (el.firstChild) el.removeChild(el.firstChild); });
}

function removeEl(...elements) {
    [].concat(...elements).forEach(el => el.parentNode.removeChild(el));
}

function makeEl(tag, attr = {}) {
    const el = document.createElement(tag);
    for (const prop in attr) el[prop] = attr[prop];
    return el;
}

function insertBefore(existingElement, newElement) {
    existingElement.parentNode.insertBefore(newElement, existingElement);
}

function onLeftClick(callback, context = document) {
    context.addEventListener('click', event => {
        if (event.button === 0) callback(event);
    });
}

function onGlobalLeftClick(targets) {
    for (const key in targets) {
        if (targets.hasOwnProperty(key)) {
            globalLeftClickTargets[key] = targets[key];
        }
    }
}

function whenReady(callback) { // Execute a function when the DOM is ready
    if (document.readyState !== 'loading') callback();
    else document.addEventListener('DOMContentLoaded', callback);
}

function escapeHtml(html) {
    return html.replace(/&/g, '&')
        .replace(/>/g, '>')
        .replace(/</g, '&lt;')
        .replace(/"/g, '&quot;');
}

function findFirstTextNode(of) {
    return Array.prototype.filter.call(of.childNodes, el => el.nodeType === Node.TEXT_NODE)[0];
}

function setupGlobalEvents() {
    document.addEventListener('click', evt => {
        if (evt.button !== 0) return;
        for (const target in globalLeftClickTargets) {
            if (evt.target && evt.target.closest(target)) {
                const result = globalLeftClickTargets[target](evt.target.closest(target));

                if (result === false) {
                    evt.preventDefault();
                }
            }
        }
    });
}

export { $, $$, showEl, hideEl, toggleEl, clearEl, removeEl, makeEl, insertBefore, onLeftClick, onGlobalLeftClick, setupGlobalEvents, whenReady, escapeHtml, findFirstTextNode };