PageSourceSearch

https://www.grammatip.de/javascripts/dad_answer_setup.js

js grammatip.de collected 2026-10-01 23:52:32 UTC 4,642 bytes, 121 lines download raw bytes

1(function () {
2    if (typeof initDADOnWindowLoad !== 'undefined' && initDADOnWindowLoad === true) {
3        window.onload = () => {
4            init();
5        }
6    } else {
7        init(true);
8    }
9})();
10
11async function init(sidePanel = false) {
12    const wrappers = document.getElementsByClassName('drag-and-drop-questions');
13    const loadings = document.getElementsByClassName('drag-and-drop-loading');
14
15    const texts = document.querySelectorAll('.exercise-question div.dad-text, .exercise-snap-to div.dad-text');
16
17    for (const text of texts) {
18        const parent = text.parentElement;
19        const puzzle = parent.querySelector('svg');
20
21        const isText = text.innerHTML.trim().length > 0;
22        const isImg = parent.querySelector('img:not(.icon-svg)');
23        const isImgWithText = isImg && isText;
24        const isAudio = parent.querySelector('.soundplayermini');
25        const isAudioWithText = isAudio && isText;
26        const isExerciseQuestion = parent.classList.contains('exercise-question');
27        const minWidth = isExerciseQuestion ? 180 : 164;
28
29
30        /**
31         * Images with text have a fixed height on the text element, making .offsetHeight on text always return the same value.
32         * Therefore, we need to get the offsetHeight of the child element instead.
33         * One line of text is 24px high, so we set the max height to 24px.
34         */
35        const offsetHeightObject = isImgWithText || isAudioWithText ? text.children[0] : text;
36        const offsetHeightMax = isImgWithText || isAudioWithText ? 24 : 100;
37
38        // Subtract 20 from minWidth, as it will be added in `do {}`
39        let puzzleWidth = minWidth - 20;
40        do {
41            puzzleWidth += 20;
42            puzzle.setAttribute('width', puzzleWidth);
43            parent.style.width = puzzleWidth + 'px';
44
45            // Wait for the puzzle to be rendered before checking the height - Race condition
46            await new Promise(r => setTimeout(r, 0));
47        } while (offsetHeightObject.offsetHeight > offsetHeightMax && puzzleWidth < 350);
48        // While it's too high and below max width
49
50        if (isExerciseQuestion) {
51            // Left puzzle is 10 extra wide by default, so we need to compensate (notice M0 in right-puzzle.tpl and M10 in left-puzzle.tpl)
52            puzzleWidth += 10;
53
54            // Position line that sits between cards
55            const hover = parent.querySelectorAll('svg')[1];
56            hover.style.left = (puzzleWidth - 189) + 'px';
57
58            // Position right puzzle
59            const snapTo = parent.parentElement.querySelector('.exercise-snap-to');
60            snapTo.style.left = (puzzleWidth - 22) + 'px';
61        }
62
63        // Set SVG width
64        const path = puzzle.querySelector('path');
65        const d = path.getAttribute('d');
66        path.setAttribute('d', d.replace(/^M\d+/, 'M' + (puzzleWidth - minWidth)));
67
68        if (!isImg && !isAudio) {
69            text.style.height = '93%';
70        }
71
72        text.style.overflow = 'hidden';
73    }
74
75    // Position correct answers (provided on incorrect or missing answers)
76    const answers = document.getElementsByClassName('exercise-correct-answer');
77
78    for (const answer of answers) {
79        const parent = answer.parentElement;
80
81        // Min width is 160 (20 added in `do {}`)
82        let width = 140;
83        do {
84            width += 20;
85            answer.style.width = width + 'px';
86        } while (answer.offsetHeight > 90 && answer.offsetWidth < 350)
87
88        //Find how left the question should be
89        const question = parent.querySelector('.exercise-question');
90        const snapTo = parent.querySelector('.exercise-snap-to');
91        const left = (question.offsetWidth + snapTo.offsetWidth) - 30;
92
93        //Should add up to around a max of 600, to fit all sizes
94        if (width <= 200 && (left <= 400 || !sidePanel)) {
95
96            // Position to the right of right puzzle
97            answer.style.left = left + 'px';
98            answer.style.top = 6 + 'px';
99            answer.style.paddingLeft = 30 + 'px';
100            answer.style.height = 90 + 'px';
101        } else {
102            // Position below left puzzle if too wide
103            parent.style.marginBottom = 100 + 'px';
104
105            answer.style.left = 0 + 'px';
106            answer.style.top = 90 + 'px';
107            answer.style.height = 110 + 'px';
108            answer.style.paddingTop = 15 + 'px';
109        }
110
111        answer.style.overflow = 'hidden';
112    }
113
114    for (const loading of loadings) {
115        loading.style.display = 'none';
116    }
117
118    for (const wrapper of wrappers) {
119        wrapper.style.visibility = null;
120    }
121}

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.