Yay a devtools!
This commit is contained in:
@@ -1,52 +1,127 @@
|
||||
const port = browser.runtime.connect({ name: "devtools" });
|
||||
port.onMessage.addListener((message) => {
|
||||
if (message.type === "PAGE_LOADED") {
|
||||
loadContextStack(); // Refresh your context stack here.
|
||||
}
|
||||
});
|
||||
|
||||
const tabId = browser.devtools.inspectedWindow.tabId;
|
||||
|
||||
document.getElementById("refresh").addEventListener("click", loadContextStack);
|
||||
|
||||
function loadContextStack() {
|
||||
const container = document.getElementById("contextContainer");
|
||||
container.innerHTML = "";
|
||||
|
||||
browser.runtime.sendMessage({ type: "GET_CONTEXT_STACK" }).then(
|
||||
browser.runtime.sendMessage({ type: "GET_CONTEXT_STACK", tabId }).then(
|
||||
(response) => {
|
||||
if (response.error) {
|
||||
container.innerHTML = `<p>Error: ${response.error}</p>`;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response || !response.contextStack) {
|
||||
container.innerHTML = "<p>No context stack found.</p>";
|
||||
return;
|
||||
}
|
||||
|
||||
const contextStack = response.contextStack;
|
||||
for (const key in contextStack) {
|
||||
const row = document.createElement("div");
|
||||
row.classList.add("context-row");
|
||||
|
||||
const keyDiv = document.createElement("div");
|
||||
keyDiv.classList.add("context-key");
|
||||
keyDiv.textContent = key;
|
||||
|
||||
const valueDiv = document.createElement("div");
|
||||
valueDiv.classList.add("context-value");
|
||||
|
||||
const input = document.createElement("input");
|
||||
input.value = contextStack[key];
|
||||
input.addEventListener("change", () => {
|
||||
browser.runtime.sendMessage({
|
||||
type: "UPDATE_CONTEXT_VALUE",
|
||||
key,
|
||||
value: input.value,
|
||||
}).then((updateResponse) => {
|
||||
if (updateResponse && updateResponse.success) {
|
||||
console.log(`Updated ${key} to ${input.value}`);
|
||||
} else {
|
||||
console.error(`Failed to update ${key}:`, updateResponse.error);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
valueDiv.appendChild(input);
|
||||
row.appendChild(keyDiv);
|
||||
row.appendChild(valueDiv);
|
||||
container.appendChild(row);
|
||||
}
|
||||
const contextStack = coalesceContextStack(response.contextStack);
|
||||
const form = generateObjectForm(contextStack);
|
||||
container.appendChild(form);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Initial load when the panel opens.
|
||||
loadContextStack();
|
||||
function generateObjectForm(obj, path = "") {
|
||||
const detail = document.createElement("details");
|
||||
detail.open = path === "";
|
||||
const summary = document.createElement("summary");
|
||||
summary.textContent = path.split(".").at(-1);
|
||||
detail.appendChild(summary);
|
||||
const form = document.createElement("form");
|
||||
let count = 0;
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
if (value == undefined || value === "[Circular]") continue;
|
||||
const isObject = value.constructor === Object;
|
||||
const isArray = Array.isArray(value);
|
||||
if (isObject || isArray) {
|
||||
const nestedForm = generateObjectForm(
|
||||
value,
|
||||
path ? path + "." + key : key,
|
||||
);
|
||||
if (!nestedForm) {
|
||||
continue;
|
||||
}
|
||||
const div = document.createElement("div");
|
||||
div.appendChild(nestedForm);
|
||||
form.appendChild(div);
|
||||
count++;
|
||||
continue;
|
||||
}
|
||||
const div = document.createElement("div");
|
||||
const label = document.createElement("label");
|
||||
label.textContent = key;
|
||||
div.appendChild(label);
|
||||
const input = document.createElement("input");
|
||||
input.name = key;
|
||||
const isBoolean = typeof value === "boolean";
|
||||
if (isBoolean) {
|
||||
input.type = "checkbox";
|
||||
input.checked = value;
|
||||
input.addEventListener("change", () => {
|
||||
browser.runtime.sendMessage({
|
||||
type: "UPDATE_CONTEXT_VALUE",
|
||||
key: path ? path + "." + key : key,
|
||||
value: input.checked,
|
||||
tabId,
|
||||
}).then((updateResponse) => {
|
||||
if (updateResponse && updateResponse.success) {
|
||||
console.log(`Updated ${key} to ${input.checked}`);
|
||||
} else {
|
||||
console.error(`Failed to update ${key}:`, updateResponse.error);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
input.type = "text";
|
||||
input.value = value;
|
||||
input.addEventListener("change", () => {
|
||||
browser.runtime.sendMessage({
|
||||
type: "UPDATE_CONTEXT_VALUE",
|
||||
key: path ? path + "." + key : key,
|
||||
value: input.value,
|
||||
tabId,
|
||||
}).then((updateResponse) => {
|
||||
if (updateResponse && updateResponse.success) {
|
||||
console.log(`Updated ${key} to ${input.value}`);
|
||||
} else {
|
||||
console.error(`Failed to update ${key}:`, updateResponse.error);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
div.appendChild(input);
|
||||
form.appendChild(div);
|
||||
count++;
|
||||
}
|
||||
if (count === 0) {
|
||||
const pre = document.createElement("pre");
|
||||
pre.textContent = JSON.stringify(obj, null, 2);
|
||||
detail.appendChild(pre);
|
||||
} else {
|
||||
detail.appendChild(form);
|
||||
}
|
||||
return detail;
|
||||
}
|
||||
|
||||
function coalesceContextStack(contextStack) {
|
||||
const obj = {};
|
||||
for (const ctx of contextStack) {
|
||||
Object.assign(obj, ctx);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
loadContextStack();
|
||||
});
|
||||
|
Reference in New Issue
Block a user