mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 02:47:35 +00:00
Base+Ladybird: Move Ladybird-related HTML files to their own folder
Pages like the new tab page, error page, etc. all belong solely to Ladybird, but are scattered across a couple of subfolders in Base. This moves them all to Base/res/ladybird.
This commit is contained in:
parent
980e32b4fe
commit
05c8d5ba57
11 changed files with 12 additions and 12 deletions
|
@ -1,51 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Index of @path@</title>
|
||||
<style>
|
||||
header {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
h1 {
|
||||
display: inline;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
a:focus, a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
table {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.folder, .file, .open-parent {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 5px;
|
||||
background-size: contain;
|
||||
}
|
||||
.folder {
|
||||
background-image: url('@resource_directory_url@/icons/32x32/filetype-folder.png');
|
||||
}
|
||||
.file {
|
||||
background-image: url('@resource_directory_url@/icons/32x32/filetype-unknown.png');
|
||||
}
|
||||
.open-parent {
|
||||
background-image: url('@resource_directory_url@/icons/16x16/open-parent-directory.png');
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<span class="folder" style="width: 24px; height: 24px;"></span>
|
||||
<h1>Index of @path@</h1>
|
||||
</header>
|
||||
<p><a href="file://@parent_path@"><span class="open-parent"></span>Open Parent Directory</a></p>
|
||||
<hr>
|
||||
@contents@
|
||||
<hr>
|
||||
</body>
|
||||
</html>
|
|
@ -1,23 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Error!</title>
|
||||
<style>
|
||||
h1 {
|
||||
display: inline;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
img {
|
||||
margin-right: 5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<img src="@resource_directory_url@/icons/32x32/msgbox-warning.png" alt="Warning" width="24" height="24">
|
||||
<h1>Failed to load @failed_url@</h1>
|
||||
</header>
|
||||
</body>
|
||||
</html>
|
|
@ -1,258 +0,0 @@
|
|||
body {
|
||||
font-family: system-ui, sans-serif;
|
||||
font-size: 10pt;
|
||||
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.split-view {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.split-view-container {
|
||||
max-height: calc(100% - 40px);
|
||||
min-height: 40px;
|
||||
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.split-view-separator {
|
||||
width: 100%;
|
||||
height: 5px;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
cursor: row-resize;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.tab-controls-container {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
|
||||
padding: 4px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.tab-controls {
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.tab-controls button {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
|
||||
float: left;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.tab-controls :first-child {
|
||||
border-radius: 0.5rem 0 0 0.5rem;
|
||||
}
|
||||
|
||||
.tab-controls :last-child {
|
||||
border-radius: 0 0.5rem 0.5rem 0;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
|
||||
display: none;
|
||||
border-radius: 0.5rem;
|
||||
|
||||
margin-top: 30px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
html {
|
||||
background-color: rgb(23, 23, 23);
|
||||
}
|
||||
|
||||
.split-view-separator {
|
||||
background-color: dimgray;
|
||||
}
|
||||
|
||||
.split-view-separator circle {
|
||||
fill: rgb(57, 57, 57);
|
||||
}
|
||||
|
||||
.tab-controls-container {
|
||||
background-color: rgb(57, 57, 57);
|
||||
}
|
||||
|
||||
.tab-controls button {
|
||||
color: white;
|
||||
background-color: rgb(43, 42, 50);
|
||||
}
|
||||
|
||||
.tab-controls button.active {
|
||||
background-color: rgb(22 100 219);
|
||||
}
|
||||
|
||||
.tab-controls button + button {
|
||||
border-left: 1px solid rgb(96, 96, 96);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.split-view-separator {
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
.split-view-separator circle {
|
||||
fill: white;
|
||||
}
|
||||
|
||||
.tab-controls-container {
|
||||
background-color: rgb(229, 229, 229);
|
||||
}
|
||||
|
||||
.tab-controls button {
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.tab-controls button.active {
|
||||
color: white;
|
||||
background-color: rgb(28, 138, 255);
|
||||
}
|
||||
|
||||
.tab-controls button + button {
|
||||
border-left: 1px solid rgb(242, 242, 242);
|
||||
}
|
||||
}
|
||||
|
||||
details > :not(:first-child) {
|
||||
display: list-item;
|
||||
list-style: none inside;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.hoverable {
|
||||
display: block;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.dom-editor {
|
||||
width: fit-content;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.hoverable:hover {
|
||||
background-color: #31383e;
|
||||
}
|
||||
|
||||
.selected {
|
||||
border: 1px dashed cyan;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.hoverable:hover {
|
||||
background-color: rgb(236, 236, 236);
|
||||
}
|
||||
|
||||
.selected {
|
||||
border: 1px dashed blue;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.console {
|
||||
font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.console-output {
|
||||
height: calc(100% - 75px);
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.console-input {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
padding: 4px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.console-input input {
|
||||
width: calc(100% - 60px);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.console-prompt {
|
||||
color: cyan;
|
||||
}
|
||||
|
||||
.console-input {
|
||||
background-color: rgb(57, 57, 57);
|
||||
}
|
||||
|
||||
.console-input input:focus {
|
||||
outline: 1px dashed cyan;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.console-prompt {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.console-input {
|
||||
background-color: rgb(229, 229, 229);
|
||||
}
|
||||
|
||||
.console-input input:focus {
|
||||
outline: 1px dashed blue;
|
||||
}
|
||||
}
|
||||
|
||||
.property-table {
|
||||
width: 100%;
|
||||
|
||||
table-layout: fixed;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.property-table th {
|
||||
position: sticky;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.property-table th,
|
||||
.property-table td {
|
||||
padding: 4px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.property-table th {
|
||||
background-color: rgb(57, 57, 57);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.property-table th {
|
||||
background-color: rgb(229, 229, 229);
|
||||
}
|
||||
}
|
|
@ -1,375 +0,0 @@
|
|||
let selectedTopTab = null;
|
||||
let selectedTopTabButton = null;
|
||||
|
||||
let selectedBottomTab = null;
|
||||
let selectedBottomTabButton = null;
|
||||
|
||||
let selectedDOMNode = null;
|
||||
|
||||
let consoleGroupStack = [];
|
||||
let consoleGroupNextID = 0;
|
||||
|
||||
let consoleHistory = [];
|
||||
let consoleHistoryIndex = 0;
|
||||
|
||||
const beginSplitViewDrag = () => {
|
||||
let inspectorTop = document.getElementById("inspector-top");
|
||||
let inspectorBottom = document.getElementById("inspector-bottom");
|
||||
let inspectorSeparator = document.getElementById("inspector-separator");
|
||||
|
||||
const windowHeight = window.innerHeight;
|
||||
const separatorHeight = inspectorSeparator.clientHeight;
|
||||
|
||||
const updateSplitView = event => {
|
||||
let position = Math.min(event.clientY, windowHeight - separatorHeight);
|
||||
position = Math.max(position, 0);
|
||||
|
||||
inspectorTop.style.height = `${position}px`;
|
||||
inspectorBottom.style.height = `${windowHeight - position - separatorHeight}px`;
|
||||
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
const endSplitViewDrag = () => {
|
||||
document.removeEventListener("mousemove", updateSplitView);
|
||||
document.removeEventListener("mouseup", endSplitViewDrag);
|
||||
document.body.style.cursor = "";
|
||||
};
|
||||
|
||||
document.addEventListener("mousemove", updateSplitView);
|
||||
document.addEventListener("mouseup", endSplitViewDrag);
|
||||
document.body.style.cursor = "row-resize";
|
||||
};
|
||||
|
||||
const selectTab = (tabButton, tabID, selectedTab, selectedTabButton) => {
|
||||
let tab = document.getElementById(tabID);
|
||||
|
||||
if (selectedTab === tab) {
|
||||
return selectedTab;
|
||||
}
|
||||
if (selectedTab !== null) {
|
||||
selectedTab.style.display = "none";
|
||||
selectedTabButton.classList.remove("active");
|
||||
}
|
||||
|
||||
tab.style.display = "block";
|
||||
tabButton.classList.add("active");
|
||||
|
||||
return tab;
|
||||
};
|
||||
|
||||
const selectTopTab = (tabButton, tabID) => {
|
||||
selectedTopTab = selectTab(tabButton, tabID, selectedTopTab, selectedTopTabButton);
|
||||
selectedTopTabButton = tabButton;
|
||||
};
|
||||
|
||||
const selectBottomTab = (tabButton, tabID) => {
|
||||
selectedBottomTab = selectTab(tabButton, tabID, selectedBottomTab, selectedBottomTabButton);
|
||||
selectedBottomTabButton = tabButton;
|
||||
};
|
||||
|
||||
let initialTopTabButton = document.getElementById("dom-tree-button");
|
||||
selectTopTab(initialTopTabButton, "dom-tree");
|
||||
|
||||
let initialBottomTabButton = document.getElementById("console-button");
|
||||
selectBottomTab(initialBottomTabButton, "console");
|
||||
|
||||
const scrollToElement = element => {
|
||||
// Include an offset to prevent the element being placed behind the fixed `tab-controls` header.
|
||||
const offset = 45;
|
||||
|
||||
let position = element.getBoundingClientRect().top;
|
||||
position += window.pageYOffset - offset;
|
||||
|
||||
window.scrollTo(0, position);
|
||||
};
|
||||
|
||||
inspector.loadDOMTree = tree => {
|
||||
let domTree = document.getElementById("dom-tree");
|
||||
domTree.innerHTML = atob(tree);
|
||||
|
||||
let domNodes = domTree.querySelectorAll(".hoverable");
|
||||
|
||||
for (let domNode of domNodes) {
|
||||
domNode.addEventListener("click", event => {
|
||||
inspectDOMNode(domNode);
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
domNodes = domTree.querySelectorAll(".editable");
|
||||
|
||||
for (let domNode of domNodes) {
|
||||
domNode.addEventListener("dblclick", event => {
|
||||
editDOMNode(domNode);
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
inspector.loadAccessibilityTree = tree => {
|
||||
let accessibilityTree = document.getElementById("accessibility-tree");
|
||||
accessibilityTree.innerHTML = atob(tree);
|
||||
};
|
||||
|
||||
inspector.inspectDOMNodeID = nodeID => {
|
||||
let domNodes = document.querySelectorAll(`[data-id="${nodeID}"]`);
|
||||
if (domNodes.length !== 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let domNode = domNodes[0]; domNode; domNode = domNode.parentNode) {
|
||||
if (domNode.tagName === "DETAILS") {
|
||||
domNode.setAttribute("open", "");
|
||||
}
|
||||
}
|
||||
|
||||
inspectDOMNode(domNodes[0]);
|
||||
scrollToElement(selectedDOMNode);
|
||||
};
|
||||
|
||||
inspector.clearInspectedDOMNode = () => {
|
||||
if (selectedDOMNode !== null) {
|
||||
selectedDOMNode.classList.remove("selected");
|
||||
selectedDOMNode = null;
|
||||
}
|
||||
};
|
||||
|
||||
inspector.createPropertyTables = (computedStyle, resolvedStyle, customProperties) => {
|
||||
const createPropertyTable = (tableID, properties) => {
|
||||
let oldTable = document.getElementById(tableID);
|
||||
|
||||
let newTable = document.createElement("tbody");
|
||||
newTable.setAttribute("id", tableID);
|
||||
|
||||
Object.keys(properties)
|
||||
.sort()
|
||||
.forEach(name => {
|
||||
let row = newTable.insertRow();
|
||||
|
||||
let nameColumn = row.insertCell();
|
||||
nameColumn.innerText = name;
|
||||
|
||||
let valueColumn = row.insertCell();
|
||||
valueColumn.innerText = properties[name];
|
||||
});
|
||||
|
||||
oldTable.parentNode.replaceChild(newTable, oldTable);
|
||||
};
|
||||
|
||||
createPropertyTable("computed-style-table", JSON.parse(computedStyle));
|
||||
createPropertyTable("resolved-style-table", JSON.parse(resolvedStyle));
|
||||
createPropertyTable("custom-properties-table", JSON.parse(customProperties));
|
||||
};
|
||||
|
||||
const inspectDOMNode = domNode => {
|
||||
if (selectedDOMNode === domNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
inspector.clearInspectedDOMNode();
|
||||
|
||||
domNode.classList.add("selected");
|
||||
selectedDOMNode = domNode;
|
||||
|
||||
inspector.inspectDOMNode(domNode.dataset.id, domNode.dataset.pseudoElement);
|
||||
};
|
||||
|
||||
const editDOMNode = domNode => {
|
||||
if (selectedDOMNode === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const domNodeID = selectedDOMNode.dataset.id;
|
||||
const type = domNode.dataset.nodeType;
|
||||
|
||||
selectedDOMNode.classList.remove("selected");
|
||||
|
||||
let input = document.createElement("input");
|
||||
input.classList.add("dom-editor");
|
||||
input.classList.add("selected");
|
||||
input.value = domNode.innerText;
|
||||
|
||||
const handleChange = () => {
|
||||
input.removeEventListener("change", handleChange);
|
||||
input.removeEventListener("blur", cancelChange);
|
||||
|
||||
if (type === "text" || type === "comment") {
|
||||
inspector.setDOMNodeText(domNodeID, input.value);
|
||||
} else if (type === "tag") {
|
||||
try {
|
||||
const element = document.createElement(input.value);
|
||||
inspector.setDOMNodeTag(domNodeID, input.value);
|
||||
} catch {
|
||||
cancelChange();
|
||||
}
|
||||
} else if (type === "attribute") {
|
||||
let element = document.createElement("div");
|
||||
element.innerHTML = `<div ${input.value}></div>`;
|
||||
|
||||
inspector.replaceDOMNodeAttribute(
|
||||
domNodeID,
|
||||
domNode.dataset.attributeName,
|
||||
element.children[0].attributes
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const cancelChange = () => {
|
||||
selectedDOMNode.classList.add("selected");
|
||||
input.parentNode.replaceChild(domNode, input);
|
||||
};
|
||||
|
||||
input.addEventListener("change", handleChange);
|
||||
input.addEventListener("blur", cancelChange);
|
||||
|
||||
domNode.parentNode.replaceChild(input, domNode);
|
||||
|
||||
setTimeout(() => {
|
||||
input.focus();
|
||||
|
||||
// FIXME: Invoke `select` when it isn't just stubbed out.
|
||||
// input.select();
|
||||
});
|
||||
};
|
||||
|
||||
const executeConsoleScript = consoleInput => {
|
||||
const script = consoleInput.value;
|
||||
|
||||
if (!/\S/.test(script)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (consoleHistory.length === 0 || consoleHistory[consoleHistory.length - 1] !== script) {
|
||||
consoleHistory.push(script);
|
||||
}
|
||||
|
||||
consoleHistoryIndex = consoleHistory.length;
|
||||
|
||||
inspector.executeConsoleScript(script);
|
||||
consoleInput.value = "";
|
||||
};
|
||||
|
||||
const setConsoleInputToPreviousHistoryItem = consoleInput => {
|
||||
if (consoleHistoryIndex === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
--consoleHistoryIndex;
|
||||
|
||||
const script = consoleHistory[consoleHistoryIndex];
|
||||
consoleInput.value = script;
|
||||
};
|
||||
|
||||
const setConsoleInputToNextHistoryItem = consoleInput => {
|
||||
if (consoleHistory.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const lastIndex = consoleHistory.length - 1;
|
||||
|
||||
if (consoleHistoryIndex < lastIndex) {
|
||||
++consoleHistoryIndex;
|
||||
|
||||
consoleInput.value = consoleHistory[consoleHistoryIndex];
|
||||
return;
|
||||
}
|
||||
|
||||
if (consoleHistoryIndex === lastIndex) {
|
||||
++consoleHistoryIndex;
|
||||
|
||||
consoleInput.value = "";
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const consoleParentGroup = () => {
|
||||
if (consoleGroupStack.length === 0) {
|
||||
return document.getElementById("console-output");
|
||||
}
|
||||
|
||||
const lastConsoleGroup = consoleGroupStack[consoleGroupStack.length - 1];
|
||||
return document.getElementById(`console-group-${lastConsoleGroup.id}`);
|
||||
};
|
||||
|
||||
const scrollConsoleToBottom = () => {
|
||||
let consoleOutput = document.getElementById("console-output");
|
||||
|
||||
// FIXME: It should be sufficient to scrollTo a y value of document.documentElement.offsetHeight,
|
||||
// but due to an unknown bug offsetHeight seems to not be properly updated after spamming
|
||||
// a lot of document changes.
|
||||
//
|
||||
// The setTimeout makes the scrollTo async and allows the DOM to be updated.
|
||||
setTimeout(function () {
|
||||
consoleOutput.scrollTo(0, 1_000_000_000);
|
||||
}, 0);
|
||||
};
|
||||
|
||||
inspector.appendConsoleOutput = output => {
|
||||
let parent = consoleParentGroup();
|
||||
|
||||
let element = document.createElement("p");
|
||||
element.innerHTML = atob(output);
|
||||
|
||||
parent.appendChild(element);
|
||||
scrollConsoleToBottom();
|
||||
};
|
||||
|
||||
inspector.clearConsoleOutput = () => {
|
||||
let consoleOutput = document.getElementById("console-output");
|
||||
consoleOutput.innerHTML = "";
|
||||
|
||||
consoleGroupStack = [];
|
||||
};
|
||||
|
||||
inspector.beginConsoleGroup = (label, startExpanded) => {
|
||||
let parent = consoleParentGroup();
|
||||
|
||||
const group = {
|
||||
id: ++consoleGroupNextID,
|
||||
label: label,
|
||||
};
|
||||
consoleGroupStack.push(group);
|
||||
|
||||
let details = document.createElement("details");
|
||||
details.id = `console-group-${group.id}`;
|
||||
details.open = startExpanded;
|
||||
|
||||
let summary = document.createElement("summary");
|
||||
summary.innerHTML = atob(label);
|
||||
|
||||
details.appendChild(summary);
|
||||
parent.appendChild(details);
|
||||
scrollConsoleToBottom();
|
||||
};
|
||||
|
||||
inspector.endConsoleGroup = () => {
|
||||
consoleGroupStack.pop();
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
let inspectorSeparator = document.getElementById("inspector-separator");
|
||||
inspectorSeparator.addEventListener("mousedown", beginSplitViewDrag);
|
||||
|
||||
let consoleInput = document.getElementById("console-input");
|
||||
consoleInput.focus();
|
||||
|
||||
consoleInput.addEventListener("keydown", event => {
|
||||
const UP_ARROW_KEYCODE = 38;
|
||||
const DOWN_ARROW_KEYCODE = 40;
|
||||
const RETURN_KEYCODE = 13;
|
||||
|
||||
if (event.keyCode === UP_ARROW_KEYCODE) {
|
||||
setConsoleInputToPreviousHistoryItem(consoleInput);
|
||||
event.preventDefault();
|
||||
} else if (event.keyCode === DOWN_ARROW_KEYCODE) {
|
||||
setConsoleInputToNextHistoryItem(consoleInput);
|
||||
event.preventDefault();
|
||||
} else if (event.keyCode === RETURN_KEYCODE) {
|
||||
executeConsoleScript(consoleInput);
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
inspector.inspectorLoaded();
|
||||
});
|
|
@ -1,97 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>New Tab</title>
|
||||
<style>
|
||||
body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
img {
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
input[type=search] {
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#search-buttons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<br>
|
||||
<img src="../../icons/32x32/app-browser.png" width="64" height="64"><br><br>
|
||||
<form>
|
||||
<input type="search" name="q" id="user_query"><br><br>
|
||||
<div id="search-buttons">
|
||||
<button type="button" onclick="search('bing')">Bing</button>
|
||||
<button type="button" onclick="search('duckduckgo')">DuckDuckGo</button>
|
||||
<button type="button" onclick="search('github')">GitHub</button>
|
||||
<button type="button" onclick="search('google')">Google</button>
|
||||
<button type="button" onclick="search('wiby')">Wiby</button>
|
||||
<button type="button" onclick="search('yandex')">Yandex</button>
|
||||
</div>
|
||||
</form>
|
||||
<br><br>
|
||||
<p>Your user agent is: <b><span id="ua"></span></b></p>
|
||||
<p>This page loaded in <b><span id="loadtime"></span></b> ms</p>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
document.getElementById("ua").innerHTML = navigator.userAgent;
|
||||
document.getElementById("loadtime").innerHTML = performance.now();
|
||||
});
|
||||
|
||||
function search(searchEngine) {
|
||||
let query = document.getElementById("user_query").value;
|
||||
|
||||
if (!query) {
|
||||
return;
|
||||
}
|
||||
|
||||
let url;
|
||||
if (searchEngine == "bing") {
|
||||
url = new URL("https://www.bing.com/search");
|
||||
url.searchParams.set("q", query);
|
||||
} else if (searchEngine == "duckduckgo") {
|
||||
url = new URL("https://duckduckgo.com");
|
||||
url.searchParams.set("q", query);
|
||||
} else if (searchEngine == "github") {
|
||||
url = new URL("https://github.com/search");
|
||||
url.searchParams.set("q", query);
|
||||
} else if (searchEngine == "google") {
|
||||
url = new URL("https://google.com/search");
|
||||
url.searchParams.set("q", query);
|
||||
} else if (searchEngine == "wiby") {
|
||||
url = new URL("https://wiby.me");
|
||||
url.searchParams.set("q", query);
|
||||
} else if (searchEngine == "yandex") {
|
||||
url = new URL("https://yandex.com/search");
|
||||
url.searchParams.set("text", query);
|
||||
}
|
||||
window.location.href = url.toString();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue