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

aplus-framework / mvc / 8575619311

05 Apr 2024 08:53PM UTC coverage: 84.857% (-15.1%) from 100.0%
8575619311

push

github

natanfelles
Debug: Use CacheCollection

4 of 4 new or added lines in 1 file covered. (100.0%)

270 existing lines in 1 file now uncovered.

1513 of 1783 relevant lines covered (84.86%)

10.16 hits per line

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

0.0
/src/Debug/Views/toggle-views-hints.php
1
<?php
2
/**
3
 * This file contains snippets originally created in CodeIgniter 4 and is
4
 * MIT licensed.
5
 *
6
 * A big thank you to all the contributors, without them this wouldn't be
7
 * possible.
8
 *
9
 * @see https://github.com/codeigniter4/CodeIgniter4/issues/758
10
 */
UNCOV
11
?><button id="debugbar-toggle-views">Toggle Views Hints</button>
×
UNCOV
12
<style>
×
UNCOV
13
    .debugbar-view.show-view {
×
UNCOV
14
        border: 1px solid;
×
UNCOV
15
        margin: 2px;
×
UNCOV
16
    }
×
17

UNCOV
18
    .debugbar-view-path {
×
UNCOV
19
        background: #000;
×
UNCOV
20
        border-bottom: 1px solid #222;
×
UNCOV
21
        color: #fff;
×
UNCOV
22
        font-family: monospace;
×
UNCOV
23
        font-size: 12px;
×
UNCOV
24
        letter-spacing: normal;
×
UNCOV
25
        min-height: 16px;
×
UNCOV
26
        padding: 2px;
×
UNCOV
27
        text-align: left;
×
UNCOV
28
    }
×
29

UNCOV
30
    .show-view .debugbar-view-path {
×
UNCOV
31
        display: block !important;
×
UNCOV
32
    }
×
33

UNCOV
34
    .debugbar-view.show-view {
×
UNCOV
35
        border-color: #222;
×
UNCOV
36
    }
×
UNCOV
37
</style>
×
UNCOV
38
<script>
×
UNCOV
39
    function toggleViewsHints() {
×
UNCOV
40
        let nodeList = []; // [ Element, NewElement( 1 )/OldElement( 0 ) ]
×
UNCOV
41
        let sortedComments = [];
×
UNCOV
42
        let comments = [];
×
UNCOV
43
        let getComments = function () {
×
UNCOV
44
            let nodes = [];
×
UNCOV
45
            let result = [];
×
UNCOV
46
            let xpathResults = document.evaluate(
×
UNCOV
47
                "//comment()[starts-with(., ' DEBUG-VIEW')]",
×
UNCOV
48
                document,
×
UNCOV
49
                null,
×
UNCOV
50
                XPathResult.ANY_TYPE,
×
UNCOV
51
                null,
×
UNCOV
52
            );
×
UNCOV
53
            let nextNode = xpathResults.iterateNext();
×
UNCOV
54
            while (nextNode) {
×
UNCOV
55
                nodes.push(nextNode);
×
UNCOV
56
                nextNode = xpathResults.iterateNext();
×
UNCOV
57
            }
×
UNCOV
58
            // sort comment by opening and closing tags
×
UNCOV
59
            for (let i = 0; i < nodes.length; ++i) {
×
UNCOV
60
                // get file path + name to use as key
×
UNCOV
61
                let path = nodes[i].nodeValue.substring(
×
UNCOV
62
                    18,
×
UNCOV
63
                    nodes[i].nodeValue.length - 1,
×
UNCOV
64
                );
×
UNCOV
65
                if (nodes[i].nodeValue[12] === 'S') {
×
UNCOV
66
                    // simple check for start comment
×
UNCOV
67
                    // create new entry
×
UNCOV
68
                    result[path] = [nodes[i], null];
×
UNCOV
69
                } else if (result[path]) {
×
UNCOV
70
                    // add to existing entry
×
UNCOV
71
                    result[path][1] = nodes[i];
×
UNCOV
72
                }
×
UNCOV
73
            }
×
UNCOV
74
            return result;
×
UNCOV
75
        };
×
UNCOV
76
        // find node that has TargetNode as parentNode
×
UNCOV
77
        let getParentNode = function (node, targetNode) {
×
UNCOV
78
            if (node.parentNode === null) {
×
UNCOV
79
                return null;
×
UNCOV
80
            }
×
UNCOV
81
            if (node.parentNode !== targetNode) {
×
UNCOV
82
                return getParentNode(node.parentNode, targetNode);
×
UNCOV
83
            }
×
UNCOV
84
            return node;
×
UNCOV
85
        };
×
UNCOV
86
        // define invalid & outer ( also invalid ) elements
×
UNCOV
87
        const INVALID_ELEMENTS = ['NOSCRIPT', 'SCRIPT', 'STYLE'];
×
UNCOV
88
        const OUTER_ELEMENTS = ['HTML', 'BODY', 'HEAD'];
×
UNCOV
89
        let getValidElementInner = function (node, reverse) {
×
UNCOV
90
            // handle invalid tags
×
UNCOV
91
            if (OUTER_ELEMENTS.indexOf(node.nodeName) !== -1) {
×
UNCOV
92
                for (let i = 0; i < document.body.children.length; ++i) {
×
UNCOV
93
                    let index = reverse
×
UNCOV
94
                        ? document.body.children.length - (i + 1)
×
UNCOV
95
                        : i;
×
UNCOV
96
                    let element = document.body.children[index];
×
UNCOV
97
                    // skip invalid tags
×
UNCOV
98
                    if (INVALID_ELEMENTS.indexOf(element.nodeName) !== -1) {
×
UNCOV
99
                        continue;
×
UNCOV
100
                    }
×
UNCOV
101
                    return [element, reverse];
×
UNCOV
102
                }
×
UNCOV
103
                return null;
×
UNCOV
104
            }
×
UNCOV
105
            // get to next valid element
×
UNCOV
106
            while (
×
UNCOV
107
                node !== null &&
×
UNCOV
108
                INVALID_ELEMENTS.indexOf(node.nodeName) !== -1
×
UNCOV
109
                ) {
×
UNCOV
110
                node = reverse
×
UNCOV
111
                    ? node.previousElementSibling
×
UNCOV
112
                    : node.nextElementSibling;
×
UNCOV
113
            }
×
UNCOV
114
            // return non array if we couldnt find something
×
UNCOV
115
            if (node === null) {
×
UNCOV
116
                return null;
×
UNCOV
117
            }
×
UNCOV
118
            return [node, reverse];
×
UNCOV
119
        };
×
UNCOV
120
        // get next valid element ( to be safe to add divs )
×
UNCOV
121
        // @return [ element, skip element ] or null if we couldnt find a valid place
×
UNCOV
122
        let getValidElement = function (nodeElement) {
×
UNCOV
123
            if (nodeElement) {
×
UNCOV
124
                if (nodeElement.nextElementSibling !== null) {
×
UNCOV
125
                    return (
×
UNCOV
126
                        getValidElementInner(
×
UNCOV
127
                            nodeElement.nextElementSibling,
×
UNCOV
128
                            false,
×
UNCOV
129
                        ) ||
×
UNCOV
130
                        getValidElementInner(
×
UNCOV
131
                            nodeElement.previousElementSibling,
×
UNCOV
132
                            true,
×
UNCOV
133
                        )
×
UNCOV
134
                    );
×
UNCOV
135
                }
×
UNCOV
136
                if (nodeElement.previousElementSibling !== null) {
×
UNCOV
137
                    return getValidElementInner(
×
UNCOV
138
                        nodeElement.previousElementSibling,
×
UNCOV
139
                        true,
×
UNCOV
140
                    );
×
UNCOV
141
                }
×
UNCOV
142
            }
×
UNCOV
143
            // something went wrong! -> element is not in DOM
×
UNCOV
144
            return null;
×
UNCOV
145
        };
×
146

UNCOV
147
        function showHints() {
×
UNCOV
148
            // Had AJAX? Reset view blocks
×
UNCOV
149
            sortedComments = getComments();
×
UNCOV
150
            for (let key in sortedComments) {
×
UNCOV
151
                let startElement = getValidElement(sortedComments[key][0]);
×
UNCOV
152
                let endElement = getValidElement(sortedComments[key][1]);
×
UNCOV
153
                // skip if we couldnt get a valid element
×
UNCOV
154
                if (startElement === null || endElement === null) {
×
UNCOV
155
                    continue;
×
UNCOV
156
                }
×
UNCOV
157
                // find element which has same parent as startelement
×
UNCOV
158
                let jointParent = getParentNode(
×
UNCOV
159
                    endElement[0],
×
UNCOV
160
                    startElement[0].parentNode,
×
UNCOV
161
                );
×
UNCOV
162
                if (jointParent === null) {
×
UNCOV
163
                    // find element which has same parent as endelement
×
UNCOV
164
                    jointParent = getParentNode(
×
UNCOV
165
                        startElement[0],
×
UNCOV
166
                        endElement[0].parentNode,
×
UNCOV
167
                    );
×
UNCOV
168
                    if (jointParent === null) {
×
UNCOV
169
                        // both tries failed
×
UNCOV
170
                        continue;
×
UNCOV
171
                    } else {
×
UNCOV
172
                        startElement[0] = jointParent;
×
UNCOV
173
                    }
×
UNCOV
174
                } else {
×
UNCOV
175
                    endElement[0] = jointParent;
×
UNCOV
176
                }
×
UNCOV
177
                let debugDiv = document.createElement('div'); // holder
×
UNCOV
178
                let debugPath = document.createElement('div'); // path
×
UNCOV
179
                let childArray = startElement[0].parentNode.childNodes; // target child array
×
UNCOV
180
                let parent = startElement[0].parentNode;
×
UNCOV
181
                let start, end;
×
UNCOV
182
                // setup container
×
UNCOV
183
                debugDiv.classList.add('debugbar-view');
×
UNCOV
184
                debugDiv.classList.add('show-view');
×
UNCOV
185
                debugPath.classList.add('debugbar-view-path');
×
UNCOV
186
                debugPath.innerText = key;
×
UNCOV
187
                debugDiv.appendChild(debugPath);
×
UNCOV
188
                // calc distance between them
×
UNCOV
189
                // start
×
UNCOV
190
                for (let i = 0; i < childArray.length; ++i) {
×
UNCOV
191
                    // check for comment ( start & end ) -> if its before valid start element
×
UNCOV
192
                    if (
×
UNCOV
193
                        childArray[i] === sortedComments[key][1] ||
×
UNCOV
194
                        childArray[i] === sortedComments[key][0] ||
×
UNCOV
195
                        childArray[i] === startElement[0]
×
UNCOV
196
                    ) {
×
UNCOV
197
                        start = i;
×
UNCOV
198
                        if (childArray[i] === sortedComments[key][0]) {
×
UNCOV
199
                            start++; // increase to skip the start comment
×
UNCOV
200
                        }
×
UNCOV
201
                        break;
×
UNCOV
202
                    }
×
UNCOV
203
                }
×
UNCOV
204
                // adjust if we want to skip the start element
×
UNCOV
205
                if (startElement[1]) {
×
UNCOV
206
                    start++;
×
UNCOV
207
                }
×
UNCOV
208
                // end
×
UNCOV
209
                for (let i = start; i < childArray.length; ++i) {
×
UNCOV
210
                    if (childArray[i] === endElement[0]) {
×
UNCOV
211
                        end = i;
×
UNCOV
212
                        // dont break to check for end comment after end valid element
×
UNCOV
213
                    } else if (childArray[i] === sortedComments[key][1]) {
×
UNCOV
214
                        // if we found the end comment, we can break
×
UNCOV
215
                        end = i;
×
UNCOV
216
                        break;
×
UNCOV
217
                    }
×
UNCOV
218
                }
×
UNCOV
219
                // move elements
×
UNCOV
220
                let number = end - start;
×
UNCOV
221
                if (endElement[1]) {
×
UNCOV
222
                    number++;
×
UNCOV
223
                }
×
UNCOV
224
                for (let i = 0; i < number; ++i) {
×
UNCOV
225
                    if (INVALID_ELEMENTS.indexOf(childArray[start]) !== -1) {
×
UNCOV
226
                        // skip invalid childs that can cause problems if moved
×
UNCOV
227
                        start++;
×
UNCOV
228
                        continue;
×
UNCOV
229
                    }
×
UNCOV
230
                    debugDiv.appendChild(childArray[start]);
×
UNCOV
231
                }
×
UNCOV
232
                // add container to DOM
×
UNCOV
233
                nodeList.push(parent.insertBefore(debugDiv, childArray[start]));
×
UNCOV
234
            }
×
UNCOV
235
            localStorage.setItem('debugbar-view', 'show');
×
UNCOV
236
            btn.classList.add('active');
×
UNCOV
237
        }
×
238

UNCOV
239
        function hideHints() {
×
UNCOV
240
            for (let i = 0; i < nodeList.length; ++i) {
×
UNCOV
241
                let index;
×
UNCOV
242
                // find index
×
UNCOV
243
                for (
×
UNCOV
244
                    let j = 0;
×
UNCOV
245
                    j < nodeList[i].parentNode.childNodes.length;
×
UNCOV
246
                    ++j
×
UNCOV
247
                ) {
×
UNCOV
248
                    if (nodeList[i].parentNode.childNodes[j] === nodeList[i]) {
×
UNCOV
249
                        index = j;
×
UNCOV
250
                        break;
×
UNCOV
251
                    }
×
UNCOV
252
                }
×
UNCOV
253
                // move child back
×
UNCOV
254
                while (nodeList[i].childNodes.length !== 1) {
×
UNCOV
255
                    nodeList[i].parentNode.insertBefore(
×
UNCOV
256
                        nodeList[i].childNodes[1],
×
UNCOV
257
                        nodeList[i].parentNode.childNodes[index].nextSibling,
×
UNCOV
258
                    );
×
UNCOV
259
                    index++;
×
UNCOV
260
                }
×
UNCOV
261
                nodeList[i].parentNode.removeChild(nodeList[i]);
×
UNCOV
262
            }
×
UNCOV
263
            nodeList.length = 0;
×
UNCOV
264
            localStorage.removeItem('debugbar-view')
×
UNCOV
265
            btn.classList.remove('active');
×
UNCOV
266
        }
×
267

UNCOV
268
        let btn = document.querySelector('#debugbar-toggle-views');
×
UNCOV
269
        // If the Views Collector is inactive stops here
×
UNCOV
270
        if (!btn) {
×
UNCOV
271
            return;
×
UNCOV
272
        }
×
UNCOV
273
        btn.onclick = function () {
×
UNCOV
274
            if (localStorage.getItem('debugbar-view')) {
×
UNCOV
275
                hideHints();
×
UNCOV
276
                return;
×
UNCOV
277
            }
×
UNCOV
278
            showHints();
×
UNCOV
279
        };
×
UNCOV
280
        // Determine Hints state on page load
×
UNCOV
281
        if (localStorage.getItem('debugbar-view')) {
×
UNCOV
282
            showHints();
×
UNCOV
283
        }
×
UNCOV
284
    }
×
285

UNCOV
286
    toggleViewsHints();
×
UNCOV
287
</script>
×
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

© 2026 Coveralls, Inc