Skip to content

Instantly share code, notes, and snippets.

@disouzam
Created April 8, 2025 22:36
Show Gist options
  • Save disouzam/44ace407cb704369a8ed8adb6d8b4dcd to your computer and use it in GitHub Desktop.
Save disouzam/44ace407cb704369a8ed8adb6d8b4dcd to your computer and use it in GitHub Desktop.
Get all computed styles from a HTML page - for debugging purposes
// Get all computed styles of a page
class Stack {
constructor() {
this.stack = [];
}
push(element) {
this.stack.push(element);
}
pop() {
if (this.isEmpty()) {
return "Stack is empty";
}
return this.stack.pop();
}
invertedStack() {
const invStack = new Stack();
const currentStackSize = this.size();
for (let i = currentStackSize - 1; i >= 0; i--) {
invStack.push(this.stack[i]);
}
return invStack;
}
isEmpty() {
return this.stack.length === 0;
}
peek() {
if (this.isEmpty()) {
return "Stack is empty";
}
return this.stack[this.stack.length - 1];
}
size() {
return this.stack.length;
}
}
const unWantedTagNames = ['HEAD', 'LINK', 'META', 'SCRIPT', 'STYLE', 'TITLE'];
function getArrayOfNodeStyles(element, arrayOfNodeStyles) {
const tagName = element.tagName;
if (unWantedTagNames.includes(tagName)) {
return arrayOfNodeStyles;
}
const nodeStyles = {
elementTag: tagName,
elementClasses: element.classList,
elementId: element.id,
elementStyle: getComputedStyle(element)
}
arrayOfNodeStyles.push(nodeStyles);
return arrayOfNodeStyles;
}
function getAllChildrenElements(element) {
const childrenStack = new Stack();
const currentChildren = element.children;
for (let child of currentChildren) {
childrenStack.push(child);
const childrenOfChildren = getAllChildrenElements(child);
const invertedStack = childrenOfChildren.invertedStack();
while (!invertedStack.isEmpty()) {
const poppedElement = invertedStack.pop();
childrenStack.push(poppedElement);
}
}
return childrenStack;
}
function getAllElementsUnderHtmlElement() {
const htmlElement = document.getElementsByTagName('html')[0];
const stackOfElements = new Stack();
stackOfElements.push(htmlElement);
const childrenElements = getAllChildrenElements(htmlElement);
const invertedStack = childrenElements.invertedStack();
while (!invertedStack.isEmpty()) {
const poppedElement = invertedStack.pop();
stackOfElements.push(poppedElement);
}
return stackOfElements;
}
function registerObserver(targetNode) {
// https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
// Options for the observer (which mutations to observe)
const config = { attributes: true, childList: true, subtree: true };
// Callback function to execute when mutations are observed
const callback = (mutationList, observer) => {
// https://stackoverflow.com/questions/40137825/mutation-observer-with-external-callback-function-code/40138582#40138582
for (const mutation of mutationList) {
if (mutation.type === "childList") {
console.log(`[${targetNode.tagName} - ${targetNode.id}] A child node has been added or removed.`);
} else if (mutation.type === "attributes") {
console.log(`[${targetNode.tagName} - ${targetNode.id}] The ${mutation.attributeName} attribute was modified.`);
}
}
const localStackOfElements = getAllElementsUnderHtmlElement();
console.warn(`Number of elements in the stack of elements: ${localStackOfElements.size()}`);
getAllComputedStyles(localStackOfElements);
};
// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(targetNode, config);
}
function getAllComputedStyles(stackOfElements) {
const stackToComputeStyles = stackOfElements.invertedStack();
let arrayOfNodeStyles = [];
while (!stackToComputeStyles.isEmpty()) {
const poppedElement = stackToComputeStyles.pop();
arrayOfNodeStyles = getArrayOfNodeStyles(poppedElement, arrayOfNodeStyles);
}
console.log(JSON.stringify(arrayOfNodeStyles));
}
function processDOM() {
const stackOfElements = getAllElementsUnderHtmlElement();
const invertedStack2 = stackOfElements.invertedStack();
while (!invertedStack2.isEmpty()) {
const poppedElement = invertedStack2.pop();
registerObserver(poppedElement);
}
getAllComputedStyles(stackOfElements);
}
processDOM();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment