This commit is contained in:
Ross
2021-07-26 10:48:08 +01:00
parent 16d7875d0d
commit 3367328d94
659 changed files with 170339 additions and 1 deletions
+3
View File
@@ -0,0 +1,3 @@
#djDebug {
display: none !important;
}
+612
View File
@@ -0,0 +1,612 @@
/* Debug Toolbar CSS Reset, adapted from Eric Meyer's CSS Reset */
#djDebug {
color: #000;
background: #fff;
}
#djDebug,
#djDebug div,
#djDebug span,
#djDebug applet,
#djDebug object,
#djDebug iframe,
#djDebug h1,
#djDebug h2,
#djDebug h3,
#djDebug h4,
#djDebug h5,
#djDebug h6,
#djDebug p,
#djDebug blockquote,
#djDebug pre,
#djDebug a,
#djDebug abbr,
#djDebug acronym,
#djDebug address,
#djDebug big,
#djDebug cite,
#djDebug code,
#djDebug del,
#djDebug dfn,
#djDebug em,
#djDebug font,
#djDebug img,
#djDebug ins,
#djDebug kbd,
#djDebug q,
#djDebug s,
#djDebug samp,
#djDebug small,
#djDebug strike,
#djDebug strong,
#djDebug sub,
#djDebug sup,
#djDebug tt,
#djDebug var,
#djDebug b,
#djDebug u,
#djDebug i,
#djDebug center,
#djDebug dl,
#djDebug dt,
#djDebug dd,
#djDebug ol,
#djDebug ul,
#djDebug li,
#djDebug fieldset,
#djDebug form,
#djDebug label,
#djDebug legend,
#djDebug table,
#djDebug caption,
#djDebug tbody,
#djDebug tfoot,
#djDebug thead,
#djDebug tr,
#djDebug th,
#djDebug td,
#djDebug button {
margin: 0;
padding: 0;
min-width: 0;
width: auto;
border: 0;
outline: 0;
font-size: 12px;
line-height: 1.5em;
color: #000;
vertical-align: baseline;
background-color: transparent;
font-family: sans-serif;
text-align: left;
text-shadow: none;
white-space: normal;
transition: none;
}
#djDebug button {
background-color: #eee;
background-image: linear-gradient(to bottom, #eee, #cccccc);
border: 1px solid #ccc;
border-bottom: 1px solid #bbb;
border-radius: 3px;
color: #333;
line-height: 1;
padding: 0 8px;
text-align: center;
text-shadow: 0 1px 0 #eee;
}
#djDebug button:hover {
background-color: #ddd;
background-image: linear-gradient(to bottom, #ddd, #bbb);
border-color: #bbb;
border-bottom-color: #999;
cursor: pointer;
text-shadow: 0 1px 0 #ddd;
}
#djDebug button:active {
border: 1px solid #aaa;
border-bottom: 1px solid #888;
box-shadow: inset 0 0 5px 2px #aaa, 0 1px 0 0 #eee;
}
#djDebug #djDebugToolbar {
background-color: #111;
width: 220px;
z-index: 100000000;
position: fixed;
top: 0;
bottom: 0;
right: 0;
opacity: 0.9;
overflow-y: auto;
}
#djDebug #djDebugToolbar small {
color: #999;
}
#djDebug #djDebugToolbar ul {
margin: 0;
padding: 0;
list-style: none;
}
#djDebug #djDebugToolbar li {
border-bottom: 1px solid #222;
color: #fff;
display: block;
font-weight: bold;
float: none;
margin: 0;
padding: 0;
position: relative;
width: auto;
}
#djDebug #djDebugToolbar input[type="checkbox"] {
float: right;
margin: 10px;
}
#djDebug #djDebugToolbar li > a,
#djDebug #djDebugToolbar li > div.djdt-contentless {
font-weight: normal;
font-style: normal;
text-decoration: none;
display: block;
font-size: 16px;
padding: 10px 10px 5px 25px;
color: #fff;
}
#djDebug #djDebugToolbar li > div.djdt-disabled {
font-style: italic;
color: #999;
}
#djDebug #djDebugToolbar li a:hover {
color: #111;
background-color: #ffc;
}
#djDebug #djDebugToolbar li.djdt-active {
background: #333;
}
#djDebug #djDebugToolbar li.djdt-active:before {
content: "▶";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
color: #eee;
font-size: 150%;
}
#djDebug #djDebugToolbar li.djdt-active a:hover {
color: #b36a60;
background-color: transparent;
}
#djDebug #djDebugToolbar li small {
font-size: 12px;
color: #999;
font-style: normal;
text-decoration: none;
}
#djDebug #djDebugToolbarHandle {
position: fixed;
transform: rotate(-90deg);
transform-origin: right bottom;
background-color: #fff;
border: 1px solid #111;
border-bottom: 0;
top: 0;
right: 0;
z-index: 100000000;
opacity: 0.75;
}
#djDebug #djShowToolBarButton {
padding: 0 5px;
border: 4px solid #fff;
border-bottom-width: 0;
color: #fff;
font-size: 22px;
font-weight: bold;
background: #000;
opacity: 0.5;
}
#djDebug #djShowToolBarButton:hover {
background-color: #111;
border-color: #ffe761;
cursor: move;
opacity: 1;
}
#djDebug #djShowToolBarD {
color: #cf9;
font-size: 22px;
}
#djDebug #djShowToolBarJ {
color: #cf9;
font-size: 16px;
}
#djDebug code {
display: block;
font-family: Consolas, Monaco, "Bitstream Vera Sans Mono", "Lucida Console",
monospace;
font-size: 12px;
white-space: pre;
overflow: auto;
}
#djDebug .djdt-panelContent {
position: fixed;
margin: 0;
top: 0;
right: 220px;
bottom: 0;
left: 0px;
background-color: #eee;
color: #666;
z-index: 100000000;
}
#djDebug .djdt-panelContent > div {
border-bottom: 1px solid #ddd;
}
#djDebug .djDebugPanelTitle {
position: absolute;
background-color: #ffc;
color: #666;
padding-left: 20px;
top: 0;
right: 0;
left: 0;
height: 50px;
}
#djDebug .djDebugPanelTitle code {
display: inline;
font-size: inherit;
}
#djDebug .djDebugPanelContent {
position: absolute;
top: 50px;
right: 0;
bottom: 0;
left: 0;
height: auto;
padding: 5px 0 0 20px;
}
#djDebug .djDebugPanelContent .djdt-loader {
margin: 80px auto;
border: 6px solid white;
border-radius: 50%;
border-top: 6px solid #ffe761;
width: 38px;
height: 38px;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#djDebug .djDebugPanelContent .djdt-scroll {
height: 100%;
overflow: auto;
display: block;
padding: 0 10px 0 0;
}
#djDebug h3 {
font-size: 24px;
font-weight: normal;
line-height: 50px;
}
#djDebug h4 {
font-size: 20px;
font-weight: bold;
margin-top: 0.8em;
}
#djDebug .djdt-panelContent table {
border: 1px solid #ccc;
border-collapse: collapse;
width: 100%;
background-color: #fff;
display: table;
margin-top: 0.8em;
overflow: auto;
}
#djDebug .djdt-panelContent tbody > tr:nth-child(odd) {
background-color: #f5f5f5;
}
#djDebug .djdt-panelContent tbody td,
#djDebug .djdt-panelContent tbody th {
vertical-align: top;
padding: 2px 3px;
}
#djDebug .djdt-panelContent tbody td.djdt-time {
text-align: center;
}
#djDebug .djdt-panelContent thead th {
padding: 1px 6px 1px 3px;
text-align: left;
font-weight: bold;
font-size: 14px;
white-space: nowrap;
}
#djDebug .djdt-panelContent tbody th {
width: 12em;
text-align: right;
color: #666;
padding-right: 0.5em;
}
#djDebug .djTemplateContext {
background-color: #fff;
}
#djDebug .djdt-panelContent .djDebugClose {
position: absolute;
top: 4px;
right: 15px;
height: 16px;
width: 16px;
line-height: 16px;
padding: 5px;
border: 6px solid #ddd;
border-radius: 50%;
background: #fff;
color: #ddd;
text-align: center;
font-weight: 900;
font-size: 20px;
box-sizing: content-box;
}
#djDebug .djdt-panelContent .djDebugClose:hover {
background: #c0695d;
}
#djDebug .djdt-panelContent dt,
#djDebug .djdt-panelContent dd {
display: block;
}
#djDebug .djdt-panelContent dt {
margin-top: 0.75em;
}
#djDebug .djdt-panelContent dd {
margin-left: 10px;
}
#djDebug a.toggleTemplate {
padding: 4px;
background-color: #bbb;
border-radius: 3px;
}
#djDebug a.toggleTemplate:hover {
padding: 4px;
background-color: #444;
color: #ffe761;
border-radius: 3px;
}
#djDebug .djDebugCollapsed {
color: #333;
}
#djDebug .djDebugUncollapsed {
color: #333;
}
#djDebug .djUnselected {
display: none;
}
#djDebug tr.djSelected {
display: table-row;
}
#djDebug .djDebugSql {
overflow-wrap: anywhere;
}
#djDebug .djSQLDetailsDiv tbody th {
text-align: left;
}
#djDebug span.djDebugLineChart {
background-color: #777;
height: 3px;
position: absolute;
bottom: 0;
top: 0;
left: 0;
display: block;
z-index: 1000000001;
}
#djDebug span.djDebugLineChartWarning {
background-color: #900;
}
#djDebug .highlight {
color: #000;
}
#djDebug .highlight .err {
color: #000;
} /* Error */
#djDebug .highlight .g {
color: #000;
} /* Generic */
#djDebug .highlight .k {
color: #000;
font-weight: bold;
} /* Keyword */
#djDebug .highlight .o {
color: #000;
} /* Operator */
#djDebug .highlight .n {
color: #000;
} /* Name */
#djDebug .highlight .mi {
color: #000;
font-weight: bold;
} /* Literal.Number.Integer */
#djDebug .highlight .l {
color: #000;
} /* Literal */
#djDebug .highlight .x {
color: #000;
} /* Other */
#djDebug .highlight .p {
color: #000;
} /* Punctuation */
#djDebug .highlight .m {
color: #000;
font-weight: bold;
} /* Literal.Number */
#djDebug .highlight .s {
color: #333;
} /* Literal.String */
#djDebug .highlight .w {
color: #888888;
} /* Text.Whitespace */
#djDebug .highlight .il {
color: #000;
font-weight: bold;
} /* Literal.Number.Integer.Long */
#djDebug .highlight .na {
color: #333;
} /* Name.Attribute */
#djDebug .highlight .nt {
color: #000;
font-weight: bold;
} /* Name.Tag */
#djDebug .highlight .nv {
color: #333;
} /* Name.Variable */
#djDebug .highlight .s2 {
color: #333;
} /* Literal.String.Double */
#djDebug .highlight .cp {
color: #333;
} /* Comment.Preproc */
#djDebug svg.djDebugLineChart {
width: 100%;
height: 1.5em;
}
#djDebug svg.djDebugLineChartWarning rect {
fill: #900;
}
#djDebug svg.djDebugLineChartInTransaction rect {
fill: #d3ff82;
}
#djDebug svg.djDebugLineChart line {
stroke: #94b24d;
}
#djDebug .djDebugRowWarning .djdt-time {
color: red;
}
#djDebug .djdt-panelContent table .djdt-toggle {
width: 14px;
padding-top: 3px;
}
#djDebug .djdt-panelContent table .djdt-actions {
min-width: 70px;
white-space: nowrap;
}
#djDebug .djdt-color:after {
content: "\00a0";
}
#djDebug .djToggleSwitch {
box-sizing: content-box;
padding: 0;
border: 1px solid #999;
border-radius: 0;
width: 12px;
color: #777;
background: linear-gradient(to bottom, #fff, #dcdcdc);
}
#djDebug .djNoToggleSwitch {
height: 14px;
width: 14px;
display: inline-block;
}
#djDebug .djSQLDetailsDiv {
margin-top: 0.8em;
}
#djDebug pre {
white-space: pre-wrap;
color: #555;
border: 1px solid #ccc;
border-collapse: collapse;
background-color: #fff;
display: block;
overflow: auto;
padding: 2px 3px;
margin-bottom: 3px;
font-family: Consolas, Monaco, "Bitstream Vera Sans Mono", "Lucida Console",
monospace;
}
#djDebug .djdt-stack span {
color: #000;
font-weight: bold;
}
#djDebug .djdt-stack span.djdt-path,
#djDebug .djdt-stack pre.djdt-locals,
#djDebug .djdt-stack pre.djdt-locals span {
color: #777;
font-weight: normal;
}
#djDebug .djdt-stack span.djdt-code {
font-weight: normal;
}
#djDebug .djdt-stack pre.djdt-locals {
margin: 0 27px 27px 27px;
}
#djDebug .djdt-width-20 {
width: 20%;
}
#djDebug .djdt-width-30 {
width: 30%;
}
#djDebug .djdt-width-60 {
width: 60%;
}
#djDebug .djdt-max-height-100 {
max-height: 100%;
}
#djDebug .djdt-highlighted {
background-color: lightgrey;
}
.djdt-hidden {
display: none;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

+40
View File
@@ -0,0 +1,40 @@
import { $$, ajaxForm } from "./utils.js";
const djDebug = document.getElementById("djDebug");
$$.on(djDebug, "click", ".switchHistory", function (event) {
event.preventDefault();
const newStoreId = this.dataset.storeId;
const tbody = this.closest("tbody");
tbody
.querySelector(".djdt-highlighted")
.classList.remove("djdt-highlighted");
this.closest("tr").classList.add("djdt-highlighted");
ajaxForm(this).then(function (data) {
djDebug.setAttribute("data-store-id", newStoreId);
Object.keys(data).forEach(function (panelId) {
const panel = document.getElementById(panelId);
if (panel) {
panel.outerHTML = data[panelId].content;
document.getElementById("djdt-" + panelId).outerHTML =
data[panelId].button;
}
});
});
});
$$.on(djDebug, "click", ".refreshHistory", function (event) {
event.preventDefault();
const container = document.getElementById("djdtHistoryRequests");
ajaxForm(this).then(function (data) {
data.requests.forEach(function (request) {
if (
!container.querySelector('[data-store-id="' + request.id + '"]')
) {
container.innerHTML = request.content + container.innerHTML;
}
});
});
});
+1
View File
@@ -0,0 +1 @@
document.getElementById("redirect_to").focus();
+59
View File
@@ -0,0 +1,59 @@
const timingOffset = performance.timing.navigationStart,
timingEnd = performance.timing.loadEventEnd,
totalTime = timingEnd - timingOffset;
function getLeft(stat) {
return ((performance.timing[stat] - timingOffset) / totalTime) * 100.0;
}
function getCSSWidth(stat, endStat) {
let width =
((performance.timing[endStat] - performance.timing[stat]) / totalTime) *
100.0;
// Calculate relative percent (same as sql panel logic)
width = (100.0 * width) / (100.0 - getLeft(stat));
return width < 1 ? "2px" : width + "%";
}
function addRow(tbody, stat, endStat) {
const row = document.createElement("tr");
if (endStat) {
// Render a start through end bar
row.innerHTML =
"<td>" +
stat.replace("Start", "") +
"</td>" +
'<td><svg class="djDebugLineChart" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 100 5" preserveAspectRatio="none"><rect y="0" height="5" fill="#ccc" /></svg></td>' +
"<td>" +
(performance.timing[stat] - timingOffset) +
" (+" +
(performance.timing[endStat] - performance.timing[stat]) +
")</td>";
row.querySelector("rect").setAttribute(
"width",
getCSSWidth(stat, endStat)
);
} else {
// Render a point in time
row.innerHTML =
"<td>" +
stat +
"</td>" +
'<td><svg class="djDebugLineChart" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 100 5" preserveAspectRatio="none"><rect y="0" height="5" fill="#ccc" /></svg></td>' +
"<td>" +
(performance.timing[stat] - timingOffset) +
"</td>";
row.querySelector("rect").setAttribute("width", 2);
}
row.querySelector("rect").setAttribute("x", getLeft(stat));
tbody.appendChild(row);
}
const tbody = document.getElementById("djDebugBrowserTimingTableBody");
// This is a reasonably complete and ordered set of timing periods (2 params) and events (1 param)
addRow(tbody, "domainLookupStart", "domainLookupEnd");
addRow(tbody, "connectStart", "connectEnd");
addRow(tbody, "requestStart", "responseEnd"); // There is no requestEnd
addRow(tbody, "responseStart", "responseEnd");
addRow(tbody, "domLoading", "domComplete"); // Spans the events below
addRow(tbody, "domInteractive");
addRow(tbody, "domContentLoadedEventStart", "domContentLoadedEventEnd");
addRow(tbody, "loadEventStart", "loadEventEnd");
document.getElementById("djDebugBrowserTiming").classList.remove("djdt-hidden");
+295
View File
@@ -0,0 +1,295 @@
import { $$, ajax } from "./utils.js";
function onKeyDown(event) {
if (event.keyCode === 27) {
djdt.hide_one_level();
}
}
const djdt = {
handleDragged: false,
init() {
const djDebug = document.getElementById("djDebug");
$$.show(djDebug);
$$.on(
document.getElementById("djDebugPanelList"),
"click",
"li a",
function (event) {
event.preventDefault();
if (!this.className) {
return;
}
const current = document.getElementById(this.className);
if ($$.visible(current)) {
djdt.hide_panels();
} else {
djdt.hide_panels();
$$.show(current);
this.parentElement.classList.add("djdt-active");
const inner = current.querySelector(
".djDebugPanelContent .djdt-scroll"
),
store_id = djDebug.dataset.storeId;
if (store_id && inner.children.length === 0) {
const url = new URL(
djDebug.dataset.renderPanelUrl,
window.location
);
url.searchParams.append("store_id", store_id);
url.searchParams.append("panel_id", this.className);
ajax(url).then(function (data) {
inner.previousElementSibling.remove(); // Remove AJAX loader
inner.innerHTML = data.content;
$$.executeScripts(data.scripts);
$$.applyStyles(inner);
});
}
}
}
);
$$.on(djDebug, "click", ".djDebugClose", function () {
djdt.hide_one_level();
});
$$.on(
djDebug,
"click",
".djDebugPanelButton input[type=checkbox]",
function () {
djdt.cookie.set(
this.dataset.cookie,
this.checked ? "on" : "off",
{
path: "/",
expires: 10,
}
);
}
);
// Used by the SQL and template panels
$$.on(djDebug, "click", ".remoteCall", function (event) {
event.preventDefault();
let url;
const ajax_data = {};
if (this.tagName === "BUTTON") {
const form = this.closest("form");
url = this.formAction;
ajax_data.method = form.method.toUpperCase();
ajax_data.body = new FormData(form);
} else if (this.tagName === "A") {
url = this.href;
}
ajax(url, ajax_data).then(function (data) {
const win = document.getElementById("djDebugWindow");
win.innerHTML = data.content;
$$.show(win);
});
});
// Used by the cache, profiling and SQL panels
$$.on(djDebug, "click", ".djToggleSwitch", function () {
const id = this.dataset.toggleId;
const toggleOpen = "+";
const toggleClose = "-";
const open_me = this.textContent === toggleOpen;
const name = this.dataset.toggleName;
const container = document.getElementById(name + "_" + id);
container
.querySelectorAll(".djDebugCollapsed")
.forEach(function (e) {
$$.toggle(e, open_me);
});
container
.querySelectorAll(".djDebugUncollapsed")
.forEach(function (e) {
$$.toggle(e, !open_me);
});
const self = this;
this.closest(".djDebugPanelContent")
.querySelectorAll(".djToggleDetails_" + id)
.forEach(function (e) {
if (open_me) {
e.classList.add("djSelected");
e.classList.remove("djUnselected");
self.textContent = toggleClose;
} else {
e.classList.remove("djSelected");
e.classList.add("djUnselected");
self.textContent = toggleOpen;
}
const switch_ = e.querySelector(".djToggleSwitch");
if (switch_) {
switch_.textContent = self.textContent;
}
});
});
document
.getElementById("djHideToolBarButton")
.addEventListener("click", function (event) {
event.preventDefault();
djdt.hide_toolbar();
});
document
.getElementById("djShowToolBarButton")
.addEventListener("click", function () {
if (!djdt.handleDragged) {
djdt.show_toolbar();
}
});
let startPageY, baseY;
const handle = document.getElementById("djDebugToolbarHandle");
function onHandleMove(event) {
// Chrome can send spurious mousemove events, so don't do anything unless the
// cursor really moved. Otherwise, it will be impossible to expand the toolbar
// due to djdt.handleDragged being set to true.
if (djdt.handleDragged || event.pageY !== startPageY) {
let top = baseY + event.pageY;
if (top < 0) {
top = 0;
} else if (top + handle.offsetHeight > window.innerHeight) {
top = window.innerHeight - handle.offsetHeight;
}
handle.style.top = top + "px";
djdt.handleDragged = true;
}
}
document
.getElementById("djShowToolBarButton")
.addEventListener("mousedown", function (event) {
event.preventDefault();
startPageY = event.pageY;
baseY = handle.offsetTop - startPageY;
document.addEventListener("mousemove", onHandleMove);
});
document.addEventListener("mouseup", function (event) {
document.removeEventListener("mousemove", onHandleMove);
if (djdt.handleDragged) {
event.preventDefault();
localStorage.setItem("djdt.top", handle.offsetTop);
requestAnimationFrame(function () {
djdt.handleDragged = false;
});
}
});
const show =
localStorage.getItem("djdt.show") || djDebug.dataset.defaultShow;
if (show === "true") {
djdt.show_toolbar();
} else {
djdt.hide_toolbar();
}
},
hide_panels() {
const djDebug = document.getElementById("djDebug");
$$.hide(document.getElementById("djDebugWindow"));
djDebug.querySelectorAll(".djdt-panelContent").forEach(function (e) {
$$.hide(e);
});
document.querySelectorAll("#djDebugToolbar li").forEach(function (e) {
e.classList.remove("djdt-active");
});
},
hide_toolbar() {
djdt.hide_panels();
$$.hide(document.getElementById("djDebugToolbar"));
const handle = document.getElementById("djDebugToolbarHandle");
$$.show(handle);
// set handle position
let handleTop = localStorage.getItem("djdt.top");
if (handleTop) {
handleTop = Math.min(
handleTop,
window.innerHeight - handle.offsetHeight
);
handle.style.top = handleTop + "px";
}
document.removeEventListener("keydown", onKeyDown);
localStorage.setItem("djdt.show", "false");
},
hide_one_level() {
const win = document.getElementById("djDebugWindow");
if ($$.visible(win)) {
$$.hide(win);
} else {
const toolbar = document.getElementById("djDebugToolbar");
if (toolbar.querySelector("li.djdt-active")) {
djdt.hide_panels();
} else {
djdt.hide_toolbar();
}
}
},
show_toolbar() {
document.addEventListener("keydown", onKeyDown);
$$.hide(document.getElementById("djDebugToolbarHandle"));
$$.show(document.getElementById("djDebugToolbar"));
localStorage.setItem("djdt.show", "true");
},
cookie: {
get(key) {
if (!document.cookie.includes(key)) {
return null;
}
const cookieArray = document.cookie.split("; "),
cookies = {};
cookieArray.forEach(function (e) {
const parts = e.split("=");
cookies[parts[0]] = parts[1];
});
return cookies[key];
},
set(key, value, options) {
options = options || {};
if (typeof options.expires === "number") {
const days = options.expires,
t = (options.expires = new Date());
t.setDate(t.getDate() + days);
}
document.cookie = [
encodeURIComponent(key) + "=" + String(value),
options.expires
? "; expires=" + options.expires.toUTCString()
: "",
options.path ? "; path=" + options.path : "",
options.domain ? "; domain=" + options.domain : "",
options.secure ? "; secure" : "",
"sameSite" in options
? "; sameSite=" + options.samesite
: "; sameSite=Lax",
].join("");
return value;
},
},
};
window.djdt = {
show_toolbar: djdt.show_toolbar,
hide_toolbar: djdt.hide_toolbar,
init: djdt.init,
close: djdt.hide_one_level,
cookie: djdt.cookie,
};
if (document.readyState !== "loading") {
djdt.init();
} else {
document.addEventListener("DOMContentLoaded", djdt.init);
}
+41
View File
@@ -0,0 +1,41 @@
const timingOffset = performance.timing.navigationStart,
timingEnd = performance.timing.loadEventEnd,
totalTime = timingEnd - timingOffset;
function getLeft(stat) {
return ((performance.timing[stat] - timingOffset) / (totalTime)) * 100.0;
}
function getCSSWidth(stat, endStat) {
let width = ((performance.timing[endStat] - performance.timing[stat]) / (totalTime)) * 100.0;
// Calculate relative percent (same as sql panel logic)
width = 100.0 * width / (100.0 - getLeft(stat));
return (width < 1) ? "2px" : width + "%";
}
function addRow(stat, endStat) {
const row = document.createElement('tr');
if (endStat) {
// Render a start through end bar
row.innerHTML = '<td>' + stat.replace('Start', '') + '</td>' +
'<td class="djdt-timeline"><svg class="djDebugLineChart" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 100 5" preserveAspectRatio="none"><rect y="0" height="5" fill="#ccc" /></svg></td>' +
'<td>' + (performance.timing[stat] - timingOffset) + ' (+' + (performance.timing[endStat] - performance.timing[stat]) + ')</td>';
row.querySelector('rect').setAttribute('width', getCSSWidth(stat, endStat));
} else {
// Render a point in time
row.innerHTML = '<td>' + stat + '</td>' +
'<td class="djdt-timeline"><svg class="djDebugLineChart" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 100 5" preserveAspectRatio="none"><rect y="0" height="5" fill="#ccc" /></svg></td>' +
'<td>' + (performance.timing[stat] - timingOffset) + '</td>';
row.querySelector('rect').setAttribute('width', 2);
}
row.querySelector('rect').setAttribute('x', getLeft(stat));
document.querySelector('#djDebugBrowserTimingTableBody').appendChild(row);
}
// This is a reasonably complete and ordered set of timing periods (2 params) and events (1 param)
addRow('domainLookupStart', 'domainLookupEnd');
addRow('connectStart', 'connectEnd');
addRow('requestStart', 'responseEnd'); // There is no requestEnd
addRow('responseStart', 'responseEnd');
addRow('domLoading', 'domComplete'); // Spans the events below
addRow('domInteractive');
addRow('domContentLoadedEventStart', 'domContentLoadedEventEnd');
addRow('loadEventStart', 'loadEventEnd');
document.querySelector('#djDebugBrowserTiming').classList.remove('djdt-hidden');
+92
View File
@@ -0,0 +1,92 @@
const $$ = {
on(root, eventName, selector, fn) {
root.addEventListener(eventName, function (event) {
const target = event.target.closest(selector);
if (root.contains(target)) {
fn.call(target, event);
}
});
},
show(element) {
element.classList.remove("djdt-hidden");
},
hide(element) {
element.classList.add("djdt-hidden");
},
toggle(element, value) {
if (value) {
$$.show(element);
} else {
$$.hide(element);
}
},
visible(element) {
return !element.classList.contains("djdt-hidden");
},
executeScripts(scripts) {
scripts.forEach(function (script) {
const el = document.createElement("script");
el.type = "module";
el.src = script;
el.async = true;
document.head.appendChild(el);
});
},
applyStyles(container) {
/*
* Given a container element, apply styles set via data-djdt-styles attribute.
* The format is data-djdt-styles="styleName1:value;styleName2:value2"
* The style names should use the CSSStyleDeclaration camel cased names.
*/
container
.querySelectorAll("[data-djdt-styles]")
.forEach(function (element) {
const styles = element.dataset.djdtStyles || "";
styles.split(";").forEach(function (styleText) {
const styleKeyPair = styleText.split(":");
if (styleKeyPair.length === 2) {
const name = styleKeyPair[0].trim();
const value = styleKeyPair[1].trim();
element.style[name] = value;
}
});
});
},
};
function ajax(url, init) {
init = Object.assign({ credentials: "same-origin" }, init);
return fetch(url, init)
.then(function (response) {
if (response.ok) {
return response.json();
}
return Promise.reject(
new Error(response.status + ": " + response.statusText)
);
})
.catch(function (error) {
const win = document.getElementById("djDebugWindow");
win.innerHTML =
'<div class="djDebugPanelTitle"><button type="button" class="djDebugClose">»</button><h3>' +
error.message +
"</h3></div>";
$$.show(win);
throw error;
});
}
function ajaxForm(element) {
const form = element.closest("form");
const url = new URL(form.action);
const formData = new FormData(form);
for (const [name, value] of formData.entries()) {
url.searchParams.append(name, value);
}
const ajaxData = {
method: form.method.toUpperCase(),
};
return ajax(url, ajaxData);
}
export { $$, ajax, ajaxForm };