|
1 | 1 | (function () { |
2 | | - "use strict"; |
3 | | - |
4 | | - // --------------------------------------------------------------------------- |
5 | | - // Safety |
6 | | - // --------------------------------------------------------------------------- |
7 | | - |
8 | | - function esc(value) { |
9 | | - return String(value) |
10 | | - .replace(/&/g, "&") |
11 | | - .replace(/</g, "<") |
12 | | - .replace(/>/g, ">") |
13 | | - .replace(/"/g, """) |
14 | | - .replace(/'/g, "'"); |
15 | | - } |
16 | | - |
17 | | - // --------------------------------------------------------------------------- |
18 | | - // Styles |
19 | | - // --------------------------------------------------------------------------- |
20 | | - |
21 | | - const STYLES = ` |
| 2 | + "use strict"; |
| 3 | + |
| 4 | + // --------------------------------------------------------------------------- |
| 5 | + // Escaping function for HTML content |
| 6 | + // --------------------------------------------------------------------------- |
| 7 | + |
| 8 | + function esc(value) { |
| 9 | + return String(value) |
| 10 | + .replace(/&/g, "&") |
| 11 | + .replace(/</g, "<") |
| 12 | + .replace(/>/g, ">") |
| 13 | + .replace(/"/g, """) |
| 14 | + .replace(/'/g, "'"); |
| 15 | + } |
| 16 | + |
| 17 | + // --------------------------------------------------------------------------- |
| 18 | + // Styles |
| 19 | + // --------------------------------------------------------------------------- |
| 20 | + |
| 21 | + const STYLES = ` |
| 22 | + #slippers_errors_ui_root { |
| 23 | + position: relative; |
| 24 | + z-index: 99999; |
| 25 | + } |
22 | 26 | #slippers-overlay { |
23 | 27 | position: fixed; inset: 0; |
24 | 28 | background: rgba(0,0,0,0.92); |
|
47 | 51 | .slippers-type { color: #2dd4bf; font-family: monospace; } |
48 | 52 | `; |
49 | 53 |
|
50 | | - // --------------------------------------------------------------------------- |
51 | | - // HTML component functions (pure: data in, HTML string out) |
52 | | - // --------------------------------------------------------------------------- |
53 | | - |
54 | | - function renderPropError(propError, tagName) { |
55 | | - const name = `<span class="slippers-var">${esc(propError.name)}</span>`; |
56 | | - const tag = `<span class="slippers-tag">${esc(tagName)}</span>`; |
57 | | - const exp = `<span class="slippers-type">${esc(propError.expected)}</span>`; |
58 | | - const act = `<span class="slippers-type">${esc(propError.actual)}</span>`; |
59 | | - |
60 | | - if (propError.error === "invalid") |
61 | | - return `Invalid prop ${name} set on ${tag}. Expected ${exp}, got ${act}.`; |
62 | | - if (propError.error === "missing") |
63 | | - return `Required prop ${name} of type ${exp} not set on ${tag}.`; |
64 | | - if (propError.error === "extra") |
65 | | - return `Extra prop ${name} of type ${act} set on ${tag}.`; |
66 | | - return esc(propError.error); |
67 | | - } |
68 | | - |
69 | | - function renderErrorBox(slippersError) { |
70 | | - const items = slippersError.errors |
71 | | - .map((e) => `<li>${renderPropError(e, slippersError.tag_name)}</li>`) |
72 | | - .join(""); |
73 | | - return ` |
| 54 | + // --------------------------------------------------------------------------- |
| 55 | + // Components |
| 56 | + // --------------------------------------------------------------------------- |
| 57 | + |
| 58 | + function formatPropErrorMessage(propError, tagName) { |
| 59 | + if (propError.error === "invalid") |
| 60 | + return `Invalid prop ${propError.name} set on ${tagName}. Expected ${propError.expected}, got ${propError.actual}.`; |
| 61 | + if (propError.error === "missing") |
| 62 | + return `Required prop ${propError.name} of type ${propError.expected} not set on ${tagName}.`; |
| 63 | + if (propError.error === "extra") |
| 64 | + return `Extra prop ${propError.name} of type ${propError.actual} set on ${tagName}.`; |
| 65 | + return propError.error; |
| 66 | + } |
| 67 | + |
| 68 | + function renderPropError(propError, tagName) { |
| 69 | + const name = `<span class="slippers-var">${esc(propError.name)}</span>`; |
| 70 | + const tag = `<span class="slippers-tag">${esc(tagName)}</span>`; |
| 71 | + const exp = `<span class="slippers-type">${esc(propError.expected)}</span>`; |
| 72 | + const act = `<span class="slippers-type">${esc(propError.actual)}</span>`; |
| 73 | + |
| 74 | + if (propError.error === "invalid") |
| 75 | + return `Invalid prop ${name} set on ${tag}. Expected ${exp}, got ${act}.`; |
| 76 | + if (propError.error === "missing") |
| 77 | + return `Required prop ${name} of type ${exp} not set on ${tag}.`; |
| 78 | + if (propError.error === "extra") |
| 79 | + return `Extra prop ${name} of type ${act} set on ${tag}.`; |
| 80 | + return esc(propError.error); |
| 81 | + } |
| 82 | + |
| 83 | + function renderErrorBox(slippersError) { |
| 84 | + const items = slippersError.errors |
| 85 | + .map( |
| 86 | + (e) => `<li>${renderPropError(e, slippersError.tag_name)}</li>`, |
| 87 | + ) |
| 88 | + .join(""); |
| 89 | + |
| 90 | + return ` |
74 | 91 | <div class="slippers-error-box"> |
75 | 92 | <p class="slippers-tag-label">${esc(slippersError.tag_name)}</p> |
76 | 93 | <p class="slippers-location">${esc(slippersError.template_name)}:${esc(slippersError.lineno)}</p> |
77 | 94 | <ul class="slippers-error-list">${items}</ul> |
78 | 95 | </div>`; |
79 | | - } |
| 96 | + } |
80 | 97 |
|
81 | | - function renderOverlay(errors) { |
82 | | - const boxes = errors.map(renderErrorBox).join(""); |
83 | | - return ` |
| 98 | + function renderOverlay(errors) { |
| 99 | + const boxes = errors.map(renderErrorBox).join(""); |
| 100 | + return ` |
84 | 101 | <style>${STYLES}</style> |
85 | 102 | <div id="slippers-overlay"> |
86 | 103 | <div class="slippers-header"> |
|
89 | 106 | </div> |
90 | 107 | ${boxes} |
91 | 108 | </div>`; |
92 | | - } |
93 | | - |
94 | | - // --------------------------------------------------------------------------- |
95 | | - // Console reporting |
96 | | - // --------------------------------------------------------------------------- |
97 | | - |
98 | | - function reportErrorsToConsole(errors) { |
99 | | - console.group("Slippers: Failed prop types"); |
100 | | - errors.forEach(function (slippersError) { |
101 | | - console.groupCollapsed( |
102 | | - slippersError.tag_name + " in " + slippersError.template_name + ":" + slippersError.lineno |
103 | | - ); |
104 | | - slippersError.errors.forEach(function (propError) { |
105 | | - if (propError.error === "invalid") |
106 | | - console.error( |
107 | | - "Invalid prop " + propError.name + " set on " + slippersError.tag_name + |
108 | | - ". Expected " + propError.expected + ", got " + propError.actual + "." |
109 | | - ); |
110 | | - else if (propError.error === "missing") |
111 | | - console.error( |
112 | | - "Required prop " + propError.name + " of type " + propError.expected + |
113 | | - " not set on " + slippersError.tag_name + "." |
114 | | - ); |
115 | | - else if (propError.error === "extra") |
116 | | - console.error( |
117 | | - "Extra prop " + propError.name + " of type " + propError.actual + |
118 | | - " set on " + slippersError.tag_name + "." |
119 | | - ); |
120 | | - }); |
121 | | - console.groupEnd(); |
122 | | - }); |
123 | | - console.groupEnd(); |
124 | | - } |
| 109 | + } |
125 | 110 |
|
126 | | - // --------------------------------------------------------------------------- |
127 | | - // Entry point |
128 | | - // --------------------------------------------------------------------------- |
| 111 | + // --------------------------------------------------------------------------- |
| 112 | + // Console reporting |
| 113 | + // --------------------------------------------------------------------------- |
| 114 | + |
| 115 | + function reportErrorsToConsole(errors) { |
| 116 | + console.group("Slippers: Failed prop types"); |
| 117 | + errors.forEach(function (slippersError) { |
| 118 | + console.groupCollapsed( |
| 119 | + slippersError.tag_name + |
| 120 | + " in " + |
| 121 | + slippersError.template_name + |
| 122 | + ":" + |
| 123 | + slippersError.lineno, |
| 124 | + ); |
| 125 | + slippersError.errors.forEach(function (propError) { |
| 126 | + console.error(formatPropErrorMessage(propError, slippersError.tag_name)); |
| 127 | + }); |
| 128 | + console.groupEnd(); |
| 129 | + }); |
| 130 | + console.groupEnd(); |
| 131 | + } |
129 | 132 |
|
130 | | - document.addEventListener("DOMContentLoaded", function () { |
131 | | - var errors = window.slippersPropErrors || []; |
132 | | - var configEl = document.getElementById("slippers_type_checking_output"); |
133 | | - var config = JSON.parse((configEl && configEl.textContent) || "[]"); |
| 133 | + // --------------------------------------------------------------------------- |
| 134 | + // Entry point |
| 135 | + // --------------------------------------------------------------------------- |
134 | 136 |
|
135 | | - if (errors.length === 0) return; |
| 137 | + document.addEventListener("DOMContentLoaded", function () { |
| 138 | + var errors = window.slippersPropErrors || []; |
| 139 | + var configEl = document.getElementById("slippers_type_checking_output"); |
| 140 | + var config = JSON.parse((configEl && configEl.textContent) || "[]"); |
136 | 141 |
|
137 | | - if (config.includes("console")) reportErrorsToConsole(errors); |
| 142 | + if (errors.length === 0) return; |
138 | 143 |
|
139 | | - if (config.includes("overlay")) { |
140 | | - var root = document.getElementById("slippers_errors_ui_root"); |
141 | | - if (!root) return; |
| 144 | + if (config.includes("console")) reportErrorsToConsole(errors); |
142 | 145 |
|
143 | | - root.innerHTML = renderOverlay(errors); |
| 146 | + if (config.includes("overlay")) { |
| 147 | + var root = document.getElementById("slippers_errors_ui_root"); |
| 148 | + if (!root) return; |
144 | 149 |
|
145 | | - document.getElementById("slippers-close-btn").addEventListener("click", function () { |
146 | | - root.innerHTML = ""; |
147 | | - }); |
| 150 | + root.innerHTML = renderOverlay(errors); |
148 | 151 |
|
149 | | - document.addEventListener("keydown", function onKey(ev) { |
150 | | - if (ev.key === "Escape") { |
151 | | - root.innerHTML = ""; |
152 | | - document.removeEventListener("keydown", onKey); |
153 | | - } |
154 | | - }); |
155 | | - } |
156 | | - }); |
| 152 | + function closeOverlay() { |
| 153 | + root.innerHTML = ""; |
| 154 | + document.removeEventListener("keydown", onKey); |
| 155 | + } |
| 156 | + |
| 157 | + function onKey(ev) { |
| 158 | + if (ev.key === "Escape") closeOverlay(); |
| 159 | + } |
157 | 160 |
|
| 161 | + document.getElementById("slippers-close-btn").addEventListener("click", closeOverlay); |
| 162 | + document.addEventListener("keydown", onKey); |
| 163 | + } |
| 164 | + }); |
158 | 165 | })(); |
0 commit comments