mirror of
https://github.com/fergalmoran/ladybird.git
synced 2025-12-22 09:19:03 +00:00
Inspector: Add a basic style sheet inspector
Choosing options from the `<select>` will load and display that style sheet's source text, with some checks to make sure that the text that just loaded is the one we currently want. The UI is a little goofy when scrolling, as it uses `position: sticky` which we don't implement yet. But that's just more motivation to implement it! :^)
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
:root {
|
||||
--code-font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background: rgb(23, 23, 23);
|
||||
@@ -174,6 +178,17 @@ body {
|
||||
overflow: auto scroll;
|
||||
}
|
||||
|
||||
.tab-header {
|
||||
position: sticky;
|
||||
top: 2px; /* FIXME: Remove this when https://github.com/LadybirdBrowser/ladybird/issues/1245 is resolved. */
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: var(--tab-controls);
|
||||
border-top: 2px solid var(--background);
|
||||
display: flex;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
details > :not(:first-child) {
|
||||
display: list-item;
|
||||
list-style: none inside;
|
||||
@@ -204,7 +219,7 @@ details > :not(:first-child) {
|
||||
}
|
||||
|
||||
.console {
|
||||
font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
font-family: var(--code-font-family);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@@ -330,3 +345,14 @@ details > :not(:first-child) {
|
||||
padding: 4px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#style-sheet-picker {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#style-sheet-source {
|
||||
font-size: 10pt;
|
||||
font-family: var(--code-font-family);
|
||||
white-space: pre;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
@@ -199,6 +199,97 @@ inspector.addAttributeToDOMNodeID = nodeID => {
|
||||
pendingEditDOMNode = null;
|
||||
};
|
||||
|
||||
inspector.setStyleSheets = styleSheets => {
|
||||
const styleSheetPicker = document.getElementById("style-sheet-picker");
|
||||
const styleSheetSource = document.getElementById("style-sheet-source");
|
||||
styleSheetPicker.replaceChildren();
|
||||
styleSheetSource.innerHTML = "";
|
||||
|
||||
function addOption(styleSheet, text) {
|
||||
const option = document.createElement("option");
|
||||
option.innerText = text;
|
||||
if (styleSheet.type) {
|
||||
option.dataset["type"] = styleSheet.type;
|
||||
}
|
||||
if (styleSheet.domNodeId) {
|
||||
option.dataset["domNodeId"] = styleSheet.domNodeId;
|
||||
}
|
||||
if (styleSheet.url) {
|
||||
option.dataset["url"] = styleSheet.url;
|
||||
}
|
||||
styleSheetPicker.add(option);
|
||||
}
|
||||
|
||||
if (styleSheets.length > 0) {
|
||||
let styleElementIndex = 1;
|
||||
for (const styleSheet of styleSheets) {
|
||||
switch (styleSheet.type) {
|
||||
case "StyleElement":
|
||||
addOption(styleSheet, `Style element #${styleElementIndex++}`);
|
||||
break;
|
||||
case "LinkElement":
|
||||
addOption(styleSheet, styleSheet.url);
|
||||
break;
|
||||
case "ImportRule":
|
||||
addOption(styleSheet, styleSheet.url);
|
||||
break;
|
||||
case "UserAgent":
|
||||
addOption(styleSheet, `User agent: ${styleSheet.url}`);
|
||||
break;
|
||||
case "UserStyle":
|
||||
addOption(styleSheet, "User style");
|
||||
break;
|
||||
}
|
||||
}
|
||||
styleSheetPicker.disabled = false;
|
||||
} else {
|
||||
addOption({}, "No style sheets found");
|
||||
styleSheetPicker.disabled = true;
|
||||
}
|
||||
|
||||
styleSheetPicker.selectedIndex = 0;
|
||||
|
||||
if (!styleSheetPicker.disabled) {
|
||||
loadStyleSheet();
|
||||
}
|
||||
};
|
||||
|
||||
const loadStyleSheet = () => {
|
||||
const styleSheetPicker = document.getElementById("style-sheet-picker");
|
||||
const styleSheetSource = document.getElementById("style-sheet-source");
|
||||
const selectedOption = styleSheetPicker.selectedOptions[0];
|
||||
|
||||
styleSheetSource.innerHTML = "Loading...";
|
||||
inspector.requestStyleSheetSource(
|
||||
selectedOption.dataset["type"],
|
||||
selectedOption.dataset["domNodeId"],
|
||||
selectedOption.dataset["url"]
|
||||
);
|
||||
};
|
||||
|
||||
inspector.setStyleSheetSource = (identifier, sourceBase64) => {
|
||||
const styleSheetPicker = document.getElementById("style-sheet-picker");
|
||||
const styleSheetSource = document.getElementById("style-sheet-source");
|
||||
const selectedOption = styleSheetPicker.selectedOptions[0];
|
||||
|
||||
// Make sure this is the source for the currently-selected style sheet.
|
||||
// NOTE: These are != not !== intentionally.
|
||||
if (
|
||||
identifier.type != selectedOption.dataset["type"] ||
|
||||
identifier.domNodeId != selectedOption.dataset["domNodeId"] ||
|
||||
identifier.url != selectedOption.dataset["url"]
|
||||
) {
|
||||
console.log(
|
||||
JSON.stringify(identifier),
|
||||
"doesn't match",
|
||||
JSON.stringify(selectedOption.dataset)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
styleSheetSource.innerHTML = decodeBase64(sourceBase64);
|
||||
};
|
||||
|
||||
inspector.createPropertyTables = (computedStyle, resolvedStyle, customProperties) => {
|
||||
const createPropertyTable = (tableID, properties) => {
|
||||
let oldTable = document.getElementById(tableID);
|
||||
|
||||
Reference in New Issue
Block a user