• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

divio / django-cms / #30120

14 Nov 2025 01:00AM UTC coverage: 89.921%. Remained the same
#30120

push

travis-ci

web-flow
Merge 73415788f into c38b75715

1333 of 2144 branches covered (62.17%)

416 of 567 new or added lines in 27 files covered. (73.37%)

421 existing lines in 12 files now uncovered.

9207 of 10239 relevant lines covered (89.92%)

11.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

58.18
/cms/static/cms/js/modules/keyboard.js
1
// Minimal Keyboard-Modul mit Kontext und Event-Registrierung
2

3
/* global KeyboardEvent */
4
const DEFAULT_CONTEXT = 'cms';
1✔
5
const contexts = {
1✔
6
    DEFAULT_CONTEXT: {}
7
};
8
let currentContext = DEFAULT_CONTEXT;
9
let lastKey = null;
1✔
10

11
function isInputFocused() {
12
    const activeElement = document.activeElement;
2✔
13

14
    if (!activeElement) {
2!
NEW
15
        return false;
×
16
    }
17
    const tagName = activeElement.tagName.toLowerCase();
2✔
18

19
    return tagName === 'input' || tagName === 'textarea' || tagName === 'select' || activeElement.isContentEditable;
2✔
20
}
21

22
function setContext(ctx) {
23
    currentContext = ctx;
145✔
24
}
25

26
function getContext() {
27
    return currentContext;
40✔
28
}
29

30
function bind(key, callback, ctx = null) {
194✔
31
    if (Array.isArray(key)) {
194!
NEW
32
        key.forEach(k => bind(k, callback, ctx));
×
NEW
33
        return;
×
34
    }
35
    const context = ctx || currentContext;
194✔
36

37
    if (!contexts[context]) {
194✔
38
        contexts[context] = {};
1✔
39
    }
40
    contexts[context][key] = callback;
194✔
41
}
42

43
function unbind(key, ctx = null) {
×
NEW
44
    if (Array.isArray(key)) {
×
NEW
45
        key.forEach(k => unbind(k, ctx));
×
NEW
46
        return;
×
47
    }
NEW
48
    const context = ctx || currentContext;
×
49

NEW
50
    if (contexts[context]) {
×
NEW
51
        delete contexts[context][key];
×
52
    }
53
}
54

55
function toKeyCode(event) {
56
    const isLetter = /^Key[a-zA-Z]$/.test(event.code) || event.code === 'Space' || event.code === 'Enter';
1✔
57
    let key = /^Key[a-zA-Z]$/.test(event.code) ? event.code.slice(-1) : event.key;
1!
58

59
    if (event.code === 'Space') {
1!
NEW
60
        key = 'space';
×
61
    }
62
    if (isLetter) {
1!
NEW
63
        if (event.altKey) {
×
NEW
64
            key = `alt+${key}`;
×
65
        }
NEW
66
        if (event.ctrlKey) {
×
NEW
67
            key = `ctrl+${key}`;
×
68
        }
NEW
69
        if (event.shiftKey) {
×
NEW
70
            key = `shift+${key}`;
×
71
        }
72
    }
73
    return key.toLowerCase();
1✔
74
}
75

76
function handleKeydown(event) {
77
    if (isInputFocused()) {
2✔
78
        return;
1✔
79
    }
80
    const context = contexts[currentContext] || contexts[DEFAULT_CONTEXT];
1!
81
    const key = toKeyCode(event);
1✔
82

83
    if (context) {
1!
84
        if (context[key]) {
1!
85
            context[key](event);
1✔
NEW
86
        } else if (lastKey) {
×
NEW
87
            const comboKey = `${lastKey} > ${key}`;
×
88

NEW
89
            if (context[comboKey]) {
×
NEW
90
                context[comboKey](event);
×
91
            }
92
        }
93
    }
94
    lastKey = null;
1✔
95
}
96

97
function handleKeyup(event) {
NEW
98
    if (isInputFocused()) {
×
NEW
99
        return;
×
100
    }
NEW
101
    lastKey = toKeyCode(event);
×
102
}
103

104
function pressKey(key) {
105
    const event = new KeyboardEvent('keydown', { key });
2✔
106

107
    handleKeydown(event);
2✔
108
}
109

110
window.addEventListener('keydown', handleKeydown);
1✔
111
window.addEventListener('keyup', handleKeyup);
1✔
112

113
const keyboard = {
1✔
114
    setContext,
115
    getContext,
116
    bind,
117
    unbind,
118
    pressKey
119
};
120

121
export default keyboard;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc