diff --git a/tracer/tracer_event.js b/tracer/tracer_event.js
index 9bba2cea..731018b8 100644
--- a/tracer/tracer_event.js
+++ b/tracer/tracer_event.js
@@ -1,7 +1,9 @@
//TODO: remove jQuery
+console.log("PDT: tracer/tracer_event.js");
+PDT.setScriptsApplied();
-//FEATURE: Mark row on right-click
-$("div#traceEvent-CONTAINER").on("contextmenu", "td#eventLineNumber", function (evt) { evt.preventDefault(); $(this).parent().toggleClass("PegaDevToolsTextRed"); });
+// //FEATURE: Mark row on right-click
+// $("div#traceEvent-CONTAINER").on("contextmenu", "td#eventLineNumber", function (evt) { evt.preventDefault(); $(this).parent().toggleClass("PegaDevToolsTextRed"); });
//FEATURE: Remove columns
const removeThreadNameButton = $('x ');
@@ -37,4 +39,147 @@ removeAllColumnsBtn.click(function () {
$('span.removeColumn').click();
this.remove();
});
-$('td.eventTitleBarStyle[title="Line"]').prev().append(removeAllColumnsBtn);
\ No newline at end of file
+$('td.eventTitleBarStyle[title="Line"]').prev().append(removeAllColumnsBtn);
+
+const menuLineNumberStructure = [
+ {
+ text: " ⚐ Mark",
+ action: () => {
+ contextTarget.parentNode.classList.toggle("PegaDevToolsTextRed")
+ }
+ },
+ {
+ text: "🔖 Add to bookmarks",
+ action: () => {
+ contextTarget.parentNode.classList.toggle("PegaDevToolsTextBlue");
+ contextTarget.setAttribute("data-PDTbookmark", true);
+
+ let bookmarksButton = window.parent.frames[0].document.querySelector("div.btnPDTGroup.greyPDT");
+ bookmarksButton.classList.remove("initiallyHidden");
+
+ let newTextContent = "Bookmarks";
+ if (bookmarksButton.getAttribute("data-count")) {
+ newTextContent = "Bookmarks" + String.fromCharCode(160);
+ newTextContent += "" + document.querySelectorAll("td[data-PDTbookmark]").length;
+ }
+ bookmarksButton.querySelector("button#btnPDTBookmarks").textContent = newTextContent;
+ }
+ },
+ { isDivider: true },
+ {
+ text: "⇑ Remove next events",
+ action: () => {
+ let eventNumber = parseInt(contextTarget.getAttribute("title"));
+ document.querySelectorAll('tr#eventRow').forEach( row => { if(parseInt(row.querySelector("td#eventLineNumber").getAttribute("title")) > eventNumber) row.remove() });
+ }
+ },
+ {
+ text: "⇓ Remove previous events",
+ action: () => {
+ let eventNumber = parseInt(contextTarget.getAttribute("title"));
+ document.querySelectorAll('tr#eventRow').forEach( row => { if(parseInt(row.querySelector("td#eventLineNumber").getAttribute("title")) < eventNumber) row.remove() });
+ }
+ },
+ { isDivider: true },
+ {
+ text: "☓ Close this menu",
+ action: () => { /* empty action just closes menu */ }
+ }
+];
+
+const menuInstanceNameStructure = [
+ {
+ text: "↪ Jump to",
+ subMenu: [
+ {
+ text: "↟ Last occurrence",
+ action: () => {
+ let eventInstance = contextTarget.title;
+ let instancesByTitle = document.querySelector("td#elementInstanceName[title='" + eventInstance + "']");
+ instancesByTitle.scrollIntoView(false);
+ }
+ },
+ {
+ text: "↟ Last step (if applicable)",
+ action: () => {
+ let tmpNodeList = contextTarget.parentElement.querySelectorAll("td.eventDataCenter");
+ let ruleNo = tmpNodeList[tmpNodeList.length-1].getAttribute("title");
+ let instancesByRuleNo = document.querySelector("td.eventDataCenter[title='" + ruleNo + "']");
+ instancesByRuleNo.scrollIntoView(false);
+ }
+ },
+ {
+ text: "↡ First occurrence",
+ action: () => {
+ let eventInstance = contextTarget.title;
+ let instancesByTitle = document.querySelectorAll("td#elementInstanceName[title='" + eventInstance + "']");
+ instancesByTitle[instancesByTitle.length - 1].scrollIntoView(false);
+ }
+ },
+ {
+ text: "↡ First step (if applicable)",
+ action: () => {
+ let tmpNodeList = contextTarget.parentElement.querySelectorAll("td.eventDataCenter");
+ let ruleNo = tmpNodeList[tmpNodeList.length-1].getAttribute("title");
+ let instancesByRuleNo = document.querySelectorAll("td.eventDataCenter[title='" + ruleNo + "']");
+ instancesByRuleNo[instancesByRuleNo.length - 1].scrollIntoView(false);
+ }
+ }
+ ]
+ },
+ {
+ text: "☖ Highlight all occurrences",
+ action: () => {
+ let color = getEventElementDataSelectColor();
+ let instanceName = contextTarget.getAttribute("title");
+ document.querySelectorAll("td.eventElementDataSelect[title='" + instanceName + "']").forEach( row => row.style.backgroundColor = color );
+ }
+ },
+ {
+ text: "🗑 Remove all occurrences",
+ action: () => {
+ let instanceName = contextTarget.getAttribute("title");
+ document.querySelectorAll('tr#eventRow').forEach( row => {
+ let eventElement = row.querySelector("td.eventElementDataSelect");
+ if(eventElement && eventElement.hasAttribute("title") && eventElement.getAttribute("title") == instanceName)
+ row.remove()
+ });
+ }
+ },
+ { isDivider: true },
+ {
+ text: "☓ Close this menu",
+ action: () => { /* empty action just closes menu */ }
+ }
+];
+
+let contextTarget;
+
+//FEATURE: menus
+$("div#traceEvent-CONTAINER").on(
+ "contextmenu",
+ "td#eventLineNumber",
+ function (evt) {
+ evt.preventDefault();
+ contextTarget = this;
+ ctxmenu.show(menuLineNumberStructure, evt);
+}).on(
+ "contextmenu",
+ "td#elementInstanceName",
+ function (evt) {
+ evt.preventDefault();
+ contextTarget = this;
+ ctxmenu.show(menuInstanceNameStructure, evt);
+});
+
+const eventElementDataSelectColors = ["PeachPuff", "lavender", "PaleGreen", "#C0448f", "#FFFACD", "#E0FFFF", "#FFD700", "#FFE1FF", "#FF8C69"];
+let currentColorIndex = 0;
+
+function getEventElementDataSelectColor() {
+ let returnColor = eventElementDataSelectColors[currentColorIndex];
+ currentColorIndex++;
+ if(currentColorIndex == eventElementDataSelectColors.length) {
+ currentColorIndex = 0;
+ }
+ return returnColor;
+}
diff --git a/tracer/tracer_menuRow.js b/tracer/tracer_menuRow.js
index 7ff4a74f..ac911ac3 100644
--- a/tracer/tracer_menuRow.js
+++ b/tracer/tracer_menuRow.js
@@ -1,292 +1,418 @@
/* tracer - top menu iframe */
+document.arrive("body#main", { onceOnly: true, existing: true}, () => {
+ PDT.setScriptsApplied();
+ console.log("[PDT] tracer/tracer_menuRow.js");
+
+ function isTracerActive() {
+ return (
+ document.getElementById("Pause") &&
+ document.getElementById("Pause").innerText == "Pause"
+ );
+ }
+ var titleTimerId;
+ var counter = 0;
+
+ async function backgroundNotify(state) {
+ if (PDT.settings.debug) {
+ browser.runtime.sendMessage({ purpose: "tracerState", tracerIsOn: state });
+ }
+ }
-function isTracerActive() {
- return (
- document.getElementById("Pause") &&
- document.getElementById("Pause").innerText == "Pause"
- );
-}
-var titleTimerId;
-var counter = 0;
-
-async function backgroundNotify(state) {
- if (PDT.settings.debug) {
- browser.runtime.sendMessage({ purpose: "tracerState", tracerIsOn: state });
+ async function backgroundHeartbeat() {
+ if (PDT.settings.debug) {
+ browser.runtime.sendMessage({ purpose: "tracerHeartbeat" });
+ console.log("PDT sending heartbeat " + Math.floor(Date.now() / 1000));
+ }
}
-}
-async function backgroundHeartbeat() {
- if (PDT.settings.debug) {
- browser.runtime.sendMessage({ purpose: "tracerHeartbeat" });
- console.log("PDT sending heartbeat " + Math.floor(Date.now() / 1000));
+ async function updateCounts() {
+ updateMessageCount(getMessagesList().length);
+ updateErrorCount(getErrorList().length);
}
-}
-
-async function updateCounts() {
- updateMessageCount(getMessagesList().length);
- updateErrorCount(getErrorList().length);
-}
-
-async function resetCounts() {
- updateMessageCount();
- updateErrorCount();
-}
-
-function setTitle() {
- if (isTracerActive()) {
- parent.document.title = "ıı Tracer Off";
- clearInterval(titleTimerId);
- backgroundNotify(false);
- updateCounts();
- } else {
- parent.document.title = "Tracer Active!";
- backgroundHeartbeat();
- backgroundNotify(true);
- resetCounts();
-
- titleTimerId = setInterval(function () {
- parent.document.title = "►" + parent.document.title;
- counter++;
- if (counter % 2 == 0) {
- parent.document.title = "Tracer Active!";
- }
+
+ async function resetCounts() {
+ updateMessageCount();
+ updateErrorCount();
+ }
+
+ function setTitle() {
+ if (isTracerActive()) {
+ parent.document.title = "ıı Tracer Off";
+ clearInterval(titleTimerId);
+ backgroundNotify(false);
+ updateCounts();
+ } else {
+ parent.document.title = "Tracer Active!";
backgroundHeartbeat();
- }, 1000);
+ backgroundNotify(true);
+ resetCounts();
+
+ titleTimerId = setInterval(function () {
+ parent.document.title = "►" + parent.document.title;
+ counter++;
+ if (counter % 2 == 0) {
+ parent.document.title = "Tracer Active!";
+ }
+ backgroundHeartbeat();
+ }, 1000);
+ }
}
-}
-
-var errorIndex = 0,
- messageIndex = 0,
- accessDeniedIndex;
-var errorList = [],
- messagesList = [],
- accessDeniedList = [];
-
-function getErrorList() {
- return window.parent.frames[1].document.querySelectorAll(
- 'td[title="FAIL"], td[title="Exception"], tr.eventTableAlertTrace td.eventElementData'
- );
-}
-
-function getMessagesList() {
- return window.parent.frames[1].document.querySelectorAll(
- 'td[bgcolor="orange"], td[title="WARN"]'
- );
-}
-
-function getAccessDeniedList() {
- return window.parent.frames[1].document.querySelectorAll(
- 'td[title="Access Denied"]'
- );
-}
-
-function updateErrorCount(count, index) {
- let newTextContent = "Errors";
- if (!(count === undefined)) {
- newTextContent = "Errors" + String.fromCharCode(160);
- if (index) newTextContent += "" + index + "/" + count;
- else newTextContent += "" + count;
+
+ var errorIndex = 0,
+ messageIndex = 0,
+ accessDeniedIndex,
+ bookmarkIndex = 1;
+ var errorList = [],
+ messagesList = [],
+ accessDeniedList = [],
+ bookmarkList = [];
+
+ function getErrorList() {
+ return window.parent.frames[1].document.querySelectorAll(
+ 'td[title="FAIL"], td[title="Exception"], tr.eventTableAlertTrace td#eventNodeId'
+ );
}
- document.querySelector("button#btnPDTErrors").textContent = newTextContent;
-}
-
-function updateMessageCount(count, index) {
- let newTextContent = "Warnings";
- if (count !== undefined) {
- newTextContent = "Warnings" + String.fromCharCode(160);
- if (index) newTextContent += "" + index + "/" + count;
- else newTextContent += "" + count;
+
+ function getMessagesList() {
+ return window.parent.frames[1].document.querySelectorAll(
+ 'td[bgcolor="orange"], td[title="WARN"]'
+ );
}
- document.querySelector("button#btnPDTMessages").textContent = newTextContent;
-}
-
-function updateAccessDeniedCount(count) {
- document.querySelector("button#btnPDTAccessDenied").textContent =
- " AccessDeny(" + count + ")";
-}
-
-//TODO: convert to use PDT.settings
-function siteConfigCallback(siteConfig, _globalConfig) {
- if (!PDT.isTracerEnabled()) {
- console.log("PDT tracer disabled");
- } else {
- console.log("PDT tracer");
- messageServiceWorker("registerTracer"); //register with Service Worker
-
- if (siteConfig && siteConfig.label) {
- let headerButtonsElement = document.querySelector("table.tracertop tr");
- if (headerButtonsElement) {
- headerButtonsElement.insertAdjacentHTML(
- "beforeend",
- "" +
- siteConfig.label +
- " td>"
- );
- }
- if (siteConfig.useColorTop) {
- document.querySelector("table.tracertop").style.cssText =
- "border-top: #" + siteConfig.color.replace("#", "") + " 2px solid";
- }
+ function getAccessDeniedList() {
+ return window.parent.frames[1].document.querySelectorAll(
+ 'td[title="Access Denied"]'
+ );
+ }
+
+ function getBookmarksList() {
+ return window.parent.frames[1].document.querySelectorAll(
+ 'td[data-PDTbookmark]'
+ );
+ }
+
+ function updateErrorCount(count, index) {
+ let newTextContent = "Errors";
+ if (count !== undefined) {
+ newTextContent = "Errors" + String.fromCharCode(160);
+ if (index) newTextContent += "" + index + "/" + count;
+ else newTextContent += "" + count;
}
- $("#Pause").click(function () {
- setTitle();
- });
+ document.querySelector("button#btnPDTErrors").textContent = newTextContent;
+ }
- $("#ClearEvents").click(function () {
- resetCounts();
- });
+ function updateMessageCount(count, index) {
+ let newTextContent = "Warnings";
+ if (count !== undefined) {
+ newTextContent = "Warnings" + String.fromCharCode(160);
+ if (index) newTextContent += "" + index + "/" + count;
+ else newTextContent += "" + count;
+ }
+ document.querySelector("button#btnPDTMessages").textContent = newTextContent;
+ }
- //TODO: get rid of jQuery, use fetch API
- $.get(browser.runtime.getURL("tracer/tracer_button.html"), function (data) {
- //add buttons from html
- $("table.tracertop table tr").eq(2).prepend(data);
+ function updateButtonCount(buttonElement, text, count, index) {
+ if (count !== undefined) {
+ text = text + String.fromCharCode(160);
+ if (index) text += "" + index + "/" + count;
+ else text += "" + count;
+ }
+ buttonElement.textContent = text;
+ }
- waitUntilRenderTracerButtons();
- });
+ function updateAccessDeniedCount(count) {
+ document.querySelector("button#btnPDTAccessDenied").textContent =
+ " AccessDeny(" + count + ")";
}
-}
-function addEventHandlers() {
- document.querySelector("button#btnPDTErrors");
+ //TODO: convert to use PDT.settings
+ function siteConfigCallback(siteConfig, _globalConfig) {
+ if (!PDT.isTracerEnabled()) {
+ console.log("PDT tracer disabled");
+ } else {
+ console.log("PDT tracer");
+ messageServiceWorker("registerTracer"); //register with Service Worker
+
+ if (siteConfig && siteConfig.label) {
+ let headerButtonsElement = document.querySelector("table.tracertop tr");
+ if (headerButtonsElement) {
+ headerButtonsElement.insertAdjacentHTML(
+ "beforeend",
+ " " +
+ siteConfig.label +
+ " td>"
+ );
+ }
- //setTitle();
+ if (siteConfig.useColorTop) {
+ document.querySelector("table.tracertop").style.cssText =
+ "border-top: #" + siteConfig.color.replace("#", "") + " 2px solid";
+ }
+ }
+ $("#Pause").click(function () {
+ setTitle();
+ });
+
+ $("#ClearEvents").click(function () {
+ resetCounts();
+ });
+
+ //TODO: get rid of jQuery, use fetch API
+ $.get(browser.runtime.getURL("tracer/tracer_button.html"), function (data) {
+ //add buttons from html
+ $("table.tracertop table tr").eq(2).prepend(data);
+ waitUntilRenderTracerButtons();
+ });
+
+ // fetch API
+ // fetch(browser.runtime.getURL("tracer/tracer_buttonBookmarks.html")).then(t => t.text()).then(data => {
+ // let prevButton = document.querySelector("div.btnPDTGroup");
+ // if(prevButton) {
+ // prevButton.insertAdjacentHTML("beforebegin", data)
+ // }
+ // });
+ }
+ }
- //TODO: !!!!!!!
- document.querySelector("button#btnPDTErrors").oncontextmenu = function () {
- let offset = this.getBoundingClientRect().left;
- let errorListDropdown = window.parent.frames[1].document.querySelector(
- "div.dropdown-content"
- );
- if (errorListDropdown) {
+ function addDropdownHandler(dropdown, itemList, offset) {
+ if (dropdown && itemList) {
Array.prototype.forEach.call(
- errorListDropdown.querySelectorAll("a"),
+ dropdown.querySelectorAll("a"),
function (node) {
node.parentNode.removeChild(node);
}
);
- errorListDropdown.style.display = "block";
- errorListDropdown.style.left = offset;
- for (let errorResult in getErrorList()) {
+ if(itemList.length === 0)
+ return false;
+
+ dropdown.style.display = "block";
+ dropdown.style.left = offset;
+
+ itemList.forEach((element) => {
let newElem = document.createElement("a");
- newElem.textContent = errorResult.parent.querySelector("td#eventLineNumber").title;
- errorListDropdown.appendChild(newElem);
- }
+ newElem.value = element.parentNode.querySelector("td#eventLineNumber").innerText;
+ newElem.textContent = newElem.value;
+ if(element.parentNode.querySelector("td#elementInstanceName"))
+ newElem.textContent += ' - ' + element.parentNode.querySelector("td#elementInstanceName").title;
+ newElem.onclick = function () {
+ window.parent.frames[1].document.querySelector("td#eventLineNumber[title='" + this.value + "']").scrollIntoView(false, { behavior: "smooth" });
+ };
+ dropdown.appendChild(newElem);
+ })
+
let elem = document.createElement("a");
+ elem.style = "border-top: 1px solid #aaa;"
elem.textContent = "Close";
elem.onclick = function () {
- document.querySelector("div.dropdown-content").style.display = "none";
+ dropdown.style.display = "none";
};
+ dropdown.appendChild(elem);
return false;
- } else console.log("[PDT] tracer dropdown not found");
- };
-
- /* #region Errors buttons */
- document.querySelector("button#btnPDTErrors").onclick = function () {
- errorList = getErrorList();
- if (errorList.length) {
- errorList[errorList.length - 1].scrollIntoView(false);
+ } else console.log("[PDT] addDropdownHandler - wrong arguments");
+ }
+
+ function addEventHandlers() {
+
+ function navigateTo(itemList, nextOrPrev, currentIndex, text, clickedButton) {
+ let buttonElement = (nextOrPrev === "next" ? clickedButton.previousElementSibling : clickedButton.nextElementSibling);
+ if (itemList.length) {
+ currentIndex += (nextOrPrev === "next" ? -1 : 1);
+ // if(nextOrPrev === "next")
+ // currentIndex -= 1;
+ // else
+ // currentIndex += 1;
+ if (currentIndex < 0) {
+ currentIndex = itemList.length - 1;
+ }
+ itemList[currentIndex].scrollIntoView(false, { behavior: "smooth" });
+ updateButtonCount(buttonElement, text, itemList.length, currentIndex + 1);
+ } else updateButtonCount(buttonElement, text, itemList.length);
+ return currentIndex;
}
- updateErrorCount(errorList.length);
- errorIndex = 0;
- };
-
- document.querySelector("button#btnPDTErrorsPrev").onclick = function () {
- errorList = getErrorList();
- if (errorList.length) {
- errorIndex += 1;
- if (errorIndex >= errorList.length) {
- errorIndex = 0;
+
+ /* #region Errors buttons */
+
+ //FEATURE: Errors button context menu
+ document.querySelector("button#btnPDTErrors").oncontextmenu = (e) => {
+ let errorListDropdown = window.parent.frames[1].document.querySelector("div.PDTdropdown.errors");
+ return addDropdownHandler(errorListDropdown, getErrorList(), e.clientX - e.offsetX);
+ };
+
+ //FEATURE: Go to first error instance
+ document.querySelector("button#btnPDTErrors").onclick = function () {
+ errorList = getErrorList();
+ if (errorList.length) {
+ errorList[errorList.length - 1].scrollIntoView(false);
}
- errorList[errorIndex].scrollIntoView(false, { behavior: "smooth" });
- updateErrorCount(errorList.length, errorIndex + 1);
- } else {
updateErrorCount(errorList.length);
- }
- };
-
- document.querySelector("button#btnPDTErrorsNext").onclick = function () {
- errorList = getErrorList();
- if (errorList.length) {
- errorIndex -= 1;
- if (errorIndex < 0) {
- errorIndex = errorList.length - 1;
+ errorIndex = 0;
+ };
+
+ //FEATURE: Go to previous error
+ document.querySelector("button#btnPDTErrorsPrev").onclick = function () {
+ // errorList = getErrorList();
+ // if (errorList.length) {
+ // errorIndex += 1;
+ // if (errorIndex >= errorList.length) {
+ // errorIndex = 0;
+ // }
+ // errorList[errorIndex].scrollIntoView(false, { behavior: "smooth" });
+ // updateErrorCount(errorList.length, errorIndex + 1);
+ // } else {
+ // updateErrorCount(errorList.length);
+ // }
+ errorIndex = navigateTo(getErrorList(), "prev", errorIndex, "Errors", this);
+ };
+
+ //FEATURE: Go to next error
+ document.querySelector("button#btnPDTErrorsNext").onclick = function () {
+ // errorList = getErrorList();
+ // if (errorList.length) {
+ // errorIndex -= 1;
+ // if (errorIndex < 0) {
+ // errorIndex = errorList.length - 1;
+ // }
+ // errorList[errorIndex].scrollIntoView(false, { behavior: "smooth" });
+ // updateErrorCount(errorList.length, errorIndex + 1);
+ // } else {
+ // updateErrorCount(errorList.length);
+ // }
+ errorIndex = navigateTo(getErrorList(), "next", errorIndex, "Errors", this);
+ };
+ /* #endregion */
+
+ /* #region Messages buttons */
+
+ //FEATURE: Warnings button context menu
+ document.querySelector("button#btnPDTMessages").oncontextmenu = (e) => {
+ let messagesListDropdown = window.parent.frames[1].document.querySelector("div.PDTdropdown.warnings");
+ return addDropdownHandler(messagesListDropdown, getMessagesList(), e.clientX - e.offsetX);
+ };
+
+ //FEATURE: Go to first warning/message instance
+ document.querySelector("button#btnPDTMessages").onclick = function () {
+ messagesList = getMessagesList();
+ if (messagesList.length) {
+ messagesList[messagesList.length - 1].scrollIntoView(false);
}
- errorList[errorIndex].scrollIntoView(false, { behavior: "smooth" });
- updateErrorCount(errorList.length, errorIndex + 1);
+ updateMessageCount(messagesList.length);
+ messageIndex = 0;
+ };
+
+ //FEATURE: Go to previous warning
+ document.querySelector("button#btnPDTMessagesPrev").onclick = function () {
+ // messagesList = getMessagesList();
+ // if (messagesList.length) {
+ // messageIndex += 1;
+ // if (messageIndex >= messagesList.length) {
+ // messageIndex = 0;
+ // }
+ // messagesList[messageIndex].scrollIntoView(false, { behavior: "smooth" });
+ // updateMessageCount(messagesList.length, messageIndex + 1);
+ // } else updateMessageCount(messagesList.length);
+ messageIndex = navigateTo(getMessagesList(), "prev", messageIndex, "Warnings", this);
+ };
+
+ //FEATURE: Go to next warning
+ document.querySelector("button#btnPDTMessagesNext").onclick = function () {
+ // messagesList = getMessagesList();
+ // if (messagesList.length) {
+ // messageIndex -= 1;
+ // if (messageIndex < 0) {
+ // messageIndex = messagesList.length - 1;
+ // }
+ // messagesList[messageIndex].scrollIntoView(false, { behavior: "smooth" });
+ // updateMessageCount(messagesList.length, messageIndex + 1);
+ // } else updateMessageCount(messagesList.length);
+ messageIndex = navigateTo(getMessagesList(), "next", messageIndex, "Warnings", this);
+ };
+ /* #endregion */
+
+ /* #region Bookmarks buttons */
+
+ //FEATURE: Bookmarks button context menu
+ document.querySelector("button#btnPDTBookmarks").oncontextmenu = (e) => {
+ let errorListDropdown = window.parent.frames[1].document.querySelector("div.PDTdropdown.bookmarks");
+ return addDropdownHandler(errorListDropdown, getBookmarksList(), e.clientX - e.offsetX);
+ };
+
+ //FEATURE: Go to first bookmark instance
+ document.querySelector("button#btnPDTBookmarks").onclick = function () {
+ bookmarkList = getBookmarksList();
+ if (bookmarkList.length) {
+ bookmarkList[bookmarkList.length - 1].scrollIntoView(false);
+ }
+ updateButtonCount(this, "Bookmarks", bookmarkList.length);
+ bookmarkIndex = 0;
+ };
+
+ //FEATURE: Go to previous bookmark
+ document.querySelector("button#btnPDTBookmarksPrev").onclick = function () {
+ // bookmarkList = getBookmarksList();
+ // if (bookmarkList.length) {
+ // bookmarkIndex += 1;
+ // if (bookmarkIndex >= bookmarkList.length) {
+ // bookmarkIndex = 0;
+ // }
+ // bookmarkList[bookmarkIndex].scrollIntoView(false, { behavior: "smooth" });
+ // updateButtonCount(this.nextElementSibling, "Bookmarks", bookmarkList.length, bookmarkIndex + 1);
+ // } else updateButtonCount(this.nextElementSibling, "Bookmarks", bookmarkList.length);
+ bookmarkIndex = navigateTo(getBookmarksList(), "prev", bookmarkIndex, "Bookmarks", this);
+ };
+
+ //FEATURE: Go to next bookmark
+ document.querySelector("button#btnPDTBookmarksNext").onclick = function () {
+ // bookmarkList = getBookmarksList();
+ // if (bookmarkList.length) {
+ // bookmarkIndex -= 1;
+ // if (bookmarkIndex < 0) {
+ // bookmarkIndex = bookmarkList.length - 1;
+ // }
+ // bookmarkList[bookmarkIndex].scrollIntoView(false, { behavior: "smooth" });
+ // updateButtonCount(this.previousElementSibling, "Bookmarks", bookmarkList.length, bookmarkIndex + 1);
+ // } else updateButtonCount(this.previousElementSibling, "Bookmarks", bookmarkList.length);
+ bookmarkIndex = navigateTo(getBookmarksList(), "next", bookmarkIndex, "Bookmarks", this);
+ };
+
+ /* #endregion */
+ }
+
+ //make sure buttons are part of the DOM before adding event handlers
+ //TODO: use arrive.js
+ function waitUntilRenderTracerButtons() {
+ let expectedElement = document.querySelector("button#btnPDTErrors");
+ if (expectedElement) {
+ addEventHandlers();
} else {
- updateErrorCount(errorList.length);
+ tries = tries + 1;
+ console.log(tries);
+ //if (tries > 10) return;
+ setTimeout(() => {
+ waitUntilRenderTracerButtons();
+ }, 500);
}
- };
- /* #endregion */
-
- /* #region Messages buttons */
- document.querySelector("button#btnPDTMessages").onclick = function () {
- messagesList = getMessagesList();
- if (messagesList.length) {
- messagesList[messagesList.length - 1].scrollIntoView(false);
- }
- updateMessageCount(messagesList.length);
- messageIndex = 0;
- };
-
- document.querySelector("button#btnPDTMessagesPrev").onclick = function () {
- messagesList = getMessagesList();
- if (messagesList.length) {
- messageIndex += 1;
- if (messageIndex >= messagesList.length) {
- messageIndex = 0;
- }
- messagesList[messageIndex].scrollIntoView(false, { behavior: "smooth" });
- updateMessageCount(messagesList.length, messageIndex + 1);
- } else updateMessageCount(messagesList.length);
- };
-
- document.querySelector("button#btnPDTMessagesNext").onclick = function () {
- messagesList = getMessagesList();
- if (messagesList.length) {
- messageIndex -= 1;
- if (messageIndex < 0) {
- messageIndex = messagesList.length - 1;
- }
- messagesList[messageIndex].scrollIntoView(false, { behavior: "smooth" });
- updateMessageCount(messagesList.length, messageIndex + 1);
- } else updateMessageCount(messagesList.length);
- };
- /* #endregion */
-}
-
-//make sure buttons are part of the DOM before adding event handlers
-//TODO: use arrive.js
-function waitUntilRenderTracerButtons() {
- let expectedElement = document.querySelector("button#btnPDTErrors");
- if (expectedElement) {
- addEventHandlers();
- } else {
- tries = tries + 1;
- console.log(tries);
- //if (tries > 10) return;
- setTimeout(() => {
- waitUntilRenderTracerButtons();
- }, 500);
}
-}
-var tries = 0;
+ var tries = 0;
+
+ //make sure we are in the right frame, script can be loaded with tracer page popup
+ if(document.querySelector("table.tracertop")) {
+ siteConfig(siteConfigCallback);
+ }
-//make sure we are in the right frame, script can be loaded with tracer page popup
-if(document.querySelector("table.tracertop")) {
- siteConfig(siteConfigCallback);
-}
+ PDT.alterFavicon();
-PDT.alterFavicon();
+ window.parent.frames[1].document.body.insertAdjacentHTML('afterbegin', '
');
+ window.parent.frames[1].document.body.insertAdjacentHTML('afterbegin', '
');
+ window.parent.frames[1].document.body.insertAdjacentHTML('afterbegin', '
');
-//TODO:
-//displayPage = new Function('pageXML','pageName','pagePropertyName', displayPage.toString().match(/{([\s\S]*)}/)[1].replace('window.open(strURL,strForm,"status=yes,toolbar=no,menubar=no,location=no,scrollbars=yes,resizable=yes" + strFeatures)', "window.open(strURL,'_blank')"));
-//TODO: Access Deny list
-//window.parent.frames[1].document.querySelectorAll('td[title="Access Denied"]')
\ No newline at end of file
+ //TODO:
+ //displayPage = new Function('pageXML','pageName','pagePropertyName', displayPage.toString().match(/{([\s\S]*)}/)[1].replace('window.open(strURL,strForm,"status=yes,toolbar=no,menubar=no,location=no,scrollbars=yes,resizable=yes" + strFeatures)', "window.open(strURL,'_blank')"));
+ //TODO: Access Deny list
+ //window.parent.frames[1].document.querySelectorAll('td[title="Access Denied"]')
+});
\ No newline at end of file
diff --git a/tracer/tracer_options.js b/tracer/tracer_options.js
index 7cec65e6..71dc5b8b 100644
--- a/tracer/tracer_options.js
+++ b/tracer/tracer_options.js
@@ -150,6 +150,10 @@ function loadRulesets(rulesets) {
});
}
+function makeFullscreen() {
+ window.resizeTo(screen.width,screen.height);
+}
+
//TODO: WiP
function responsiveLayout() {
document.querySelectorAll("div#ProfileDiv div.dialogDataContainer table table td")[2].className = "PDTrow";
@@ -162,7 +166,7 @@ function siteConfigCallback(_siteConfig, globalConfig) {
} else {
//FEATURE: Display settings in fullscreen
if (globalConfig.settings.tracer.settingsFullscreen) {
- PDT.makeFullscreen();
+ makeFullscreen();
}
}
}
@@ -191,8 +195,8 @@ fetch(browser.runtime.getURL("tracer/tracer_pegaRulesetSelection.html"))
});
document.arrive("button#PDTDeselectPegaRulesets", {onceOnly: true, existing: true}, () => {
- document.querySelector("button#PDTSelectPegaRulesets").addEventListener("click", () => document.querySelectorAll("div#RuleSetDisplay table table table td.dataLabelStyle input[type='CHECKBOX']").forEach(function (el) { if(el.nextSibling.textContent.trim().startsWith("Pega") || el.nextSibling.textContent.trim().startsWith("UI-")) el.checked = true } ));
- document.querySelector("button#PDTDeselectPegaRulesets").addEventListener("click", () => document.querySelectorAll("div#RuleSetDisplay table table table td.dataLabelStyle input[type='CHECKBOX']").forEach(function (el) { if(el.nextSibling.textContent.trim().startsWith("Pega") || el.nextSibling.textContent.trim().startsWith("UI-")) el.checked = false } ));
+ document.querySelector("button#PDTSelectPegaRulesets").addEventListener("click", () => document.querySelectorAll("div#RuleSetDisplay table table table td.dataLabelStyle input[type='CHECKBOX']").forEach(function (el) { if(el.nextSibling.textContent.trim().startsWith("Pega")) el.checked = true } ));
+ document.querySelector("button#PDTDeselectPegaRulesets").addEventListener("click", () => document.querySelectorAll("div#RuleSetDisplay table table table td.dataLabelStyle input[type='CHECKBOX']").forEach(function (el) { if(el.nextSibling.textContent.trim().startsWith("Pega")) el.checked = false } ));
});
siteConfig(siteConfigCallback);
\ No newline at end of file
diff --git a/tracer/tracer_page.js b/tracer/tracer_page.js
index ec6efa1b..15f30574 100644
--- a/tracer/tracer_page.js
+++ b/tracer/tracer_page.js
@@ -1,37 +1,3 @@
-console.log("PDT: tracer_page");
-
-document.arrive("div#MainDiv", {onceOnly: true, existing: true}, () => {
- if(getMainTable()) {
- addPageNavigation();
- addSearch();
- injectScript("/js/", "expandTracerMessagesOnLoad.js");
- } else {
- //FEATURE: full SQL query
- let sql = "", inserts = "", insertsRow;
-
- for (tr of document.querySelectorAll("div.dialogDataContainer tr.eventTable")) {
- if (tr.children[0].textContent.trim() == "SQL") {
- sql = tr.children[1].textContent.trim();
- } else if (tr.children[0].textContent.trim() == "SQL Inserts") {
- inserts = tr.children[1].textContent.trim();
- insertsRow = tr;
- }
- }
-
- if(sql && inserts) {
- let fullSQL = prepareSQL(sql, inserts);
- if(fullSQL) {
- let fullSQLElement = document.createElement('td');
- fullSQLElement.colSpan = 2;
- fullSQLElement.style.border = "thin solid black";
- fullSQLElement.style.padding = "4px";
- fullSQLElement.style.fontFamily = "monospace";
- fullSQLElement.innerHTML = fullSQL;
- insertsRow.insertAdjacentElement("afterend", fullSQLElement);
- }
- }
- }
-});
//sorting based on https://stackoverflow.com/questions/14267781/sorting-html-table-with-javascript by Nick Grealy
const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent;
@@ -43,11 +9,9 @@ function getMainTable() { return document.querySelector("div#scrollingDIV table
function sortTopLevel() {
let mainTable = getMainTable();
- if(mainTable) {
- Array.from(mainTable.querySelectorAll(':scope > tbody > tr.eventTable:nth-child(n+2)'))
- .sort(comparer(0))
- .forEach(tr => mainTable.appendChild(tr) );
- }
+ Array.from(mainTable.querySelectorAll(':scope > tbody > tr.eventTable:nth-child(n+2)'))
+ .sort(comparer(0))
+ .forEach(tr => mainTable.appendChild(tr) );
}
function addPageNavigation() {
@@ -63,6 +27,8 @@ function addPageNavigation() {
if (mainTable) {
injectScript("/js/", "tracerMarkNavigatedPage.js");
+ //TODO: needed?
+ mainTable.setAttribute("id", "mainTable");
//let subHeader = document.querySelector("td.dialogSubHeaderBackground");
//subHeader.innerHTML = "";
@@ -72,25 +38,65 @@ function addPageNavigation() {
function(a, b) {
let textA = a.parentNode.parentNode.querySelector("td").innerText.trim().toUpperCase();
let textB = b.parentNode.parentNode.querySelector("td").innerText.trim().toUpperCase();
- return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
+ return (textA < textB) ? -1 : ((textA > textB) ? 1 : 0);
}
).forEach(elem => {
let pElem = elem.parentNode.parentNode.querySelector("td");
- let pElemText = pElem.innerText.trim();
- //FEATURE: skip list items with index > 1, only one link representing the list will be shown for clarity
- if(pElemText.endsWith(")") && !pElemText.endsWith("(1)")) {
- return;
- }
-
- pElem.setAttribute("id", "mainPageNode" + pElemText);
- let linkTag = document.createElement("a");
+ pElem.setAttribute("id", "mainPageNode" + pElem.innerText.trim());
+ let linkTag = document.createElement("a");
+ linkTag.innerHTML = pElem.innerText.trim();
linkTag.setAttribute("href", "#" + "mainPageNode" + pElem.innerText.trim());
linkTag.setAttribute("onclick", "markNavigatedPage(this)");
- if(pElemText.endsWith("(1)")) {
- pElemText = pElemText.replace("(1)", "()");
+ linkTag.setAttribute("title", pElem.innerText.trim());
+ divTag.appendChild(linkTag);
+ divTag.appendChild(document.createElement("br"));
+ })
+ console.log("PDT tracer_page: navigation added");
+
+ //FEATURE: make page navigation float
+ //TODO: Ugly. Copies navigation div as a transparent placeholder to keep width and sets navigation position as fixed. Needs a nice CSS solution.
+ let divTagClone = divTag.cloneNode(true);
+ divTagClone.id = "PDT_placeholder";
+ divTagClone.classList.add("PegaDevToolsTransparent");
+ divTag.style.setProperty("position", "fixed");
+ mainDiv.prepend(divTagClone);
+ } else {
+ return false;
+ }
+}
+
+function addPageNavigation() {
+ let mainDiv = document.querySelector("div#MainDiv");
+ mainDiv.style.display = "flex";
+ let divTag = document.createElement("div");
+ divTag.id = "PDT_embeddedPageList";
+ divTag.style.minWidth = "15%";
+ divTag.style.maxWidth = "20%";
+ mainDiv.prepend(divTag);
+
+ let mainTable = getMainTable();
+ if (mainTable) {
+ injectScript("/js/", "tracerMarkNavigatedPage.js");
+
+ //let subHeader = document.querySelector("td.dialogSubHeaderBackground");
+ //subHeader.innerHTML = "";
+
+ //FEATURE: add navigation link
+ let embeddedPages = mainTable.querySelectorAll(":scope > tbody > tr.eventTable > td > table");
+ Array.from(embeddedPages).sort(
+ function(a, b) {
+ let textA = a.parentNode.parentNode.querySelector("td").innerText.trim().toUpperCase();
+ let textB = b.parentNode.parentNode.querySelector("td").innerText.trim().toUpperCase();
+ return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
}
- linkTag.setAttribute("title", pElemText);
- linkTag.innerHTML = pElemText;
+ ).forEach(elem => {
+ let pElem = elem.parentNode.parentNode.querySelector("td");
+ pElem.setAttribute("id", "mainPageNode" + pElem.innerText.trim());
+ let linkTag = document.createElement("a");
+ linkTag.innerHTML = pElem.innerText.trim();
+ linkTag.setAttribute("href", "#" + "mainPageNode" + pElem.innerText.trim());
+ linkTag.setAttribute("onclick", "markNavigatedPage(this)");
+ linkTag.setAttribute("title", pElem.innerText.trim());
divTag.appendChild(linkTag);
divTag.appendChild(document.createElement("br"));
})
@@ -135,7 +141,7 @@ function addSearch() {
};
return searchBox;
- }
+ }
let mainTable = getMainTable();
if (mainTable) {
@@ -151,43 +157,11 @@ function addSearch() {
}
}
-function prepareSQL(sql, inserts) {
- //regex would be much nicer
- // function sanitize(inText) {
- // if(inText.includes("< ") || inText.includes(" >")) {
- // inText = inText.replace("< ", "<").replace(" >", ">");
- // return(sanitize(inText));
- // }
- // return inText;
- // }
-
- // inserts = sanitize(inserts);
- // inserts = inserts.replaceAll("<", "'").replaceAll(">", "'").trim();
-
- // let insertsSplit = inserts.split(" ");
-
- inserts = inserts.replaceAll("> <", ">\t<").trim();;
- inserts = inserts.replaceAll("<", "'").replaceAll(">", "'");
- let insertsSplit = inserts.split("\t");
- // for (let i = 0; i < insertsSplit.length; i++) {
- // insertsSplit[i] = insertsSplit[i].replace("<", "").replace(">", "");
- // }
- let sqlSplit = sql.split("?");
- let resultSql = "";
- for (let i = 0; i < sqlSplit.length - 1; i++) {
- resultSql += sqlSplit[i] + "" + insertsSplit[i] + " ";
- }
- resultSql += sqlSplit[sqlSplit.length - 1];
-
- resultSql = resultSql.replaceAll("''null''", "NULL");
- return resultSql;
-}
-
//TODO: convert to PDT settings
-function siteConfigCallback(siteConfig, globalConfig) {
+function siteConfigCallback(_siteConfig, globalConfig) {
if (! PDT.isTracerEnabled()) {
console.log('PDT tracer disabled');
- } else {
+ } else {
document.arrive("div#MainDiv", {onceOnly: true, existing: true}, () => {
if(getMainTable()) {
//FEATURE: Sort properties alphabetically in page view
@@ -205,3 +179,8 @@ function siteConfigCallback(siteConfig, globalConfig) {
}
siteConfig(siteConfigCallback);
+
+document.arrive("div#MainDiv", {onceOnly: true, existing: true}, () => {
+ addPageNavigation();
+ addSearch();
+});
\ No newline at end of file
diff --git a/tracer/tracer_pegaRulesetSelection.html b/tracer/tracer_pegaRulesetSelection.html
index 4f269969..92aa9922 100644
--- a/tracer/tracer_pegaRulesetSelection.html
+++ b/tracer/tracer_pegaRulesetSelection.html
@@ -1,4 +1,3 @@
-