rails-profiler 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/builds/profiler-toolbar.js +76 -72
- data/app/assets/builds/profiler.css +66 -6
- data/lib/profiler/middleware/toolbar_injector.rb +169 -62
- data/lib/profiler/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 80a34504e3cb67a077d5f46265cbc265cbf7704f89ad06f90e5ab5df22651a70
|
|
4
|
+
data.tar.gz: d23a6d0d9f107611d66dfe34987447efde5f74f2562efd146d43d910fe431c6a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 668d228ede43471fc71a5d65d6498bfd00606865f7cad69dd23e03f79a4e84a2ba5f34dbc2d9e07809df4319946055464b7b8e615ee29e14c8cfafdef10ffc4a
|
|
7
|
+
data.tar.gz: 16926d1a141c64cc72110698cd21e4d5c26d6e9022cd17ad6ba5ba3112aa98ce1917db9d005c112fac62190790433c06b24f1d9a85648edabf679664eb89b30d
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
function P(n2, l3, u4, t3, i3, r3, o3, e3, f4, c3, s3) {
|
|
71
|
-
var a3, h3, y3, d3, w3, g2,
|
|
72
|
-
for (f4 = A(u4, l3, m3, f4, b), a3 = 0; a3 < b; a3++) null != (y3 = u4.__k[a3]) && (h3 = -1 != y3.__i && m3[y3.__i] || p, y3.__i = a3, g2 = z(n2, y3, h3, i3, r3, o3, e3, f4, c3, s3), d3 = y3.__e, y3.ref && h3.ref != y3.ref && (h3.ref && D(h3.ref, null, y3), s3.push(y3.ref, y3.__c || d3, y3)), null == w3 && null != d3 && (w3 = d3), (
|
|
71
|
+
var a3, h3, y3, d3, w3, g2, _3, m3 = t3 && t3.__k || v, b = l3.length;
|
|
72
|
+
for (f4 = A(u4, l3, m3, f4, b), a3 = 0; a3 < b; a3++) null != (y3 = u4.__k[a3]) && (h3 = -1 != y3.__i && m3[y3.__i] || p, y3.__i = a3, g2 = z(n2, y3, h3, i3, r3, o3, e3, f4, c3, s3), d3 = y3.__e, y3.ref && h3.ref != y3.ref && (h3.ref && D(h3.ref, null, y3), s3.push(y3.ref, y3.__c || d3, y3)), null == w3 && null != d3 && (w3 = d3), (_3 = !!(4 & y3.__u)) || h3.__k === y3.__k ? f4 = H(y3, f4, n2, _3) : "function" == typeof y3.type && void 0 !== g2 ? f4 = g2 : d3 && (f4 = d3.nextSibling), y3.__u &= -7);
|
|
73
73
|
return u4.__e = w3, f4;
|
|
74
74
|
}
|
|
75
75
|
function A(n2, l3, u4, t3, i3) {
|
|
@@ -130,11 +130,11 @@
|
|
|
130
130
|
};
|
|
131
131
|
}
|
|
132
132
|
function z(n2, u4, t3, i3, r3, o3, e3, f4, c3, s3) {
|
|
133
|
-
var a3, h3, p3, y3,
|
|
133
|
+
var a3, h3, p3, y3, _3, m3, b, S2, C3, M2, $2, I2, A3, H2, L, T3 = u4.type;
|
|
134
134
|
if (void 0 !== u4.constructor) return null;
|
|
135
135
|
128 & t3.__u && (c3 = !!(32 & t3.__u), o3 = [f4 = u4.__e = t3.__e]), (a3 = l.__b) && a3(u4);
|
|
136
136
|
n: if ("function" == typeof T3) try {
|
|
137
|
-
if (S2 = u4.props, C3 = T3.prototype && T3.prototype.render, M2 = (a3 = T3.contextType) && i3[a3.__c], $2 = a3 ? M2 ? M2.props.value : a3.__ : i3, t3.__c ? b = (h3 = u4.__c = t3.__c).__ = h3.__E : (C3 ? u4.__c = h3 = new T3(S2, $2) : (u4.__c = h3 = new x(S2, $2), h3.constructor = T3, h3.render = G), M2 && M2.sub(h3), h3.state || (h3.state = {}), h3.__n = i3, p3 = h3.__d = true, h3.__h = [], h3._sb = []), C3 && null == h3.__s && (h3.__s = h3.state), C3 && null != T3.getDerivedStateFromProps && (h3.__s == h3.state && (h3.__s = w({}, h3.__s)), w(h3.__s, T3.getDerivedStateFromProps(S2, h3.__s))), y3 = h3.props,
|
|
137
|
+
if (S2 = u4.props, C3 = T3.prototype && T3.prototype.render, M2 = (a3 = T3.contextType) && i3[a3.__c], $2 = a3 ? M2 ? M2.props.value : a3.__ : i3, t3.__c ? b = (h3 = u4.__c = t3.__c).__ = h3.__E : (C3 ? u4.__c = h3 = new T3(S2, $2) : (u4.__c = h3 = new x(S2, $2), h3.constructor = T3, h3.render = G), M2 && M2.sub(h3), h3.state || (h3.state = {}), h3.__n = i3, p3 = h3.__d = true, h3.__h = [], h3._sb = []), C3 && null == h3.__s && (h3.__s = h3.state), C3 && null != T3.getDerivedStateFromProps && (h3.__s == h3.state && (h3.__s = w({}, h3.__s)), w(h3.__s, T3.getDerivedStateFromProps(S2, h3.__s))), y3 = h3.props, _3 = h3.state, h3.__v = u4, p3) C3 && null == T3.getDerivedStateFromProps && null != h3.componentWillMount && h3.componentWillMount(), C3 && null != h3.componentDidMount && h3.__h.push(h3.componentDidMount);
|
|
138
138
|
else {
|
|
139
139
|
if (C3 && null == T3.getDerivedStateFromProps && S2 !== y3 && null != h3.componentWillReceiveProps && h3.componentWillReceiveProps(S2, $2), u4.__v == t3.__v || !h3.__e && null != h3.shouldComponentUpdate && false === h3.shouldComponentUpdate(S2, h3.__s, $2)) {
|
|
140
140
|
u4.__v != t3.__v && (h3.props = S2, h3.state = h3.__s, h3.__d = false), u4.__e = t3.__e, u4.__k = t3.__k, u4.__k.some(function(n3) {
|
|
@@ -143,14 +143,14 @@
|
|
|
143
143
|
break n;
|
|
144
144
|
}
|
|
145
145
|
null != h3.componentWillUpdate && h3.componentWillUpdate(S2, h3.__s, $2), C3 && null != h3.componentDidUpdate && h3.__h.push(function() {
|
|
146
|
-
h3.componentDidUpdate(y3,
|
|
146
|
+
h3.componentDidUpdate(y3, _3, m3);
|
|
147
147
|
});
|
|
148
148
|
}
|
|
149
149
|
if (h3.context = $2, h3.props = S2, h3.__P = n2, h3.__e = false, I2 = l.__r, A3 = 0, C3) h3.state = h3.__s, h3.__d = false, I2 && I2(u4), a3 = h3.render(h3.props, h3.state, h3.context), v.push.apply(h3.__h, h3._sb), h3._sb = [];
|
|
150
150
|
else do {
|
|
151
151
|
h3.__d = false, I2 && I2(u4), a3 = h3.render(h3.props, h3.state, h3.context), h3.state = h3.__s;
|
|
152
152
|
} while (h3.__d && ++A3 < 25);
|
|
153
|
-
h3.state = h3.__s, null != h3.getChildContext && (i3 = w(w({}, i3), h3.getChildContext())), C3 && !p3 && null != h3.getSnapshotBeforeUpdate && (m3 = h3.getSnapshotBeforeUpdate(y3,
|
|
153
|
+
h3.state = h3.__s, null != h3.getChildContext && (i3 = w(w({}, i3), h3.getChildContext())), C3 && !p3 && null != h3.getSnapshotBeforeUpdate && (m3 = h3.getSnapshotBeforeUpdate(y3, _3)), H2 = null != a3 && a3.type === k && null == a3.key ? q(a3.props.children) : a3, f4 = P(n2, d(H2) ? H2 : [H2], u4, t3, i3, r3, o3, e3, f4, c3, s3), h3.base = u4.__e, u4.__u &= -161, h3.__h.length && e3.push(h3), b && (h3.__E = h3.__ = null);
|
|
154
154
|
} catch (n3) {
|
|
155
155
|
if (u4.__v = null, c3 || null != o3) if (n3.then) {
|
|
156
156
|
for (u4.__u |= c3 ? 160 : 128; f4 && 8 == f4.nodeType && f4.nextSibling; ) f4 = f4.nextSibling;
|
|
@@ -184,7 +184,7 @@
|
|
|
184
184
|
return "object" != typeof n2 || null == n2 || n2.__b > 0 ? n2 : d(n2) ? n2.map(q) : w({}, n2);
|
|
185
185
|
}
|
|
186
186
|
function B(u4, t3, i3, r3, o3, e3, f4, c3, s3) {
|
|
187
|
-
var a3, h3, v3, y3, w3,
|
|
187
|
+
var a3, h3, v3, y3, w3, _3, m3, b = i3.props || p, k3 = t3.props, x2 = t3.type;
|
|
188
188
|
if ("svg" == x2 ? o3 = "http://www.w3.org/2000/svg" : "math" == x2 ? o3 = "http://www.w3.org/1998/Math/MathML" : o3 || (o3 = "http://www.w3.org/1999/xhtml"), null != e3) {
|
|
189
189
|
for (a3 = 0; a3 < e3.length; a3++) if ((w3 = e3[a3]) && "setAttribute" in w3 == !!x2 && (x2 ? w3.localName == x2 : 3 == w3.nodeType)) {
|
|
190
190
|
u4 = w3, e3[a3] = null;
|
|
@@ -199,10 +199,10 @@
|
|
|
199
199
|
else {
|
|
200
200
|
if (e3 = e3 && n.call(u4.childNodes), !c3 && null != e3) for (b = {}, a3 = 0; a3 < u4.attributes.length; a3++) b[(w3 = u4.attributes[a3]).name] = w3.value;
|
|
201
201
|
for (a3 in b) w3 = b[a3], "dangerouslySetInnerHTML" == a3 ? v3 = w3 : "children" == a3 || a3 in k3 || "value" == a3 && "defaultValue" in k3 || "checked" == a3 && "defaultChecked" in k3 || F(u4, a3, null, w3, o3);
|
|
202
|
-
for (a3 in k3) w3 = k3[a3], "children" == a3 ? y3 = w3 : "dangerouslySetInnerHTML" == a3 ? h3 = w3 : "value" == a3 ?
|
|
202
|
+
for (a3 in k3) w3 = k3[a3], "children" == a3 ? y3 = w3 : "dangerouslySetInnerHTML" == a3 ? h3 = w3 : "value" == a3 ? _3 = w3 : "checked" == a3 ? m3 = w3 : c3 && "function" != typeof w3 || b[a3] === w3 || F(u4, a3, w3, b[a3], o3);
|
|
203
203
|
if (h3) c3 || v3 && (h3.__html == v3.__html || h3.__html == u4.innerHTML) || (u4.innerHTML = h3.__html), t3.__k = [];
|
|
204
204
|
else if (v3 && (u4.innerHTML = ""), P("template" == t3.type ? u4.content : u4, d(y3) ? y3 : [y3], t3, i3, r3, "foreignObject" == x2 ? "http://www.w3.org/1999/xhtml" : o3, e3, f4, e3 ? e3[0] : i3.__k && S(i3, 0), c3, s3), null != e3) for (a3 = e3.length; a3--; ) g(e3[a3]);
|
|
205
|
-
c3 || (a3 = "value", "progress" == x2 && null ==
|
|
205
|
+
c3 || (a3 = "value", "progress" == x2 && null == _3 ? u4.removeAttribute("value") : null != _3 && (_3 !== u4[a3] || "progress" == x2 && !_3 || "option" == x2 && _3 != b[a3]) && F(u4, a3, _3, b[a3], o3), a3 = "checked", null != m3 && m3 != u4[a3] && F(u4, a3, m3, b[a3], o3));
|
|
206
206
|
}
|
|
207
207
|
return u4;
|
|
208
208
|
}
|
|
@@ -314,6 +314,10 @@
|
|
|
314
314
|
var i3 = p2(t2++, 3);
|
|
315
315
|
!c2.__s && C2(i3.__H, u4) && (i3.__ = n2, i3.u = u4, r2.__H.__h.push(i3));
|
|
316
316
|
}
|
|
317
|
+
function _2(n2, u4) {
|
|
318
|
+
var i3 = p2(t2++, 4);
|
|
319
|
+
!c2.__s && C2(i3.__H, u4) && (i3.__ = n2, i3.u = u4, r2.__h.push(i3));
|
|
320
|
+
}
|
|
317
321
|
function A2(n2) {
|
|
318
322
|
return o2 = 5, T2(function() {
|
|
319
323
|
return { current: n2 };
|
|
@@ -427,7 +431,7 @@
|
|
|
427
431
|
}
|
|
428
432
|
hideTimer.current = setTimeout(() => setVisible(false), 150);
|
|
429
433
|
};
|
|
430
|
-
|
|
434
|
+
_2(() => {
|
|
431
435
|
if (visible && panelRef.current) {
|
|
432
436
|
const el = panelRef.current;
|
|
433
437
|
el.style.left = "50%";
|
|
@@ -453,8 +457,7 @@
|
|
|
453
457
|
"div",
|
|
454
458
|
{
|
|
455
459
|
ref: panelRef,
|
|
456
|
-
class: `profiler-toolbar-panel${panelLarge ? " profiler-toolbar-panel-large" : ""}`,
|
|
457
|
-
style: { display: visible ? "block" : "none" },
|
|
460
|
+
class: `profiler-toolbar-panel${panelLarge ? " profiler-toolbar-panel-large" : ""}${visible ? " is-visible" : ""}`,
|
|
458
461
|
onMouseEnter: show,
|
|
459
462
|
onMouseLeave: hide,
|
|
460
463
|
children: panel
|
|
@@ -1027,7 +1030,7 @@
|
|
|
1027
1030
|
second: "2-digit"
|
|
1028
1031
|
});
|
|
1029
1032
|
}
|
|
1030
|
-
function ToolbarApp({ profile, token
|
|
1033
|
+
function ToolbarApp({ profile, token }) {
|
|
1031
1034
|
const cd = profile.collectors_data || {};
|
|
1032
1035
|
const requestData = cd["request"];
|
|
1033
1036
|
const dbData = cd["database"];
|
|
@@ -1048,7 +1051,7 @@
|
|
|
1048
1051
|
const dbClass = (dbData?.slow_queries ?? 0) > 0 ? "profiler-text--error" : "profiler-text--success";
|
|
1049
1052
|
const ajaxClass = (ajaxData?.total_requests ?? 0) > 20 ? "profiler-text--error" : "profiler-text--success";
|
|
1050
1053
|
const cacheClass = (cacheData?.hit_rate ?? 0) > 80 ? "profiler-text--success" : "profiler-text--warning";
|
|
1051
|
-
return /* @__PURE__ */ u3("div", { class: "profiler-toolbar-container", children: [
|
|
1054
|
+
return /* @__PURE__ */ u3(k, { children: /* @__PURE__ */ u3("div", { class: "profiler-toolbar-container", children: [
|
|
1052
1055
|
requestData && /* @__PURE__ */ u3(k, { children: [
|
|
1053
1056
|
/* @__PURE__ */ u3(
|
|
1054
1057
|
ToolbarItem,
|
|
@@ -1291,83 +1294,84 @@
|
|
|
1291
1294
|
]
|
|
1292
1295
|
}
|
|
1293
1296
|
),
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
{
|
|
1297
|
-
href: `/_profiler/profiles/${token}`,
|
|
1298
|
-
class: "profiler-toolbar-item profiler-text--warning",
|
|
1299
|
-
title: `Captur\xE9 avec v${profile.gem_version} \u2014 actuel : v${currentVersion}`,
|
|
1300
|
-
children: [
|
|
1301
|
-
"\u26A0\uFE0F v",
|
|
1302
|
-
profile.gem_version
|
|
1303
|
-
]
|
|
1304
|
-
}
|
|
1305
|
-
) : currentVersion ? /* @__PURE__ */ u3("span", { class: "profiler-toolbar-item", style: "cursor:default", children: [
|
|
1306
|
-
"v",
|
|
1307
|
-
currentVersion
|
|
1308
|
-
] }) : null,
|
|
1309
|
-
/* @__PURE__ */ u3("a", { href: "/_profiler", class: "profiler-toolbar-item", children: "\u2B21 Profiler" })
|
|
1310
|
-
] });
|
|
1297
|
+
/* @__PURE__ */ u3("a", { href: "/_profiler", class: "profiler-toolbar-item profiler-toolbar-logo", children: "\u2B21 Profiler" })
|
|
1298
|
+
] }) });
|
|
1311
1299
|
}
|
|
1312
1300
|
|
|
1313
1301
|
// app/assets/typescript/profiler/toolbar-bundle.tsx
|
|
1314
|
-
|
|
1302
|
+
var ANIM_MS = 280;
|
|
1303
|
+
function applyTheme(elements) {
|
|
1315
1304
|
const stored = localStorage.getItem("profiler-theme");
|
|
1316
1305
|
const theme = stored === "light" ? "light" : stored === "dark" ? "dark" : window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
|
|
1317
|
-
el.setAttribute("data-theme", theme);
|
|
1306
|
+
elements.forEach((el) => el.setAttribute("data-theme", theme));
|
|
1307
|
+
}
|
|
1308
|
+
function ToolbarMount({ token }) {
|
|
1309
|
+
const [profile, setProfile] = d2(null);
|
|
1310
|
+
y2(() => {
|
|
1311
|
+
const load = () => {
|
|
1312
|
+
fetch(`/_profiler/api/toolbar/${token}`).then((res) => res.json()).then((data) => {
|
|
1313
|
+
if (data.profile) setProfile(data.profile);
|
|
1314
|
+
}).catch((err) => console.debug("Profiler toolbar load failed:", err));
|
|
1315
|
+
};
|
|
1316
|
+
window.__PROFILER_REFRESH_TOOLBAR__ = load;
|
|
1317
|
+
load();
|
|
1318
|
+
}, [token]);
|
|
1319
|
+
if (!profile) return null;
|
|
1320
|
+
return /* @__PURE__ */ u3(ToolbarApp, { profile, token });
|
|
1318
1321
|
}
|
|
1319
1322
|
function mountToolbar() {
|
|
1320
1323
|
const el = document.getElementById("profiler-toolbar");
|
|
1321
|
-
|
|
1324
|
+
const toggleEl = document.getElementById("profiler-toolbar-toggle");
|
|
1325
|
+
if (!el || !toggleEl) return;
|
|
1322
1326
|
const token = el.dataset.token;
|
|
1323
1327
|
if (!token) return;
|
|
1324
|
-
const
|
|
1325
|
-
applyTheme(
|
|
1328
|
+
const themeEls = [el, toggleEl];
|
|
1329
|
+
applyTheme(themeEls);
|
|
1326
1330
|
window.addEventListener("storage", (e3) => {
|
|
1327
|
-
if (e3.key === "profiler-theme") applyTheme(
|
|
1331
|
+
if (e3.key === "profiler-theme") applyTheme(themeEls);
|
|
1328
1332
|
});
|
|
1329
1333
|
window.addEventListener("profiler:theme-change", ((e3) => {
|
|
1330
|
-
if (e3.detail?.theme)
|
|
1334
|
+
if (e3.detail?.theme) themeEls.forEach((elem) => elem.setAttribute("data-theme", e3.detail.theme));
|
|
1331
1335
|
}));
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1336
|
+
let isCollapsed = localStorage.getItem("profiler-toolbar-collapsed") === "true";
|
|
1337
|
+
toggleEl.dataset.collapsed = String(isCollapsed);
|
|
1338
|
+
if (isCollapsed && !el.style.transform) {
|
|
1339
|
+
el.style.animation = "none";
|
|
1340
|
+
el.style.transform = "translateX(calc(100% + 44px))";
|
|
1341
|
+
}
|
|
1342
|
+
if (!isCollapsed) {
|
|
1343
|
+
setTimeout(() => {
|
|
1344
|
+
el.style.animation = "none";
|
|
1345
|
+
}, 400);
|
|
1346
|
+
}
|
|
1347
|
+
function toggleCollapse() {
|
|
1348
|
+
const next = !isCollapsed;
|
|
1349
|
+
isCollapsed = next;
|
|
1350
|
+
localStorage.setItem("profiler-toolbar-collapsed", String(next));
|
|
1351
|
+
toggleEl.dataset.collapsed = String(next);
|
|
1352
|
+
if (next) {
|
|
1353
|
+
el.style.transition = `transform ${ANIM_MS}ms cubic-bezier(0.4,0,0.2,1)`;
|
|
1354
|
+
el.style.transform = "translateX(calc(100% + 44px))";
|
|
1355
|
+
} else {
|
|
1356
|
+
el.style.transition = "none";
|
|
1357
|
+
el.style.transform = "translateX(calc(100% + 44px))";
|
|
1358
|
+
void el.offsetWidth;
|
|
1359
|
+
el.style.transition = `transform ${ANIM_MS}ms cubic-bezier(0.4,0,0.2,1)`;
|
|
1360
|
+
el.style.transform = "translateX(0)";
|
|
1361
|
+
setTimeout(() => {
|
|
1362
|
+
el.style.transform = "";
|
|
1363
|
+
el.style.transition = "";
|
|
1364
|
+
}, ANIM_MS + 50);
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
toggleEl.addEventListener("click", toggleCollapse);
|
|
1343
1368
|
document.addEventListener("keydown", (e3) => {
|
|
1344
1369
|
if (e3.altKey && e3.key === "p") {
|
|
1345
1370
|
e3.preventDefault();
|
|
1346
|
-
|
|
1347
|
-
if (hidden2) {
|
|
1348
|
-
el.dataset.hidden = "false";
|
|
1349
|
-
el.style.transform = "translateY(0)";
|
|
1350
|
-
el.style.opacity = "1";
|
|
1351
|
-
localStorage.setItem("profiler-toolbar-hidden", "false");
|
|
1352
|
-
} else {
|
|
1353
|
-
el.dataset.hidden = "true";
|
|
1354
|
-
el.style.transform = "translateY(100%)";
|
|
1355
|
-
el.style.opacity = "0";
|
|
1356
|
-
localStorage.setItem("profiler-toolbar-hidden", "true");
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1359
|
-
if (e3.key === "Escape") {
|
|
1360
|
-
el.dataset.hidden = "true";
|
|
1361
|
-
el.style.transform = "translateY(100%)";
|
|
1362
|
-
el.style.opacity = "0";
|
|
1371
|
+
toggleCollapse();
|
|
1363
1372
|
}
|
|
1364
1373
|
});
|
|
1365
|
-
|
|
1366
|
-
if (hidden) {
|
|
1367
|
-
el.dataset.hidden = "true";
|
|
1368
|
-
el.style.transform = "translateY(100%)";
|
|
1369
|
-
el.style.opacity = "0";
|
|
1370
|
-
}
|
|
1374
|
+
J(/* @__PURE__ */ u3(ToolbarMount, { token }), el);
|
|
1371
1375
|
}
|
|
1372
1376
|
if (document.readyState === "loading") {
|
|
1373
1377
|
document.addEventListener("DOMContentLoaded", mountToolbar);
|
|
@@ -1395,6 +1395,26 @@ tr:hover .btn-row-delete {
|
|
|
1395
1395
|
color: var(--profiler-text-muted);
|
|
1396
1396
|
}
|
|
1397
1397
|
|
|
1398
|
+
@keyframes pfPop {
|
|
1399
|
+
0% {
|
|
1400
|
+
transform: scaleX(1);
|
|
1401
|
+
}
|
|
1402
|
+
15% {
|
|
1403
|
+
transform: scaleX(1.18);
|
|
1404
|
+
}
|
|
1405
|
+
40% {
|
|
1406
|
+
transform: scaleX(0.87);
|
|
1407
|
+
}
|
|
1408
|
+
65% {
|
|
1409
|
+
transform: scaleX(1.08);
|
|
1410
|
+
}
|
|
1411
|
+
85% {
|
|
1412
|
+
transform: scaleX(0.97);
|
|
1413
|
+
}
|
|
1414
|
+
100% {
|
|
1415
|
+
transform: scaleX(1);
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1398
1418
|
#profiler-toolbar {
|
|
1399
1419
|
position: fixed;
|
|
1400
1420
|
bottom: 0;
|
|
@@ -1409,6 +1429,7 @@ tr:hover .btn-row-delete {
|
|
|
1409
1429
|
font-family: var(--profiler-font-mono);
|
|
1410
1430
|
font-size: 11px;
|
|
1411
1431
|
animation: toolbarIn 300ms cubic-bezier(0.4, 0, 0.2, 1) both;
|
|
1432
|
+
transition: left 280ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
1412
1433
|
}
|
|
1413
1434
|
#profiler-toolbar::before {
|
|
1414
1435
|
content: "";
|
|
@@ -1464,12 +1485,10 @@ tr:hover .btn-row-delete {
|
|
|
1464
1485
|
background: var(--profiler-accent);
|
|
1465
1486
|
transform: scaleX(0);
|
|
1466
1487
|
transform-origin: left;
|
|
1467
|
-
transition: transform
|
|
1488
|
+
transition: transform 280ms cubic-bezier(0.34, 1.4, 0.64, 1);
|
|
1468
1489
|
}
|
|
1469
1490
|
.profiler-toolbar-item:last-child {
|
|
1470
1491
|
border-right: none;
|
|
1471
|
-
margin-left: auto;
|
|
1472
|
-
padding-left: 20px;
|
|
1473
1492
|
}
|
|
1474
1493
|
.profiler-toolbar-item:hover {
|
|
1475
1494
|
color: var(--profiler-text);
|
|
@@ -1479,12 +1498,30 @@ tr:hover .btn-row-delete {
|
|
|
1479
1498
|
transform: scaleX(1);
|
|
1480
1499
|
}
|
|
1481
1500
|
|
|
1501
|
+
.profiler-toolbar-collapse-btn {
|
|
1502
|
+
margin-left: auto;
|
|
1503
|
+
padding: 0 14px;
|
|
1504
|
+
border-left: 1px solid var(--profiler-border);
|
|
1505
|
+
font-size: 10px;
|
|
1506
|
+
color: var(--profiler-text-muted);
|
|
1507
|
+
cursor: pointer;
|
|
1508
|
+
}
|
|
1509
|
+
.profiler-toolbar-collapse-btn:hover {
|
|
1510
|
+
color: var(--profiler-text);
|
|
1511
|
+
background: var(--profiler-accent-bg);
|
|
1512
|
+
animation: pfPop 380ms ease-out both;
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1482
1515
|
a.profiler-toolbar-item {
|
|
1483
1516
|
cursor: pointer;
|
|
1484
1517
|
font-family: var(--profiler-font-mono);
|
|
1485
1518
|
font-size: 11px;
|
|
1486
1519
|
}
|
|
1487
1520
|
|
|
1521
|
+
.profiler-toolbar-logo {
|
|
1522
|
+
border-right: 1px solid var(--profiler-border) !important;
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1488
1525
|
.profiler-text--success {
|
|
1489
1526
|
color: var(--profiler-success) !important;
|
|
1490
1527
|
}
|
|
@@ -1505,19 +1542,22 @@ a.profiler-toolbar-item {
|
|
|
1505
1542
|
color: var(--profiler-accent) !important;
|
|
1506
1543
|
}
|
|
1507
1544
|
|
|
1508
|
-
|
|
1545
|
+
.profiler-toolbar-item.profiler-text--error::after {
|
|
1509
1546
|
background: var(--profiler-error);
|
|
1510
1547
|
}
|
|
1511
1548
|
|
|
1512
|
-
|
|
1549
|
+
.profiler-toolbar-item.profiler-text--warning::after {
|
|
1513
1550
|
background: var(--profiler-warning);
|
|
1514
1551
|
}
|
|
1515
1552
|
|
|
1553
|
+
.profiler-toolbar-item.profiler-text--success::after {
|
|
1554
|
+
background: var(--profiler-success);
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1516
1557
|
.profiler-toolbar-hoverable {
|
|
1517
1558
|
position: relative;
|
|
1518
1559
|
}
|
|
1519
1560
|
.profiler-toolbar-hoverable .profiler-toolbar-panel {
|
|
1520
|
-
display: none;
|
|
1521
1561
|
position: absolute;
|
|
1522
1562
|
bottom: calc(100% + 12px);
|
|
1523
1563
|
left: 50%;
|
|
@@ -1530,6 +1570,16 @@ a.profiler-toolbar-item.profiler-text--warning::after {
|
|
|
1530
1570
|
box-shadow: var(--profiler-shadow-xl), 0 0 0 1px var(--profiler-border-accent);
|
|
1531
1571
|
z-index: var(--profiler-z-panel);
|
|
1532
1572
|
overflow: hidden;
|
|
1573
|
+
opacity: 0;
|
|
1574
|
+
visibility: hidden;
|
|
1575
|
+
pointer-events: none;
|
|
1576
|
+
transition: opacity 160ms cubic-bezier(0.4, 0, 0.2, 1), visibility 0s linear 160ms;
|
|
1577
|
+
}
|
|
1578
|
+
.profiler-toolbar-hoverable .profiler-toolbar-panel.is-visible {
|
|
1579
|
+
opacity: 1;
|
|
1580
|
+
visibility: visible;
|
|
1581
|
+
pointer-events: auto;
|
|
1582
|
+
transition: opacity 160ms cubic-bezier(0.4, 0, 0.2, 1), visibility 0s;
|
|
1533
1583
|
}
|
|
1534
1584
|
.profiler-toolbar-hoverable .profiler-toolbar-panel::before {
|
|
1535
1585
|
content: "";
|
|
@@ -1674,6 +1724,16 @@ a.profiler-toolbar-item.profiler-text--warning::after {
|
|
|
1674
1724
|
margin-top: 6px;
|
|
1675
1725
|
}
|
|
1676
1726
|
|
|
1727
|
+
#profiler-toolbar[data-collapsed=true] .profiler-toolbar-item:not(.profiler-toolbar-collapse-btn) {
|
|
1728
|
+
display: none;
|
|
1729
|
+
}
|
|
1730
|
+
#profiler-toolbar[data-collapsed=true] .profiler-toolbar-collapse-btn {
|
|
1731
|
+
margin-left: 0;
|
|
1732
|
+
}
|
|
1733
|
+
#profiler-toolbar[data-collapsed=true]::before {
|
|
1734
|
+
opacity: 0;
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1677
1737
|
.container > table {
|
|
1678
1738
|
width: 100%;
|
|
1679
1739
|
border-collapse: collapse;
|
|
@@ -62,9 +62,11 @@ module Profiler
|
|
|
62
62
|
def toolbar_html
|
|
63
63
|
<<~HTML
|
|
64
64
|
#{ajax_interceptor_script}
|
|
65
|
-
<div id="profiler-toolbar" data-token="#{@token}" data-version="#{Profiler::VERSION}"></div>
|
|
66
|
-
<script src="/_profiler/assets/profiler-toolbar.js" defer#{nonce_attr}></script>
|
|
67
65
|
<style>#{toolbar_styles}</style>
|
|
66
|
+
<div id="profiler-toolbar" class="profiler-root" data-token="#{@token}"></div>
|
|
67
|
+
<button id="profiler-toolbar-toggle" class="profiler-root" title="Toggle profiler (Alt+P)"><span class="profiler-toggle-icon">▶</span></button>
|
|
68
|
+
<script#{nonce_attr}>(function(){var c=localStorage.getItem('profiler-toolbar-collapsed')==='true',t=localStorage.getItem('profiler-theme'),theme=t==='light'?'light':t==='dark'?'dark':(window.matchMedia('(prefers-color-scheme:light)').matches?'light':'dark'),el=document.getElementById('profiler-toolbar'),tog=document.getElementById('profiler-toolbar-toggle');if(c){el.style.cssText='animation:none!important;transform:translateX(calc(100% + 44px))';tog.dataset.collapsed='true';}el.setAttribute('data-theme',theme);tog.setAttribute('data-theme',theme);})();</script>
|
|
69
|
+
<script src="/_profiler/assets/profiler-toolbar.js" defer#{nonce_attr}></script>
|
|
68
70
|
HTML
|
|
69
71
|
end
|
|
70
72
|
|
|
@@ -76,39 +78,28 @@ module Profiler
|
|
|
76
78
|
# Variables are defined on #profiler-toolbar to avoid polluting the host app.
|
|
77
79
|
def toolbar_styles
|
|
78
80
|
<<~'CSS'
|
|
79
|
-
|
|
81
|
+
.profiler-root {
|
|
80
82
|
--pf-bg: #080b10;
|
|
81
83
|
--pf-surface: #0d1117;
|
|
82
84
|
--pf-raised: #131920;
|
|
83
85
|
--pf-text: #eef2f7;
|
|
84
|
-
--pf-muted: #
|
|
86
|
+
--pf-muted: #4d6170;
|
|
85
87
|
--pf-amber: #f59e0b;
|
|
86
88
|
--pf-amber-h: #fbbf24;
|
|
87
|
-
--pf-amber-bg: rgba(245,158,11,.
|
|
88
|
-
--pf-amber-glow: rgba(245,158,11,.
|
|
89
|
+
--pf-amber-bg: rgba(245,158,11,.08);
|
|
90
|
+
--pf-amber-glow: rgba(245,158,11,.2);
|
|
89
91
|
--pf-success: #22c55e;
|
|
90
92
|
--pf-warning: #fb923c;
|
|
91
93
|
--pf-error: #f87171;
|
|
92
94
|
--pf-info: #60a5fa;
|
|
93
|
-
--pf-border: rgba(255,255,255,.
|
|
94
|
-
--pf-border-s: rgba(255,255,255,.
|
|
95
|
+
--pf-border: rgba(255,255,255,.06);
|
|
96
|
+
--pf-border-s: rgba(255,255,255,.11);
|
|
95
97
|
--pf-mono: 'JetBrains Mono','SF Mono','Fira Code',monospace;
|
|
96
|
-
--pf-tf:
|
|
97
|
-
--pf-tb:
|
|
98
|
-
|
|
99
|
-
position: fixed;
|
|
100
|
-
bottom: 0; left: 0; right: 0;
|
|
101
|
-
height: 44px;
|
|
102
|
-
background: var(--pf-bg);
|
|
103
|
-
border-top: 1px solid var(--pf-border-s);
|
|
104
|
-
z-index: 999999;
|
|
105
|
-
font-family: var(--pf-mono);
|
|
106
|
-
font-size: 11px;
|
|
107
|
-
color: var(--pf-muted);
|
|
108
|
-
animation: pfIn 300ms cubic-bezier(.4,0,.2,1) both;
|
|
98
|
+
--pf-tf: 140ms cubic-bezier(.4,0,.2,1);
|
|
99
|
+
--pf-tb: 240ms cubic-bezier(.4,0,.2,1);
|
|
109
100
|
}
|
|
110
|
-
/* ── Light theme
|
|
111
|
-
|
|
101
|
+
/* ── Light theme ─────────────────────────────────────────────────── */
|
|
102
|
+
.profiler-root[data-theme="light"] {
|
|
112
103
|
--pf-bg: #f5f3ef;
|
|
113
104
|
--pf-surface: #edeae3;
|
|
114
105
|
--pf-raised: #e3ded5;
|
|
@@ -116,39 +107,63 @@ module Profiler
|
|
|
116
107
|
--pf-muted: #8a7a6e;
|
|
117
108
|
--pf-amber: #b45309;
|
|
118
109
|
--pf-amber-h: #92400e;
|
|
119
|
-
--pf-amber-bg: rgba(180,83,9,.
|
|
120
|
-
--pf-amber-glow: rgba(180,83,9,.
|
|
110
|
+
--pf-amber-bg: rgba(180,83,9,.07);
|
|
111
|
+
--pf-amber-glow: rgba(180,83,9,.18);
|
|
121
112
|
--pf-success: #15803d;
|
|
122
113
|
--pf-warning: #c2410c;
|
|
123
114
|
--pf-error: #dc2626;
|
|
124
115
|
--pf-info: #1d4ed8;
|
|
125
|
-
--pf-border: rgba(28,20,16,.
|
|
126
|
-
--pf-border-s: rgba(28,20,16,.
|
|
116
|
+
--pf-border: rgba(28,20,16,.08);
|
|
117
|
+
--pf-border-s: rgba(28,20,16,.18);
|
|
127
118
|
}
|
|
128
|
-
|
|
119
|
+
#profiler-toolbar {
|
|
120
|
+
position: fixed;
|
|
121
|
+
bottom: 0; left: 0; right: 44px;
|
|
122
|
+
height: 44px;
|
|
123
|
+
background: linear-gradient(180deg, var(--pf-surface) 0%, var(--pf-bg) 100%);
|
|
124
|
+
border-top: 1px solid var(--pf-border-s);
|
|
125
|
+
z-index: 999999;
|
|
126
|
+
font-family: var(--pf-mono);
|
|
127
|
+
font-size: 11px;
|
|
128
|
+
color: var(--pf-muted);
|
|
129
|
+
animation: pfIn 320ms cubic-bezier(.4,0,.2,1) both;
|
|
130
|
+
}
|
|
131
|
+
/* ── Slide-in animation ──────────────────────────────────────────── */
|
|
129
132
|
@keyframes pfIn {
|
|
130
133
|
from { transform: translateY(100%); opacity: 0; }
|
|
131
|
-
to { transform: translateY(0);
|
|
134
|
+
to { transform: translateY(0); opacity: 1; }
|
|
135
|
+
}
|
|
136
|
+
@keyframes pfPop {
|
|
137
|
+
0% { transform: scaleX(1); }
|
|
138
|
+
15% { transform: scaleX(1.18); }
|
|
139
|
+
40% { transform: scaleX(0.87); }
|
|
140
|
+
65% { transform: scaleX(1.08); }
|
|
141
|
+
85% { transform: scaleX(0.97); }
|
|
142
|
+
100% { transform: scaleX(1); }
|
|
132
143
|
}
|
|
144
|
+
/* ── Amber accent line ───────────────────────────────────────────── */
|
|
133
145
|
#profiler-toolbar::before {
|
|
134
146
|
content: '';
|
|
135
147
|
position: absolute;
|
|
136
148
|
top: -1px; left: 0; right: 0;
|
|
137
149
|
height: 1px;
|
|
138
|
-
background: linear-gradient(90deg,transparent 0
|
|
139
|
-
opacity: .
|
|
150
|
+
background: linear-gradient(90deg, transparent 0%, #f59e0b 25%, #fbbf24 50%, #f59e0b 75%, transparent 100%);
|
|
151
|
+
opacity: .55;
|
|
152
|
+
transition: opacity 280ms;
|
|
140
153
|
}
|
|
154
|
+
/* ── Container ───────────────────────────────────────────────────── */
|
|
141
155
|
#profiler-toolbar .profiler-toolbar-container {
|
|
142
156
|
display: flex;
|
|
143
157
|
align-items: stretch;
|
|
144
158
|
height: 100%;
|
|
145
159
|
}
|
|
160
|
+
/* ── Items ───────────────────────────────────────────────────────── */
|
|
146
161
|
#profiler-toolbar .profiler-toolbar-item {
|
|
147
162
|
position: relative;
|
|
148
163
|
display: inline-flex;
|
|
149
164
|
align-items: center;
|
|
150
165
|
gap: 5px;
|
|
151
|
-
padding: 0
|
|
166
|
+
padding: 0 13px;
|
|
152
167
|
color: var(--pf-muted);
|
|
153
168
|
text-decoration: none;
|
|
154
169
|
white-space: nowrap;
|
|
@@ -159,7 +174,9 @@ module Profiler
|
|
|
159
174
|
font-family: var(--pf-mono);
|
|
160
175
|
font-size: 11px;
|
|
161
176
|
transition: color var(--pf-tf), background var(--pf-tf);
|
|
177
|
+
cursor: default;
|
|
162
178
|
}
|
|
179
|
+
/* Amber bottom indicator — springy easing */
|
|
163
180
|
#profiler-toolbar .profiler-toolbar-item::after {
|
|
164
181
|
content: '';
|
|
165
182
|
position: absolute;
|
|
@@ -168,52 +185,114 @@ module Profiler
|
|
|
168
185
|
background: var(--pf-amber);
|
|
169
186
|
transform: scaleX(0);
|
|
170
187
|
transform-origin: left;
|
|
171
|
-
transition: transform
|
|
188
|
+
transition: transform 280ms cubic-bezier(.34,1.4,.64,1);
|
|
172
189
|
}
|
|
173
|
-
|
|
174
|
-
#profiler-toolbar a.profiler-toolbar-item
|
|
190
|
+
/* Hover: all interactive items */
|
|
191
|
+
#profiler-toolbar a.profiler-toolbar-item,
|
|
192
|
+
#profiler-toolbar .profiler-toolbar-hoverable { cursor: pointer; }
|
|
193
|
+
|
|
194
|
+
#profiler-toolbar a.profiler-toolbar-item:hover,
|
|
195
|
+
#profiler-toolbar .profiler-toolbar-hoverable:hover {
|
|
175
196
|
color: var(--pf-text);
|
|
176
197
|
background: var(--pf-amber-bg);
|
|
177
198
|
}
|
|
178
|
-
#profiler-toolbar a.profiler-toolbar-item:hover::after
|
|
199
|
+
#profiler-toolbar a.profiler-toolbar-item:hover::after,
|
|
200
|
+
#profiler-toolbar .profiler-toolbar-hoverable:hover::after { transform: scaleX(1); }
|
|
201
|
+
|
|
202
|
+
/* Severity underline colors */
|
|
203
|
+
#profiler-toolbar .profiler-text--error::after { background: var(--pf-error); }
|
|
204
|
+
#profiler-toolbar .profiler-text--warning::after { background: var(--pf-warning); }
|
|
205
|
+
#profiler-toolbar .profiler-text--success::after { background: var(--pf-success); }
|
|
206
|
+
|
|
207
|
+
/* Semantic colors */
|
|
179
208
|
#profiler-toolbar .profiler-text--success { color: var(--pf-success) !important; }
|
|
180
209
|
#profiler-toolbar .profiler-text--warning { color: var(--pf-warning) !important; }
|
|
181
210
|
#profiler-toolbar .profiler-text--error { color: var(--pf-error) !important; }
|
|
182
211
|
#profiler-toolbar .profiler-text--accent { color: var(--pf-amber) !important; }
|
|
183
212
|
#profiler-toolbar .profiler-text--muted { color: var(--pf-muted) !important; }
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
#profiler-toolbar .profiler-toolbar-
|
|
187
|
-
border-right:
|
|
188
|
-
margin-left: auto;
|
|
213
|
+
|
|
214
|
+
/* Logo link */
|
|
215
|
+
#profiler-toolbar .profiler-toolbar-logo {
|
|
216
|
+
border-right: 1px solid var(--pf-border) !important;
|
|
189
217
|
color: var(--pf-amber);
|
|
190
|
-
padding-left: 20px;
|
|
191
218
|
font-weight: 600;
|
|
219
|
+
letter-spacing: .02em;
|
|
220
|
+
}
|
|
221
|
+
#profiler-toolbar .profiler-toolbar-logo:hover { color: var(--pf-amber-h); }
|
|
222
|
+
|
|
223
|
+
/* ── Toggle button (fixed, always visible) ───────────────────────── */
|
|
224
|
+
#profiler-toolbar-toggle {
|
|
225
|
+
position: fixed;
|
|
226
|
+
bottom: 0; right: 0;
|
|
227
|
+
width: 44px; height: 44px;
|
|
228
|
+
display: flex; align-items: center; justify-content: center;
|
|
229
|
+
cursor: pointer;
|
|
230
|
+
background: linear-gradient(180deg, var(--pf-surface) 0%, var(--pf-bg) 100%);
|
|
231
|
+
border: none;
|
|
232
|
+
border-top: 1px solid var(--pf-border-s);
|
|
233
|
+
border-left: 1px solid var(--pf-border);
|
|
234
|
+
color: var(--pf-muted);
|
|
235
|
+
font-family: var(--pf-mono);
|
|
236
|
+
font-size: 13px;
|
|
237
|
+
z-index: 1000000;
|
|
238
|
+
border-radius: 0;
|
|
239
|
+
transition: color var(--pf-tf), background var(--pf-tf);
|
|
240
|
+
}
|
|
241
|
+
#profiler-toolbar-toggle:hover {
|
|
242
|
+
color: var(--pf-amber);
|
|
243
|
+
animation: pfPop 380ms ease-out both;
|
|
244
|
+
transform: none;
|
|
192
245
|
}
|
|
193
|
-
|
|
246
|
+
.profiler-toggle-icon {
|
|
247
|
+
display: inline-block;
|
|
248
|
+
transition: transform 280ms cubic-bezier(.4,0,.2,1);
|
|
249
|
+
}
|
|
250
|
+
#profiler-toolbar-toggle[data-collapsed="true"] .profiler-toggle-icon {
|
|
251
|
+
transform: scaleX(-1);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/* ── Hoverable wrapper ───────────────────────────────────────────── */
|
|
194
255
|
#profiler-toolbar .profiler-toolbar-hoverable { position: relative; }
|
|
256
|
+
|
|
257
|
+
/* ── Panel (CSS-driven visibility) ───────────────────────────────── */
|
|
195
258
|
#profiler-toolbar .profiler-toolbar-panel {
|
|
196
|
-
display: none;
|
|
197
259
|
position: absolute;
|
|
198
|
-
bottom: calc(100% +
|
|
260
|
+
bottom: calc(100% + 12px);
|
|
199
261
|
left: 50%;
|
|
200
262
|
transform: translateX(-50%);
|
|
201
263
|
min-width: 300px;
|
|
202
264
|
max-width: 420px;
|
|
203
265
|
background: var(--pf-surface);
|
|
204
266
|
border: 1px solid var(--pf-border-s);
|
|
205
|
-
border-radius:
|
|
206
|
-
box-shadow: 0
|
|
267
|
+
border-radius: 10px;
|
|
268
|
+
box-shadow: 0 12px 40px rgba(0,0,0,.7), 0 0 0 1px var(--pf-amber-glow);
|
|
207
269
|
z-index: 1000000;
|
|
208
270
|
overflow: hidden;
|
|
271
|
+
/* Hidden state */
|
|
272
|
+
opacity: 0;
|
|
273
|
+
visibility: hidden;
|
|
274
|
+
pointer-events: none;
|
|
275
|
+
transition:
|
|
276
|
+
opacity 160ms cubic-bezier(.4,0,.2,1),
|
|
277
|
+
visibility 0s linear 160ms;
|
|
209
278
|
}
|
|
279
|
+
#profiler-toolbar .profiler-toolbar-panel.is-visible {
|
|
280
|
+
opacity: 1;
|
|
281
|
+
visibility: visible;
|
|
282
|
+
pointer-events: auto;
|
|
283
|
+
transition:
|
|
284
|
+
opacity 160ms cubic-bezier(.4,0,.2,1),
|
|
285
|
+
visibility 0s;
|
|
286
|
+
}
|
|
287
|
+
/* Amber top bar on panel */
|
|
210
288
|
#profiler-toolbar .profiler-toolbar-panel::before {
|
|
211
289
|
content: '';
|
|
212
290
|
position: absolute;
|
|
213
291
|
top: 0; left: 0; right: 0;
|
|
214
292
|
height: 2px;
|
|
215
|
-
background: linear-gradient(90deg
|
|
293
|
+
background: linear-gradient(90deg, #f59e0b, #fbbf24);
|
|
216
294
|
}
|
|
295
|
+
/* Arrow */
|
|
217
296
|
#profiler-toolbar .profiler-toolbar-panel::after {
|
|
218
297
|
content: '';
|
|
219
298
|
position: absolute;
|
|
@@ -223,11 +302,13 @@ module Profiler
|
|
|
223
302
|
border-top-color: var(--pf-border-s);
|
|
224
303
|
}
|
|
225
304
|
#profiler-toolbar .profiler-toolbar-panel-large { min-width: 420px; max-width: 560px; }
|
|
305
|
+
|
|
306
|
+
/* ── Panel header ────────────────────────────────────────────────── */
|
|
226
307
|
#profiler-toolbar .profiler-toolbar-panel-header {
|
|
227
308
|
display: flex;
|
|
228
309
|
align-items: center;
|
|
229
310
|
justify-content: space-between;
|
|
230
|
-
padding: 10px 14px
|
|
311
|
+
padding: 10px 14px 9px;
|
|
231
312
|
font-size: 10px;
|
|
232
313
|
font-weight: 700;
|
|
233
314
|
letter-spacing: .12em;
|
|
@@ -244,6 +325,8 @@ module Profiler
|
|
|
244
325
|
letter-spacing: 0;
|
|
245
326
|
font-size: 10px;
|
|
246
327
|
}
|
|
328
|
+
|
|
329
|
+
/* ── Panel content ───────────────────────────────────────────────── */
|
|
247
330
|
#profiler-toolbar .profiler-toolbar-panel-content {
|
|
248
331
|
padding: 8px 14px 12px;
|
|
249
332
|
max-height: 380px;
|
|
@@ -258,16 +341,22 @@ module Profiler
|
|
|
258
341
|
background: var(--pf-border-s);
|
|
259
342
|
border-radius: 99px;
|
|
260
343
|
}
|
|
344
|
+
|
|
345
|
+
/* ── Panel rows ──────────────────────────────────────────────────── */
|
|
261
346
|
#profiler-toolbar .profiler-toolbar-panel-row {
|
|
262
347
|
display: flex;
|
|
263
348
|
justify-content: space-between;
|
|
264
349
|
align-items: baseline;
|
|
265
|
-
padding:
|
|
350
|
+
padding: 6px 0;
|
|
266
351
|
border-bottom: 1px solid var(--pf-border);
|
|
267
352
|
gap: 12px;
|
|
268
353
|
}
|
|
269
354
|
#profiler-toolbar .profiler-toolbar-panel-row:last-child { border-bottom: none; }
|
|
270
|
-
#profiler-toolbar .profiler-toolbar-panel-row span {
|
|
355
|
+
#profiler-toolbar .profiler-toolbar-panel-row span {
|
|
356
|
+
color: var(--pf-muted);
|
|
357
|
+
font-size: 10px;
|
|
358
|
+
flex-shrink: 0;
|
|
359
|
+
}
|
|
271
360
|
#profiler-toolbar .profiler-toolbar-panel-row strong {
|
|
272
361
|
color: var(--pf-text);
|
|
273
362
|
font-weight: 600;
|
|
@@ -275,6 +364,8 @@ module Profiler
|
|
|
275
364
|
font-variant-numeric: tabular-nums;
|
|
276
365
|
word-break: break-all;
|
|
277
366
|
}
|
|
367
|
+
|
|
368
|
+
/* ── Section header ──────────────────────────────────────────────── */
|
|
278
369
|
#profiler-toolbar .profiler-section__header {
|
|
279
370
|
font-size: 9px;
|
|
280
371
|
font-weight: 700;
|
|
@@ -282,22 +373,26 @@ module Profiler
|
|
|
282
373
|
text-transform: uppercase;
|
|
283
374
|
color: var(--pf-amber);
|
|
284
375
|
padding: 10px 0 4px;
|
|
285
|
-
border-bottom: 1px solid rgba(245,158,11,.
|
|
376
|
+
border-bottom: 1px solid rgba(245,158,11,.18);
|
|
286
377
|
margin-bottom: 6px;
|
|
287
378
|
font-family: var(--pf-mono);
|
|
288
379
|
}
|
|
289
380
|
#profiler-toolbar .profiler-section__header:first-child { padding-top: 4px; }
|
|
381
|
+
|
|
382
|
+
/* ── Query cards ─────────────────────────────────────────────────── */
|
|
290
383
|
#profiler-toolbar .profiler-toolbar-panel-query {
|
|
291
384
|
padding: 7px 10px;
|
|
292
385
|
background: var(--pf-raised);
|
|
293
386
|
border: 1px solid var(--pf-border);
|
|
294
|
-
border-radius:
|
|
387
|
+
border-radius: 5px;
|
|
295
388
|
margin-bottom: 5px;
|
|
389
|
+
transition: border-color var(--pf-tf);
|
|
296
390
|
}
|
|
297
391
|
#profiler-toolbar .profiler-toolbar-panel-query:last-child { margin-bottom: 0; }
|
|
392
|
+
#profiler-toolbar .profiler-toolbar-panel-query:hover { border-color: var(--pf-border-s); }
|
|
298
393
|
#profiler-toolbar .profiler-toolbar-panel-query-slow {
|
|
299
394
|
border-left: 2px solid var(--pf-error);
|
|
300
|
-
background: rgba(248,113,113,.
|
|
395
|
+
background: rgba(248,113,113,.05);
|
|
301
396
|
}
|
|
302
397
|
#profiler-toolbar .profiler-toolbar-panel-query code {
|
|
303
398
|
display: block;
|
|
@@ -313,6 +408,8 @@ module Profiler
|
|
|
313
408
|
padding: 0;
|
|
314
409
|
border: none;
|
|
315
410
|
}
|
|
411
|
+
|
|
412
|
+
/* ── More hint ───────────────────────────────────────────────────── */
|
|
316
413
|
#profiler-toolbar .profiler-more {
|
|
317
414
|
text-align: center;
|
|
318
415
|
padding: 7px;
|
|
@@ -322,13 +419,17 @@ module Profiler
|
|
|
322
419
|
border-top: 1px dashed var(--pf-border);
|
|
323
420
|
margin-top: 6px;
|
|
324
421
|
}
|
|
422
|
+
|
|
423
|
+
/* ── Ajax cards ──────────────────────────────────────────────────── */
|
|
325
424
|
#profiler-toolbar .profiler-ajax-card {
|
|
326
425
|
background: var(--pf-raised);
|
|
327
426
|
border: 1px solid var(--pf-border);
|
|
328
|
-
border-radius:
|
|
427
|
+
border-radius: 5px;
|
|
329
428
|
padding: 6px 8px;
|
|
330
429
|
margin-bottom: 4px;
|
|
430
|
+
transition: border-color var(--pf-tf);
|
|
331
431
|
}
|
|
432
|
+
#profiler-toolbar .profiler-ajax-card:hover { border-color: var(--pf-border-s); }
|
|
332
433
|
#profiler-toolbar .profiler-ajax-card--success { border-left: 2px solid var(--pf-success); }
|
|
333
434
|
#profiler-toolbar .profiler-ajax-card--error { border-left: 2px solid var(--pf-error); }
|
|
334
435
|
#profiler-toolbar .profiler-ajax-card__row {
|
|
@@ -337,10 +438,12 @@ module Profiler
|
|
|
337
438
|
align-items: center;
|
|
338
439
|
gap: 8px;
|
|
339
440
|
}
|
|
441
|
+
|
|
442
|
+
/* ── Dump cards ──────────────────────────────────────────────────── */
|
|
340
443
|
#profiler-toolbar .profiler-dump-card {
|
|
341
444
|
background: var(--pf-raised);
|
|
342
445
|
border: 1px solid var(--pf-border);
|
|
343
|
-
border-radius:
|
|
446
|
+
border-radius: 5px;
|
|
344
447
|
padding: 6px 8px;
|
|
345
448
|
margin-bottom: 4px;
|
|
346
449
|
}
|
|
@@ -349,11 +452,13 @@ module Profiler
|
|
|
349
452
|
justify-content: space-between;
|
|
350
453
|
margin-bottom: 4px;
|
|
351
454
|
}
|
|
455
|
+
|
|
456
|
+
/* ── Badges ──────────────────────────────────────────────────────── */
|
|
352
457
|
#profiler-toolbar .badge {
|
|
353
458
|
display: inline-flex;
|
|
354
459
|
align-items: center;
|
|
355
|
-
padding: 1px
|
|
356
|
-
border-radius:
|
|
460
|
+
padding: 1px 6px;
|
|
461
|
+
border-radius: 4px;
|
|
357
462
|
font-size: 9px;
|
|
358
463
|
font-weight: 700;
|
|
359
464
|
letter-spacing: .05em;
|
|
@@ -361,10 +466,12 @@ module Profiler
|
|
|
361
466
|
background: var(--pf-raised);
|
|
362
467
|
color: var(--pf-muted);
|
|
363
468
|
}
|
|
364
|
-
#profiler-toolbar .badge-info { background: rgba(96,165,250,.
|
|
365
|
-
#profiler-toolbar .badge-success { background: rgba(34,197,94,.
|
|
366
|
-
#profiler-toolbar .badge-warning { background: rgba(251,146,60,.
|
|
367
|
-
#profiler-toolbar .badge-error { background: rgba(248,113,113,.
|
|
469
|
+
#profiler-toolbar .badge-info { background: rgba(96,165,250,.1); color: var(--pf-info); }
|
|
470
|
+
#profiler-toolbar .badge-success { background: rgba(34,197,94,.1); color: var(--pf-success); }
|
|
471
|
+
#profiler-toolbar .badge-warning { background: rgba(251,146,60,.1); color: var(--pf-warning); }
|
|
472
|
+
#profiler-toolbar .badge-error { background: rgba(248,113,113,.1); color: var(--pf-error); }
|
|
473
|
+
|
|
474
|
+
/* ── Utilities ───────────────────────────────────────────────────── */
|
|
368
475
|
#profiler-toolbar .profiler-flex { display: flex; }
|
|
369
476
|
#profiler-toolbar .profiler-flex--between { justify-content: space-between; }
|
|
370
477
|
#profiler-toolbar .profiler-flex--gap-2 { gap: 8px; }
|
data/lib/profiler/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails-profiler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.21.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sébastien Duplessy
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-05-
|
|
11
|
+
date: 2026-05-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|