|
|
|
/*
|
|
|
|
* Functionality for the CodeIgniter Debug Toolbar.
|
|
|
|
*/
|
|
|
|
|
|
|
|
var ciDebugBar = {
|
|
|
|
toolbarContainer: null,
|
|
|
|
toolbar: null,
|
|
|
|
icon: null,
|
|
|
|
|
|
|
|
init: function () {
|
|
|
|
this.toolbarContainer = document.getElementById("toolbarContainer");
|
|
|
|
this.toolbar = document.getElementById("debug-bar");
|
|
|
|
this.icon = document.getElementById("debug-icon");
|
|
|
|
|
|
|
|
ciDebugBar.createListeners();
|
|
|
|
ciDebugBar.setToolbarState();
|
|
|
|
ciDebugBar.setToolbarPosition();
|
|
|
|
ciDebugBar.setToolbarTheme();
|
|
|
|
ciDebugBar.toggleViewsHints();
|
|
|
|
ciDebugBar.routerLink();
|
|
|
|
ciDebugBar.setHotReloadState();
|
|
|
|
|
|
|
|
document
|
|
|
|
.getElementById("debug-bar-link")
|
|
|
|
.addEventListener("click", ciDebugBar.toggleToolbar, true);
|
|
|
|
document
|
|
|
|
.getElementById("debug-icon-link")
|
|
|
|
.addEventListener("click", ciDebugBar.toggleToolbar, true);
|
|
|
|
|
|
|
|
// Allows to highlight the row of the current history request
|
|
|
|
var btn = this.toolbar.querySelector(
|
|
|
|
'button[data-time="' + localStorage.getItem("debugbar-time") + '"]'
|
|
|
|
);
|
|
|
|
ciDebugBar.addClass(btn.parentNode.parentNode, "current");
|
|
|
|
|
|
|
|
historyLoad = this.toolbar.getElementsByClassName("ci-history-load");
|
|
|
|
|
|
|
|
for (var i = 0; i < historyLoad.length; i++) {
|
|
|
|
historyLoad[i].addEventListener(
|
|
|
|
"click",
|
|
|
|
function () {
|
|
|
|
loadDoc(this.getAttribute("data-time"));
|
|
|
|
},
|
|
|
|
true
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Display the active Tab on page load
|
|
|
|
var tab = ciDebugBar.readCookie("debug-bar-tab");
|
|
|
|
if (document.getElementById(tab)) {
|
|
|
|
var el = document.getElementById(tab);
|
|
|
|
ciDebugBar.switchClass(el, "debug-bar-ndisplay", "debug-bar-dblock");
|
|
|
|
ciDebugBar.addClass(el, "active");
|
|
|
|
tab = document.querySelector("[data-tab=" + tab + "]");
|
|
|
|
if (tab) {
|
|
|
|
ciDebugBar.addClass(tab.parentNode, "active");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
createListeners: function () {
|
|
|
|
var buttons = [].slice.call(
|
|
|
|
this.toolbar.querySelectorAll(".ci-label a")
|
|
|
|
);
|
|
|
|
|
|
|
|
for (var i = 0; i < buttons.length; i++) {
|
|
|
|
buttons[i].addEventListener("click", ciDebugBar.showTab, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Hook up generic toggle via data attributes `data-toggle="foo"`
|
|
|
|
var links = this.toolbar.querySelectorAll("[data-toggle]");
|
|
|
|
for (var i = 0; i < links.length; i++) {
|
|
|
|
let toggleData = links[i].getAttribute("data-toggle");
|
|
|
|
if (toggleData === "datatable") {
|
|
|
|
|
|
|
|
let datatable = links[i].getAttribute("data-table");
|
|
|
|
links[i].addEventListener("click", function() {
|
|
|
|
ciDebugBar.toggleDataTable(datatable)
|
|
|
|
}, true);
|
|
|
|
|
|
|
|
} else if (toggleData === "childrows") {
|
|
|
|
|
|
|
|
let child = links[i].getAttribute("data-child");
|
|
|
|
links[i].addEventListener("click", function() {
|
|
|
|
ciDebugBar.toggleChildRows(child)
|
|
|
|
}, true);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
links[i].addEventListener("click", ciDebugBar.toggleRows, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
showTab: function () {
|
|
|
|
// Get the target tab, if any
|
|
|
|
var tab = document.getElementById(this.getAttribute("data-tab"));
|
|
|
|
|
|
|
|
// If the label have not a tab stops here
|
|
|
|
if (! tab) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove debug-bar-tab cookie
|
|
|
|
ciDebugBar.createCookie("debug-bar-tab", "", -1);
|
|
|
|
|
|
|
|
// Check our current state.
|
|
|
|
var state = tab.classList.contains("debug-bar-dblock");
|
|
|
|
|
|
|
|
// Hide all tabs
|
|
|
|
var tabs = document.querySelectorAll("#debug-bar .tab");
|
|
|
|
|
|
|
|
for (var i = 0; i < tabs.length; i++) {
|
|
|
|
ciDebugBar.switchClass(tabs[i], "debug-bar-dblock", "debug-bar-ndisplay");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mark all labels as inactive
|
|
|
|
var labels = document.querySelectorAll("#debug-bar .ci-label");
|
|
|
|
|
|
|
|
for (var i = 0; i < labels.length; i++) {
|
|
|
|
ciDebugBar.removeClass(labels[i], "active");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Show/hide the selected tab
|
|
|
|
if (! state) {
|
|
|
|
ciDebugBar.switchClass(tab, "debug-bar-ndisplay", "debug-bar-dblock");
|
|
|
|
ciDebugBar.addClass(this.parentNode, "active");
|
|
|
|
// Create debug-bar-tab cookie to persistent state
|
|
|
|
ciDebugBar.createCookie(
|
|
|
|
"debug-bar-tab",
|
|
|
|
this.getAttribute("data-tab"),
|
|
|
|
365
|
|
|
|
);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
addClass: function (el, className) {
|
|
|
|
if (el.classList) {
|
|
|
|
el.classList.add(className);
|
|
|
|
} else {
|
|
|
|
el.className += " " + className;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
removeClass: function (el, className) {
|
|
|
|
if (el.classList) {
|
|
|
|
el.classList.remove(className);
|
|
|
|
} else {
|
|
|
|
el.className = el.className.replace(
|
|
|
|
new RegExp(
|
|
|
|
"(^|\\b)" + className.split(" ").join("|") + "(\\b|$)",
|
|
|
|
"gi"
|
|
|
|
),
|
|
|
|
" "
|
|
|
|
);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
switchClass : function(el, classFrom, classTo) {
|
|
|
|
ciDebugBar.removeClass(el, classFrom);
|
|
|
|
ciDebugBar.addClass(el, classTo);
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Toggle display of another object based on
|
|
|
|
* the data-toggle value of this object
|
|
|
|
*
|
|
|
|
* @param event
|
|
|
|
*/
|
|
|
|
toggleRows: function (event) {
|
|
|
|
if (event.target) {
|
|
|
|
let row = event.target.closest("tr");
|
|
|
|
let target = document.getElementById(
|
|
|
|
row.getAttribute("data-toggle")
|
|
|
|
);
|
|
|
|
|
|
|
|
if (target.classList.contains("debug-bar-ndisplay")) {
|
|
|
|
ciDebugBar.switchClass(target, "debug-bar-ndisplay", "debug-bar-dtableRow");
|
|
|
|
} else {
|
|
|
|
ciDebugBar.switchClass(target, "debug-bar-dtableRow", "debug-bar-ndisplay");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Toggle display of a data table
|
|
|
|
*
|
|
|
|
* @param obj
|
|
|
|
*/
|
|
|
|
toggleDataTable: function (obj) {
|
|
|
|
if (typeof obj == "string") {
|
|
|
|
obj = document.getElementById(obj + "_table");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (obj) {
|
|
|
|
if (obj.classList.contains("debug-bar-ndisplay")) {
|
|
|
|
ciDebugBar.switchClass(obj, "debug-bar-ndisplay", "debug-bar-dblock");
|
|
|
|
} else {
|
|
|
|
ciDebugBar.switchClass(obj, "debug-bar-dblock", "debug-bar-ndisplay");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Toggle display of timeline child elements
|
|
|
|
*
|
|
|
|
* @param obj
|
|
|
|
*/
|
|
|
|
toggleChildRows: function (obj) {
|
|
|
|
if (typeof obj == "string") {
|
|
|
|
par = document.getElementById(obj + "_parent");
|
|
|
|
obj = document.getElementById(obj + "_children");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (par && obj) {
|
|
|
|
|
|
|
|
if (obj.classList.contains("debug-bar-ndisplay")) {
|
|
|
|
ciDebugBar.removeClass(obj, "debug-bar-ndisplay");
|
|
|
|
} else {
|
|
|
|
ciDebugBar.addClass(obj, "debug-bar-ndisplay");
|
|
|
|
}
|
|
|
|
|
|
|
|
par.classList.toggle("timeline-parent-open");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Toggle tool bar from full to icon and icon to full
|
|
|
|
*/
|
|
|
|
toggleToolbar: function () {
|
|
|
|
var open = ! ciDebugBar.toolbar.classList.contains("debug-bar-ndisplay");
|
|
|
|
|
|
|
|
if (open) {
|
|
|
|
ciDebugBar.switchClass(ciDebugBar.icon, "debug-bar-ndisplay", "debug-bar-dinlineBlock");
|
|
|
|
ciDebugBar.switchClass(ciDebugBar.toolbar, "debug-bar-dinlineBlock", "debug-bar-ndisplay");
|
|
|
|
} else {
|
|
|
|
ciDebugBar.switchClass(ciDebugBar.icon, "debug-bar-dinlineBlock", "debug-bar-ndisplay");
|
|
|
|
ciDebugBar.switchClass(ciDebugBar.toolbar, "debug-bar-ndisplay", "debug-bar-dinlineBlock");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remember it for other page loads on this site
|
|
|
|
ciDebugBar.createCookie("debug-bar-state", "", -1);
|
|
|
|
ciDebugBar.createCookie(
|
|
|
|
"debug-bar-state",
|
|
|
|
open == true ? "minimized" : "open",
|
|
|
|
365
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the initial state of the toolbar (open or minimized) when
|
|
|
|
* the page is first loaded to allow it to remember the state between refreshes.
|
|
|
|
*/
|
|
|
|
setToolbarState: function () {
|
|
|
|
var open = ciDebugBar.readCookie("debug-bar-state");
|
|
|
|
|
|
|
|
if (open != "open") {
|
|
|
|
ciDebugBar.switchClass(ciDebugBar.icon, "debug-bar-ndisplay", "debug-bar-dinlineBlock");
|
|
|
|
ciDebugBar.switchClass(ciDebugBar.toolbar, "debug-bar-dinlineBlock", "debug-bar-ndisplay");
|
|
|
|
} else {
|
|
|
|
ciDebugBar.switchClass(ciDebugBar.icon, "debug-bar-dinlineBlock", "debug-bar-ndisplay");
|
|
|
|
ciDebugBar.switchClass(ciDebugBar.toolbar, "debug-bar-ndisplay", "debug-bar-dinlineBlock");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
toggleViewsHints: function () {
|
|
|
|
// Avoid toggle hints on history requests that are not the initial
|
|
|
|
if (
|
|
|
|
localStorage.getItem("debugbar-time") !=
|
|
|
|
localStorage.getItem("debugbar-time-new")
|
|
|
|
) {
|
|
|
|
var a = document.querySelector('a[data-tab="ci-views"]');
|
|
|
|
a.href = "#";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var nodeList = []; // [ Element, NewElement( 1 )/OldElement( 0 ) ]
|
|
|
|
var sortedComments = [];
|
|
|
|
var comments = [];
|
|
|
|
|
|
|
|
var getComments = function () {
|
|
|
|
var nodes = [];
|
|
|
|
var result = [];
|
|
|
|
var xpathResults = document.evaluate(
|
|
|
|
"//comment()[starts-with(., ' DEBUG-VIEW')]",
|
|
|
|
document,
|
|
|
|
null,
|
|
|
|
XPathResult.ANY_TYPE,
|
|
|
|
null
|
|
|
|
);
|
|
|
|
var nextNode = xpathResults.iterateNext();
|
|
|
|
while (nextNode) {
|
|
|
|
nodes.push(nextNode);
|
|
|
|
nextNode = xpathResults.iterateNext();
|
|
|
|
}
|
|
|
|
|
|
|
|
// sort comment by opening and closing tags
|
|
|
|
for (var i = 0; i < nodes.length; ++i) {
|
|
|
|
// get file path + name to use as key
|
|
|
|
var path = nodes[i].nodeValue.substring(
|
|
|
|
18,
|
|
|
|
nodes[i].nodeValue.length - 1
|
|
|
|
);
|
|
|
|
|
|
|
|
if (nodes[i].nodeValue[12] === "S") {
|
|
|
|
// simple check for start comment
|
|
|
|
// create new entry
|
|
|
|
result[path] = [nodes[i], null];
|
|
|
|
} else if (result[path]) {
|
|
|
|
// add to existing entry
|
|
|
|
result[path][1] = nodes[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
|
|
|
|
// find node that has TargetNode as parentNode
|
|
|
|
var getParentNode = function (node, targetNode) {
|
|
|
|
if (node.parentNode === null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (node.parentNode !== targetNode) {
|
|
|
|
return getParentNode(node.parentNode, targetNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
return node;
|
|
|
|
};
|
|
|
|
|
|
|
|
// define invalid & outer ( also invalid ) elements
|
|
|
|
const INVALID_ELEMENTS = ["NOSCRIPT", "SCRIPT", "STYLE"];
|
|
|
|
const OUTER_ELEMENTS = ["HTML", "BODY", "HEAD"];
|
|
|
|
|
|
|
|
var getValidElementInner = function (node, reverse) {
|
|
|
|
// handle invalid tags
|
|
|
|
if (OUTER_ELEMENTS.indexOf(node.nodeName) !== -1) {
|
|
|
|
for (var i = 0; i < document.body.children.length; ++i) {
|
|
|
|
var index = reverse
|
|
|
|
? document.body.children.length - (i + 1)
|
|
|
|
: i;
|
|
|
|
var element = document.body.children[index];
|
|
|
|
|
|
|
|
// skip invalid tags
|
|
|
|
if (INVALID_ELEMENTS.indexOf(element.nodeName) !== -1) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return [element, reverse];
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get to next valid element
|
|
|
|
while (
|
|
|
|
node !== null &&
|
|
|
|
INVALID_ELEMENTS.indexOf(node.nodeName) !== -1
|
|
|
|
) {
|
|
|
|
node = reverse
|
|
|
|
? node.previousElementSibling
|
|
|
|
: node.nextElementSibling;
|
|
|
|
}
|
|
|
|
|
|
|
|
// return non array if we couldnt find something
|
|
|
|
if (node === null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return [node, reverse];
|
|
|
|
};
|
|
|
|
|
|
|
|
// get next valid element ( to be safe to add divs )
|
|
|
|
// @return [ element, skip element ] or null if we couldnt find a valid place
|
|
|
|
var getValidElement = function (nodeElement) {
|
|
|
|
if (nodeElement) {
|
|
|
|
if (nodeElement.nextElementSibling !== null) {
|
|
|
|
return (
|
|
|
|
getValidElementInner(
|
|
|
|
nodeElement.nextElementSibling,
|
|
|
|
false
|
|
|
|
) ||
|
|
|
|
getValidElementInner(
|
|
|
|
nodeElement.previousElementSibling,
|
|
|
|
true
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (nodeElement.previousElementSibling !== null) {
|
|
|
|
return getValidElementInner(
|
|
|
|
nodeElement.previousElementSibling,
|
|
|
|
true
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// something went wrong! -> element is not in DOM
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
|
|
|
function showHints() {
|
|
|
|
// Had AJAX? Reset view blocks
|
|
|
|
sortedComments = getComments();
|
|
|
|
|
|
|
|
for (var key in sortedComments) {
|
|
|
|
var startElement = getValidElement(sortedComments[key][0]);
|
|
|
|
var endElement = getValidElement(sortedComments[key][1]);
|
|
|
|
|
|
|
|
// skip if we couldnt get a valid element
|
|
|
|
if (startElement === null || endElement === null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// find element which has same parent as startelement
|
|
|
|
var jointParent = getParentNode(
|
|
|
|
endElement[0],
|
|
|
|
startElement[0].parentNode
|
|
|
|
);
|
|
|
|
if (jointParent === null) {
|
|
|
|
// find element which has same parent as endelement
|
|
|
|
jointParent = getParentNode(
|
|
|
|
startElement[0],
|
|
|
|
endElement[0].parentNode
|
|
|
|
);
|
|
|
|
if (jointParent === null) {
|
|
|
|
// both tries failed
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
startElement[0] = jointParent;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
endElement[0] = jointParent;
|
|
|
|
}
|
|
|
|
|
|
|
|
var debugDiv = document.createElement("div"); // holder
|
|
|
|
var debugPath = document.createElement("div"); // path
|
|
|
|
var childArray = startElement[0].parentNode.childNodes; // target child array
|
|
|
|
var parent = startElement[0].parentNode;
|
|
|
|
var start, end;
|
|
|
|
|
|
|
|
// setup container
|
|
|
|
debugDiv.classList.add("debug-view");
|
|
|
|
debugDiv.classList.add("show-view");
|
|
|
|
debugPath.classList.add("debug-view-path");
|
|
|
|
debugPath.innerText = key;
|
|
|
|
debugDiv.appendChild(debugPath);
|
|
|
|
|
|
|
|
// calc distance between them
|
|
|
|
// start
|
|
|
|
for (var i = 0; i < childArray.length; ++i) {
|
|
|
|
// check for comment ( start & end ) -> if its before valid start element
|
|
|
|
if (
|
|
|
|
childArray[i] === sortedComments[key][1] ||
|
|
|
|
childArray[i] === sortedComments[key][0] ||
|
|
|
|
childArray[i] === startElement[0]
|
|
|
|
) {
|
|
|
|
start = i;
|
|
|
|
if (childArray[i] === sortedComments[key][0]) {
|
|
|
|
start++; // increase to skip the start comment
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// adjust if we want to skip the start element
|
|
|
|
if (startElement[1]) {
|
|
|
|
start++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// end
|
|
|
|
for (var i = start; i < childArray.length; ++i) {
|
|
|
|
if (childArray[i] === endElement[0]) {
|
|
|
|
end = i;
|
|
|
|
// dont break to check for end comment after end valid element
|
|
|
|
} else if (childArray[i] === sortedComments[key][1]) {
|
|
|
|
// if we found the end comment, we can break
|
|
|
|
end = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// move elements
|
|
|
|
var number = end - start;
|
|
|
|
if (endElement[1]) {
|
|
|
|
number++;
|
|
|
|
}
|
|
|
|
for (var i = 0; i < number; ++i) {
|
|
|
|
if (INVALID_ELEMENTS.indexOf(childArray[start]) !== -1) {
|
|
|
|
// skip invalid childs that can cause problems if moved
|
|
|
|
start++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
debugDiv.appendChild(childArray[start]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// add container to DOM
|
|
|
|
nodeList.push(parent.insertBefore(debugDiv, childArray[start]));
|
|
|
|
}
|
|
|
|
|
|
|
|
ciDebugBar.createCookie("debug-view", "show", 365);
|
|
|
|
ciDebugBar.addClass(btn, "active");
|
|
|
|
}
|
|
|
|
|
|
|
|
function hideHints() {
|
|
|
|
for (var i = 0; i < nodeList.length; ++i) {
|
|
|
|
var index;
|
|
|
|
|
|
|
|
// find index
|
|
|
|
for (
|
|
|
|
var j = 0;
|
|
|
|
j < nodeList[i].parentNode.childNodes.length;
|
|
|
|
++j
|
|
|
|
) {
|
|
|
|
if (nodeList[i].parentNode.childNodes[j] === nodeList[i]) {
|
|
|
|
index = j;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// move child back
|
|
|
|
while (nodeList[i].childNodes.length !== 1) {
|
|
|
|
nodeList[i].parentNode.insertBefore(
|
|
|
|
nodeList[i].childNodes[1],
|
|
|
|
nodeList[i].parentNode.childNodes[index].nextSibling
|
|
|
|
);
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
nodeList[i].parentNode.removeChild(nodeList[i]);
|
|
|
|
}
|
|
|
|
nodeList.length = 0;
|
|
|
|
|
|
|
|
ciDebugBar.createCookie("debug-view", "", -1);
|
|
|
|
ciDebugBar.removeClass(btn, "active");
|
|
|
|
}
|
|
|
|
|
|
|
|
var btn = document.querySelector("[data-tab=ci-views]");
|
|
|
|
|
|
|
|
// If the Views Collector is inactive stops here
|
|
|
|
if (! btn) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
btn.parentNode.onclick = function () {
|
|
|
|
if (ciDebugBar.readCookie("debug-view")) {
|
|
|
|
hideHints();
|
|
|
|
} else {
|
|
|
|
showHints();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Determine Hints state on page load
|
|
|
|
if (ciDebugBar.readCookie("debug-view")) {
|
|
|
|
showHints();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
setToolbarPosition: function () {
|
|
|
|
var btnPosition = this.toolbar.querySelector("#toolbar-position");
|
|
|
|
|
|
|
|
if (ciDebugBar.readCookie("debug-bar-position") === "top") {
|
|
|
|
ciDebugBar.addClass(ciDebugBar.icon, "fixed-top");
|
|
|
|
ciDebugBar.addClass(ciDebugBar.toolbar, "fixed-top");
|
|
|
|
}
|
|
|
|
|
|
|
|
btnPosition.addEventListener(
|
|
|
|
"click",
|
|
|
|
function () {
|
|
|
|
var position = ciDebugBar.readCookie("debug-bar-position");
|
|
|
|
|
|
|
|
ciDebugBar.createCookie("debug-bar-position", "", -1);
|
|
|
|
|
|
|
|
if (! position || position === "bottom") {
|
|
|
|
ciDebugBar.createCookie("debug-bar-position", "top", 365);
|
|
|
|
ciDebugBar.addClass(ciDebugBar.icon, "fixed-top");
|
|
|
|
ciDebugBar.addClass(ciDebugBar.toolbar, "fixed-top");
|
|
|
|
} else {
|
|
|
|
ciDebugBar.createCookie(
|
|
|
|
"debug-bar-position",
|
|
|
|
"bottom",
|
|
|
|
365
|
|
|
|
);
|
|
|
|
ciDebugBar.removeClass(ciDebugBar.icon, "fixed-top");
|
|
|
|
ciDebugBar.removeClass(ciDebugBar.toolbar, "fixed-top");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
true
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
|
|
|
setToolbarTheme: function () {
|
|
|
|
var btnTheme = this.toolbar.querySelector("#toolbar-theme");
|
|
|
|
var isDarkMode = window.matchMedia(
|
|
|
|
"(prefers-color-scheme: dark)"
|
|
|
|
).matches;
|
|
|
|
var isLightMode = window.matchMedia(
|
|
|
|
"(prefers-color-scheme: light)"
|
|
|
|
).matches;
|
|
|
|
|
|
|
|
// If a cookie is set with a value, we force the color scheme
|
|
|
|
if (ciDebugBar.readCookie("debug-bar-theme") === "dark") {
|
|
|
|
ciDebugBar.removeClass(ciDebugBar.toolbarContainer, "light");
|
|
|
|
ciDebugBar.addClass(ciDebugBar.toolbarContainer, "dark");
|
|
|
|
} else if (ciDebugBar.readCookie("debug-bar-theme") === "light") {
|
|
|
|
ciDebugBar.removeClass(ciDebugBar.toolbarContainer, "dark");
|
|
|
|
ciDebugBar.addClass(ciDebugBar.toolbarContainer, "light");
|
|
|
|
}
|
|
|
|
|
|
|
|
btnTheme.addEventListener(
|
|
|
|
"click",
|
|
|
|
function () {
|
|
|
|
var theme = ciDebugBar.readCookie("debug-bar-theme");
|
|
|
|
|
|
|
|
if (
|
|
|
|
! theme &&
|
|
|
|
window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
|
|
) {
|
|
|
|
// If there is no cookie, and "prefers-color-scheme" is set to "dark"
|
|
|
|
// It means that the user wants to switch to light mode
|
|
|
|
ciDebugBar.createCookie("debug-bar-theme", "light", 365);
|
|
|
|
ciDebugBar.removeClass(ciDebugBar.toolbarContainer, "dark");
|
|
|
|
ciDebugBar.addClass(ciDebugBar.toolbarContainer, "light");
|
|
|
|
} else {
|
|
|
|
if (theme === "dark") {
|
|
|
|
ciDebugBar.createCookie(
|
|
|
|
"debug-bar-theme",
|
|
|
|
"light",
|
|
|
|
365
|
|
|
|
);
|
|
|
|
ciDebugBar.removeClass(
|
|
|
|
ciDebugBar.toolbarContainer,
|
|
|
|
"dark"
|
|
|
|
);
|
|
|
|
ciDebugBar.addClass(
|
|
|
|
ciDebugBar.toolbarContainer,
|
|
|
|
"light"
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
// In any other cases: if there is no cookie, or the cookie is set to
|
|
|
|
// "light", or the "prefers-color-scheme" is "light"...
|
|
|
|
ciDebugBar.createCookie("debug-bar-theme", "dark", 365);
|
|
|
|
ciDebugBar.removeClass(
|
|
|
|
ciDebugBar.toolbarContainer,
|
|
|
|
"light"
|
|
|
|
);
|
|
|
|
ciDebugBar.addClass(
|
|
|
|
ciDebugBar.toolbarContainer,
|
|
|
|
"dark"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
true
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
|
|
|
setHotReloadState: function () {
|
|
|
|
var btn = document.getElementById("debug-hot-reload").parentNode;
|
|
|
|
var btnImg = btn.getElementsByTagName("img")[0];
|
|
|
|
var eventSource;
|
|
|
|
|
|
|
|
// If the Hot Reload Collector is inactive stops here
|
|
|
|
if (! btn) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
btn.onclick = function () {
|
|
|
|
if (ciDebugBar.readCookie("debug-hot-reload")) {
|
|
|
|
ciDebugBar.createCookie("debug-hot-reload", "", -1);
|
|
|
|
ciDebugBar.removeClass(btn, "active");
|
|
|
|
ciDebugBar.removeClass(btnImg, "rotate");
|
|
|
|
|
|
|
|
// Close the EventSource connection if it exists
|
|
|
|
if (typeof eventSource !== "undefined") {
|
|
|
|
eventSource.close();
|
|
|
|
eventSource = void 0; // Undefine the variable
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ciDebugBar.createCookie("debug-hot-reload", "show", 365);
|
|
|
|
ciDebugBar.addClass(btn, "active");
|
|
|
|
ciDebugBar.addClass(btnImg, "rotate");
|
|
|
|
|
|
|
|
eventSource = ciDebugBar.hotReloadConnect();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Determine Hot Reload state on page load
|
|
|
|
if (ciDebugBar.readCookie("debug-hot-reload")) {
|
|
|
|
ciDebugBar.addClass(btn, "active");
|
|
|
|
ciDebugBar.addClass(btnImg, "rotate");
|
|
|
|
eventSource = ciDebugBar.hotReloadConnect();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
hotReloadConnect: function () {
|
|
|
|
const eventSource = new EventSource(ciSiteURL + "/__hot-reload");
|
|
|
|
|
|
|
|
eventSource.addEventListener("reload", function (e) {
|
|
|
|
console.log("reload", e);
|
|
|
|
window.location.reload();
|
|
|
|
});
|
|
|
|
|
|
|
|
eventSource.onerror = (err) => {
|
|
|
|
console.error("EventSource failed:", err);
|
|
|
|
};
|
|
|
|
|
|
|
|
return eventSource;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper to create a cookie.
|
|
|
|
*
|
|
|
|
* @param name
|
|
|
|
* @param value
|
|
|
|
* @param days
|
|
|
|
*/
|
|
|
|
createCookie: function (name, value, days) {
|
|
|
|
if (days) {
|
|
|
|
var date = new Date();
|
|
|
|
|
|
|
|
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
|
|
|
|
|
|
|
|
var expires = "; expires=" + date.toGMTString();
|
|
|
|
} else {
|
|
|
|
var expires = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
document.cookie =
|
|
|
|
name + "=" + value + expires + "; path=/; samesite=Lax";
|
|
|
|
},
|
|
|
|
|
|
|
|
readCookie: function (name) {
|
|
|
|
var nameEQ = name + "=";
|
|
|
|
var ca = document.cookie.split(";");
|
|
|
|
|
|
|
|
for (var i = 0; i < ca.length; i++) {
|
|
|
|
var c = ca[i];
|
|
|
|
while (c.charAt(0) == " ") {
|
|
|
|
c = c.substring(1, c.length);
|
|
|
|
}
|
|
|
|
if (c.indexOf(nameEQ) == 0) {
|
|
|
|
return c.substring(nameEQ.length, c.length);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
|
|
|
|
trimSlash: function (text) {
|
|
|
|
return text.replace(/^\/|\/$/g, "");
|
|
|
|
},
|
|
|
|
|
|
|
|
routerLink: function () {
|
|
|
|
var row, _location;
|
|
|
|
var rowGet = this.toolbar.querySelectorAll(
|
|
|
|
'td[data-debugbar-route="GET"]'
|
|
|
|
);
|
|
|
|
var patt = /\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)/;
|
|
|
|
|
|
|
|
for (var i = 0; i < rowGet.length; i++) {
|
|
|
|
row = rowGet[i];
|
|
|
|
if (!/\/\(.+?\)/.test(rowGet[i].innerText)) {
|
|
|
|
ciDebugBar.addClass(row, "debug-bar-pointer");
|
|
|
|
row.setAttribute(
|
|
|
|
"title",
|
|
|
|
location.origin + "/" + ciDebugBar.trimSlash(row.innerText)
|
|
|
|
);
|
|
|
|
row.addEventListener("click", function (ev) {
|
|
|
|
_location =
|
|
|
|
location.origin +
|
|
|
|
"/" +
|
|
|
|
ciDebugBar.trimSlash(ev.target.innerText);
|
|
|
|
var redirectWindow = window.open(_location, "_blank");
|
|
|
|
redirectWindow.location;
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
row.innerHTML =
|
|
|
|
"<div>" +
|
|
|
|
row.innerText +
|
|
|
|
"</div>" +
|
|
|
|
'<form data-debugbar-route-tpl="' +
|
|
|
|
ciDebugBar.trimSlash(row.innerText.replace(patt, "?")) +
|
|
|
|
'">' +
|
|
|
|
row.innerText.replace(
|
|
|
|
patt,
|
|
|
|
'<input type="text" placeholder="$1">'
|
|
|
|
) +
|
|
|
|
'<input type="submit" value="Go" class="debug-bar-mleft4">' +
|
|
|
|
"</form>";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rowGet = this.toolbar.querySelectorAll(
|
|
|
|
'td[data-debugbar-route="GET"] form'
|
|
|
|
);
|
|
|
|
for (var i = 0; i < rowGet.length; i++) {
|
|
|
|
row = rowGet[i];
|
|
|
|
|
|
|
|
row.addEventListener("submit", function (event) {
|
|
|
|
event.preventDefault();
|
|
|
|
var inputArray = [],
|
|
|
|
t = 0;
|
|
|
|
var input = event.target.querySelectorAll("input[type=text]");
|
|
|
|
var tpl = event.target.getAttribute("data-debugbar-route-tpl");
|
|
|
|
|
|
|
|
for (var n = 0; n < input.length; n++) {
|
|
|
|
if (input[n].value.length > 0) {
|
|
|
|
inputArray.push(input[n].value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (inputArray.length > 0) {
|
|
|
|
_location =
|
|
|
|
location.origin +
|
|
|
|
"/" +
|
|
|
|
tpl.replace(/\?/g, function () {
|
|
|
|
return inputArray[t++];
|
|
|
|
});
|
|
|
|
|
|
|
|
var redirectWindow = window.open(_location, "_blank");
|
|
|
|
redirectWindow.location;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
};
|