From 9ccb8fce3104cb5b400a6e4c2c86a8210fe02368 Mon Sep 17 00:00:00 2001 From: Powei Feng Date: Thu, 26 Oct 2023 14:14:01 -0700 Subject: [PATCH] matdbg: UI refresh (#7301) --- libs/matdbg/CMakeLists.txt | 4 +- libs/matdbg/src/DebugServer.cpp | 99 ++--- libs/matdbg/web/{experiment => }/api.js | 0 libs/matdbg/web/{experiment => }/app.js | 4 + libs/matdbg/web/experiment/index.html | 23 -- libs/matdbg/web/index.html | 109 +---- libs/matdbg/web/script.js | 516 ------------------------ libs/matdbg/web/style.css | 110 ----- 8 files changed, 66 insertions(+), 799 deletions(-) rename libs/matdbg/web/{experiment => }/api.js (100%) rename libs/matdbg/web/{experiment => }/app.js (99%) delete mode 100644 libs/matdbg/web/experiment/index.html delete mode 100644 libs/matdbg/web/script.js delete mode 100644 libs/matdbg/web/style.css diff --git a/libs/matdbg/CMakeLists.txt b/libs/matdbg/CMakeLists.txt index 0dafe5c71d..e580585480 100644 --- a/libs/matdbg/CMakeLists.txt +++ b/libs/matdbg/CMakeLists.txt @@ -41,8 +41,8 @@ set(SRCS set(RESOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(RESOURCE_BINS - ${CMAKE_CURRENT_SOURCE_DIR}/web/style.css - ${CMAKE_CURRENT_SOURCE_DIR}/web/script.js + ${CMAKE_CURRENT_SOURCE_DIR}/web/api.js + ${CMAKE_CURRENT_SOURCE_DIR}/web/app.js ${CMAKE_CURRENT_SOURCE_DIR}/web/index.html ) diff --git a/libs/matdbg/src/DebugServer.cpp b/libs/matdbg/src/DebugServer.cpp index d5164a90c1..2416931e66 100644 --- a/libs/matdbg/src/DebugServer.cpp +++ b/libs/matdbg/src/DebugServer.cpp @@ -50,13 +50,28 @@ using utils::FixedCapacityVector; // serves files directly from the source code tree. #define SERVE_FROM_SOURCE_TREE 0 -// When set to 1, we will serve an experimental frontend, which will potentially replace the current -// frontend when ready. -#define EXPERIMENTAL_WEB_FRAMEWORK 0 +#if SERVE_FROM_SOURCE_TREE + +namespace { +std::string const BASE_URL = "libs/matdbg/web"; +} // anonymous + +#else -#if !SERVE_FROM_SOURCE_TREE #include "matdbg_resources.h" -#endif +#include + +namespace { + +struct Asset { + std::string_view mime; + std::string_view data; +}; +std::unordered_map ASSET_MAP; + +} // anonymous + +#endif // SERVE_FROM_SOURCE_TREE namespace filament::matdbg { @@ -74,14 +89,6 @@ std::string_view const DebugServer::kErrorHeader = "HTTP/1.1 404 Not Found\r\nContent-Type: %s\r\n" "Connection: close\r\n\r\n"; -#if EXPERIMENTAL_WEB_FRAMEWORK - -namespace { - -std::string const BASE_URL = "libs/matdbg/web/experiment"; - -} // anonymous - class FileRequestHandler : public CivetHandler { public: FileRequestHandler(DebugServer* server) : mServer(server) {} @@ -92,66 +99,44 @@ public: if (uri == "/") { uri = "/index.html"; } + +#if SERVE_FROM_SOURCE_TREE if (uri == "/index.html" || uri == "/app.js" || uri == "/api.js") { mg_send_file(conn, (BASE_URL + uri).c_str()); return true; } - slog.e << "DebugServer: bad request at line " << __LINE__ << ": " << uri << io::endl; - return false; - } -private: - DebugServer* mServer; -}; - #else -class FileRequestHandler : public CivetHandler { -public: - FileRequestHandler(DebugServer* server) : mServer(server) {} - bool handleGet(CivetServer *server, struct mg_connection *conn) { - auto const& kSuccessHeader = DebugServer::kSuccessHeader; - - const struct mg_request_info* request = mg_get_request_info(conn); - std::string uri(request->request_uri); - if (uri == "/" || uri == "/index.html") { - #if SERVE_FROM_SOURCE_TREE - mg_send_file(conn, "libs/matdbg/web/index.html"); - #else - mg_printf(conn, kSuccessHeader.data(), "text/html"); - mg_write(conn, mServer->mHtml.c_str(), mServer->mHtml.size()); - #endif - return true; - } - if (uri == "/style.css") { - #if SERVE_FROM_SOURCE_TREE - mg_send_file(conn, "libs/matdbg/web/style.css"); - #else - mg_printf(conn, kSuccessHeader.data(), "text/css"); - mg_write(conn, mServer->mCss.c_str(), mServer->mCss.size()); - #endif - return true; - } - if (uri == "/script.js") { - #if SERVE_FROM_SOURCE_TREE - mg_send_file(conn, "libs/matdbg/web/script.js"); - #else - mg_printf(conn, kSuccessHeader.data(), "text/javascript"); - mg_write(conn, mServer->mJavascript.c_str(), mServer->mJavascript.size()); - #endif + auto const& asset_itr = ASSET_MAP.find(uri); + if (asset_itr != ASSET_MAP.end()) { + auto const& mime = asset_itr->second.mime; + auto const& data = asset_itr->second.data; + mg_printf(conn, kSuccessHeader.data(), mime.data()); + mg_write(conn, data.data(), data.size()); return true; } +#endif slog.e << "DebugServer: bad request at line " << __LINE__ << ": " << uri << io::endl; return false; } private: DebugServer* mServer; }; -#endif DebugServer::DebugServer(Backend backend, int port) : mBackend(backend) { + #if !SERVE_FROM_SOURCE_TREE - mHtml = CString((const char*) MATDBG_RESOURCES_INDEX_DATA, MATDBG_RESOURCES_INDEX_SIZE - 1); - mJavascript = CString((const char*) MATDBG_RESOURCES_SCRIPT_DATA, MATDBG_RESOURCES_SCRIPT_SIZE - 1); - mCss = CString((const char*) MATDBG_RESOURCES_STYLE_DATA, MATDBG_RESOURCES_STYLE_SIZE - 1); + ASSET_MAP["/index.html"] = { + .mime = "text/html", + .data = {(char const*) MATDBG_RESOURCES_INDEX_DATA}, + }; + ASSET_MAP["/app.js"] = { + .mime = "text/javascript", + .data = {(char const*) MATDBG_RESOURCES_APP_DATA}, + }; + ASSET_MAP["/api.js"] = { + .mime = "text/javascript", + .data = {(char const*) MATDBG_RESOURCES_API_DATA}, + }; #endif // By default the server spawns 50 threads so we override this to 10. According to the civetweb diff --git a/libs/matdbg/web/experiment/api.js b/libs/matdbg/web/api.js similarity index 100% rename from libs/matdbg/web/experiment/api.js rename to libs/matdbg/web/api.js diff --git a/libs/matdbg/web/experiment/app.js b/libs/matdbg/web/app.js similarity index 99% rename from libs/matdbg/web/experiment/app.js rename to libs/matdbg/web/app.js index cf9d518c14..fef9c422c4 100644 --- a/libs/matdbg/web/experiment/app.js +++ b/libs/matdbg/web/app.js @@ -242,6 +242,10 @@ class CodeViewer extends LitElement { } _rebuild() { + if (!this.active || !this.modified) { + console.log('Called rebuild while variant is inactive or unmodified'); + return; + } this.dispatchEvent(new CustomEvent( 'rebuild-shader', {detail: this.editor.getValue(), bubbles: true, composed: true} diff --git a/libs/matdbg/web/experiment/index.html b/libs/matdbg/web/experiment/index.html deleted file mode 100644 index d49468873b..0000000000 --- a/libs/matdbg/web/experiment/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - Filament Debugger - - - - - - - - - - - - - diff --git a/libs/matdbg/web/index.html b/libs/matdbg/web/index.html index 9474348e0c..d49468873b 100644 --- a/libs/matdbg/web/index.html +++ b/libs/matdbg/web/index.html @@ -1,96 +1,23 @@ - + Filament Debugger - - - - - - -
matdbg
- -
- -
-
-
- -
 
- - - - - - - - - + + + + + + + + + + + diff --git a/libs/matdbg/web/script.js b/libs/matdbg/web/script.js deleted file mode 100644 index 5a7df5b557..0000000000 --- a/libs/matdbg/web/script.js +++ /dev/null @@ -1,516 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - -*/ -const kMonacoBaseUrl = 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.25.2/min/'; -const kUntitledPlaceholder = "untitled"; - -const materialList = document.getElementById("material-list"); -const materialDetail = document.getElementById("material-detail"); -const header = document.querySelector("header"); -const footer = document.querySelector("footer"); -const shaderSource = document.getElementById("shader-source"); -const matDetailTemplate = document.getElementById("material-detail-template"); -const matListTemplate = document.getElementById("material-list-template"); - -const STATUS_LOOP_TIMEOUT = 3000; - -const gMaterialDatabase = {}; - -let gEditor = null; -let gCurrentMaterial = "00000000"; -let gCurrentLanguage = "glsl"; -let gCurrentShader = { matid: "00000000", glindex: 0 }; -let gEditorIsLoading = false; - -require.config({ paths: { "vs": `${kMonacoBaseUrl}vs` }}); - -window.MonacoEnvironment = { - getWorkerUrl: function() { - return `data:text/javascript;charset=utf-8,${encodeURIComponent(` - self.MonacoEnvironment = { - baseUrl: '${kMonacoBaseUrl}' - }; - importScripts('${kMonacoBaseUrl}vs/base/worker/workerMain.js');` - )}`; - } -}; - -function getShaderAPI(selection) { - if (!selection) { - selection = gCurrentShader; - } - if ("glindex" in selection) return "opengl"; - if ("vkindex" in selection) return "vulkan"; - if ("metalindex" in selection) return "metal"; - return "error"; -} - -function rebuildMaterial() { - let api = 0, index = -1; - - const shader = getShaderRecord(gCurrentShader); - const shaderApi = getShaderAPI(); - - switch (shaderApi) { - case "opengl": api = 1; index = gCurrentShader.glindex; break; - case "vulkan": api = 2; index = gCurrentShader.vkindex; break; - case "metal": api = 3; index = gCurrentShader.metalindex; break; - } - - if (shaderApi === "vulkan") { - if (gCurrentLanguage === "glsl") { - delete shader["spirv"]; - } else if (gCurrentLanguage === "spirv") { - delete shader["glsl"]; - } - } - - const editedText = shader[gCurrentLanguage]; - const req = new XMLHttpRequest(); - req.open('POST', '/api/edit'); - req.send(`${gCurrentShader.matid} ${api} ${index} ${editedText}`); -} - -document.querySelector("body").addEventListener("click", (evt) => { - const anchor = evt.target.closest("a"); - if (!anchor) { - return; - } - - // Handle selection of a material. - if (anchor.classList.contains("material")) { - selectMaterial(anchor.dataset.matid, true); - return; - } - - // Handle selection of a shader. - if (anchor.classList.contains("shader")) { - selectShader(anchor.dataset); - return; - } - - // Handle a rebuild. - if (anchor.classList.contains("rebuild")) { - rebuildMaterial(); - return; - } - - // Handle language selection. - for (const lang of "glsl spirv msl".split(" ")) { - if (anchor.classList.contains(lang)) { - gCurrentLanguage = lang; - selectShader(gCurrentShader); - return; - } - } -}); - -// Handle Ctrl+Arrow for fast keyboard navigation between shader variants and materials. Either the -// materialStep or shaderStep argument can be non-zero (not both) and they must be -1, 0, or +1. -// TODO: this function could be vastly simplified by changing the format of the shader selector. -function selectNextShader(materialStep, shaderStep) { - if (materialStep !== 0) { - const matids = getDisplayedMaterials().map(m => m.matid).filter(m => m); - const currentIndex = matids.indexOf(gCurrentMaterial); - const nextIndex = currentIndex + materialStep; - if (nextIndex >= 0 && nextIndex < matids.length) { - selectMaterial(matids[nextIndex], true); - } - return; - } - const material = gMaterialDatabase[gCurrentMaterial]; - const variants = []; - let currentIndex = 0; - for (const [index, shader] of material.opengl.entries()) { - if (index === gCurrentShader.glindex) currentIndex = variants.length; - variants.push({ matid, glindex: index }); - } - for (const [index, shader] of material.vulkan.entries()) { - if (index === gCurrentShader.vkindex) currentIndex = variants.length; - variants.push({ matid, vkindex: index }); - } - for (const [index, shader] of material.metal.entries()) { - if (index === gCurrentShader.metalindex) currentIndex = variants.length; - variants.push({ matid, metalindex: index }); - } - const nextIndex = currentIndex + shaderStep; - if (nextIndex >= 0 && nextIndex < variants.length) { - selectShader(variants[nextIndex]); - } -} - -function fetchMaterial(matid) { - fetch(`api/material?matid=${matid}`).then(function(response) { - return response.json(); - }).then(function(matInfo) { - if (matid in gMaterialDatabase) { - return; - } - matInfo.matid = matid; - gMaterialDatabase[matid] = matInfo; - renderMaterialList(); - }); -} - -function queryActiveShaders() { - if (!isConnected()) { - return; - } - fetch("api/active").then(function(response) { - return response.json(); - }).then(function(activeMaterials) { - // The only active materials are the ones with active variants. - for (matid in gMaterialDatabase) { - const material = gMaterialDatabase[matid]; - material.active = false; - } - for (matid in activeMaterials) { - const material = gMaterialDatabase[matid]; - const activeBackend = activeMaterials[matid][0]; - const activeShaders = activeMaterials[matid].slice(1); - for (const shader of material[activeBackend]) { - shader.active = activeShaders.indexOf(shader.variant) > -1; - material.active = material.active || shader.active; - } - } - renderMaterialList(); - renderMaterialDetail(); - }) - .catch(error => { - // This can occur if the JSON is invalid. - console.error(error); - }); -} - -function isConnected() { - return footer.innerText == 'connected'; -} - -function onConnected() { - footer.innerText = 'connected'; - fetch("api/matids").then(function(response) { - return response.json(); - }).then(function(matInfo) { - for (matid of matInfo) { - if (!(matid in gMaterialDatabase)) { - fetchMaterial(matid); - } - } - }); -} - -function onDisconnected() { - footer.innerText = 'not connected'; - for (matid in gMaterialDatabase) { - const material = gMaterialDatabase[matid]; - material.active = false; - for (const shader of material.opengl) shader.active = false; - for (const shader of material.vulkan) shader.active = false; - for (const shader of material.metal) shader.active = false; - } - renderMaterialList(); - renderMaterialDetail(); -} - -function statusLoop() { - // This is a hanging get except for when transition from disconnected to connected, which - // should return immediately. - fetch("api/status" + (isConnected() ? '' : '?firstTime')) - .then(async (response) => { - const matid = await response.text(); - // A first-time request returned successfully - if (matid === '0') { - onConnected(); - } else if (matid != '1') { - fetchMaterial(matid); - } // else matid == '1' and it's a no-op, we just loop again. - statusLoop(); - }) - .catch(err => { - onDisconnected(); - setTimeout(statusLoop, STATUS_LOOP_TIMEOUT) - }); -} - -function fetchMaterials() { - fetch("api/materials").then(function(response) { - return response.json(); - }).then(function(matJson) { - for (const matInfo of matJson) { - if (matInfo.matid in gMaterialDatabase) { - continue; - } - gMaterialDatabase[matInfo.matid] = matInfo; - } - selectMaterial(matJson[0].matid, true); - }); -} - -function fetchShader(selection, matinfo, onDone) { - let query, target, index; - switch (getShaderAPI(selection)) { - case "opengl": - index = parseInt(selection.glindex); - query = `type=${gCurrentLanguage}&glindex=${index}`; - target = matinfo.opengl[index]; - break; - case "vulkan": - index = parseInt(selection.vkindex); - query = `type=${gCurrentLanguage}&vkindex=${index}`; - target = matinfo.vulkan[index]; - break; - case "metal": - index = parseInt(selection.metalindex); - query = `type=${gCurrentLanguage}&metalindex=${index}`; - target = matinfo.metal[index]; - break; - } - fetch(`api/shader?matid=${matinfo.matid}&${query}`).then(function(response) { - return response.text(); - }).then(function(shaderText) { - target[gCurrentLanguage] = shaderText; - onDone(); - }); -} - -function getDisplayedMaterials() { - const items = []; - - // Names need not be unique, so we display a numeric suffix for non-unique names. - // To achieve stable ordering of anonymous materials, we first sort by matid. - const labels = new Set(); - const matids = Object.keys(gMaterialDatabase).sort(); - const duplicatedLabels = {}; - for (const matid of matids) { - const name = gMaterialDatabase[matid].name || kUntitledPlaceholder; - if (labels.has(name)) { - duplicatedLabels[name] = 0; - } else { - labels.add(name); - } - } - - // Build a list of objects to pass into the template string. - for (const matid of matids) { - const item = Object.assign({}, gMaterialDatabase[matid]); - item.classes = matid === gCurrentMaterial ? "current " : ""; - if (!item.active) { - item.classes += "inactive " - } - item.domain = item.shading.material_domain === "surface" ? "surface" : "postpro"; - item.is_material = true; - - const name = item.name || kUntitledPlaceholder; - if (name in duplicatedLabels) { - const index = duplicatedLabels[name]; - item.name = `${name} (${index})`; - duplicatedLabels[name] = index + 1; - } else { - item.name = name; - } - - items.push(item); - } - - // The template takes a flat list of items, so here we insert items for section headers using - // blank names, which causes them to sort to the top of their respective sections. - const sectionLabel = {"is_label": true, "name": ""}; - items.push(Object.assign({"label": "Surface materials", "domain": "surface"}, sectionLabel)); - items.push(Object.assign({"label": "PostProcess materials", "domain": "postpro"}, sectionLabel)); - - // Next, sort all materials and section headers. - items.sort((a, b) => { - if (a.domain > b.domain) return -1; - if (a.domain < b.domain) return +1; - if (a.name < b.name) return -1; - if (a.name > b.name) return +1; - return 0; - }); - return items; -} - -function renderMaterialList() { - const items = getDisplayedMaterials(); - materialList.innerHTML = Mustache.render(matListTemplate.innerHTML, { "item": items } ); -} - -function updateClassList(array, indexProperty, selectedIndex) { - for (let item of array) { - const current = parseInt(item[indexProperty]) === selectedIndex; - item.classes = current ? "current " : ""; - if (!item.active) { - item.classes += "inactive " - } - } -} - -function renderMaterialDetail() { - const mat = gMaterialDatabase[gCurrentMaterial]; - const ok = mat.matid === gCurrentShader.matid; - updateClassList(mat.opengl, "index", ok ? parseInt(gCurrentShader.glindex) : -1); - updateClassList(mat.vulkan, "index", ok ? parseInt(gCurrentShader.vkindex) : -1); - updateClassList(mat.metal, "index", ok ? parseInt(gCurrentShader.metalindex) : -1); - const item = Object.assign({}, mat); - if (item.shading.material_domain !== "surface") { - delete item.shading; - } - materialDetail.innerHTML = Mustache.render(matDetailTemplate.innerHTML, item); -} - -function getShaderRecord(selection) { - const mat = gMaterialDatabase[gCurrentMaterial]; - if (selection.glindex >= 0) return mat.opengl[parseInt(selection.glindex)]; - if (selection.vkindex >= 0) return mat.vulkan[parseInt(selection.vkindex)]; - if (selection.metalindex >= 0) return mat.metal[parseInt(selection.metalindex)]; - return null; -} - -function renderShaderStatus() { - const shader = getShaderRecord(gCurrentShader); - let statusString = ""; - if (shader) { - const glsl = "glsl " + (gCurrentLanguage === "glsl" ? "active" : ""); - const msl = "msl " + (gCurrentLanguage === "msl" ? "active" : ""); - const spirv = "spirv " + (gCurrentLanguage === "spirv" ? "active" : ""); - switch (getShaderAPI()) { - case "opengl": - statusString += `   [GLSL]`; - break; - case "metal": - statusString += `   [MSL]`; - break; - case "vulkan": - statusString += `   [GLSL]`; - statusString += `   [SPIRV]`; - break; - } - if (shader.modified && gCurrentLanguage !== "spirv") { - statusString += "   [rebuild]"; - } - if (!shader.active) { - statusString += "   selected variant is inactive "; - } - } - header.innerHTML = "matdbg" + statusString; -} - -function selectShader(selection) { - const shader = getShaderRecord(selection); - if (!shader) { - console.error("Shader not yet available.") - return; - } - - // Change the current language selection if necessary. - switch (getShaderAPI(selection)) { - case "opengl": - if (gCurrentLanguage !== "glsl") { - gCurrentLanguage = "glsl"; - } - break; - case "vulkan": - if (gCurrentLanguage !== "spirv" && gCurrentLanguage !== "glsl") { - gCurrentLanguage = "spirv"; - } - break; - case "metal": - if (gCurrentLanguage !== "msl") { - gCurrentLanguage = "msl"; - } - break; - } - - const showShaderSource = () => { - gCurrentShader = selection; - gCurrentShader.matid = gCurrentMaterial; - renderMaterialDetail(); - gEditorIsLoading = true; - gEditor.setValue(shader[gCurrentLanguage]); - gEditorIsLoading = false; - shaderSource.style.visibility = "visible"; - renderShaderStatus(); - }; - if (!shader[gCurrentLanguage]) { - const matInfo = gMaterialDatabase[gCurrentMaterial]; - fetchShader(selection, matInfo, showShaderSource); - } else { - showShaderSource(); - } -} - -function onEdit(changes) { - if (gEditorIsLoading) { - return; - } - const shader = getShaderRecord(gCurrentShader); - if (!shader) { - return; - } - if (!shader.modified) { - shader.modified = true; - renderShaderStatus(); - } - shader[gCurrentLanguage] = gEditor.getValue(); -} - -function selectMaterial(matid, selectFirstShader) { - gCurrentMaterial = matid; - renderMaterialList(); - renderMaterialDetail(); - if (selectFirstShader) { - const mat = gMaterialDatabase[gCurrentMaterial]; - const selection = { matid }; - if (mat.opengl.length > 0) selection.glindex = 0; - else if (mat.vulkan.length > 0) selection.vkindex = 0; - else if (mat.metal.length > 0) selection.metalindex = 0; - selectShader(selection); - } -} - -function init() { - require(["vs/editor/editor.main"], function () { - const KeyMod = monaco.KeyMod, KeyCode = monaco.KeyCode; - gEditor = monaco.editor.create(shaderSource, { - value: "", - language: "cpp", - scrollBeyondLastLine: false, - readOnly: false, - minimap: { enabled: false } - }); - gEditor.onDidChangeModelContent((e) => { onEdit(e.changes); }); - - gEditor.addCommand(KeyMod.CtrlCmd | KeyCode.KEY_S, () => rebuildMaterial()); - - gEditor.addCommand(KeyMod.Shift | KeyMod.WinCtrl | KeyCode.UpArrow, () => selectNextShader(-1, 0)); - gEditor.addCommand(KeyMod.Shift | KeyMod.WinCtrl | KeyCode.DownArrow, () => selectNextShader(+1, 0)); - gEditor.addCommand(KeyMod.Shift | KeyMod.WinCtrl | KeyCode.LeftArrow, () => selectNextShader(0, -1)); - gEditor.addCommand(KeyMod.Shift | KeyMod.WinCtrl | KeyCode.RightArrow, () => selectNextShader(0, +1)); - - fetchMaterials(); - }); - - Mustache.parse(matDetailTemplate.innerHTML); - Mustache.parse(matListTemplate.innerHTML); - - statusLoop(); - - // Poll for active shaders once every second. - // Take care not to poll more frequently than the frame rate. Active variants are determined - // by the list of variants that were fetched between this query and the previous query. - setInterval(queryActiveShaders, 1000); -} - -init(); diff --git a/libs/matdbg/web/style.css b/libs/matdbg/web/style.css deleted file mode 100644 index 05e46e6364..0000000000 --- a/libs/matdbg/web/style.css +++ /dev/null @@ -1,110 +0,0 @@ -html, body, .viewport { - width: 100%; - height: 100%; - margin: 0; -} - -body { - font-family: 'Lexend Deca', sans-serif; - overflow: hidden; -} - -a, a:visited { - text-decoration: none; - color: #567; - cursor: pointer; -} - -a:hover, a.current { - font-weight: bold; - color: #07f; -} - -a.status_button { - color: #e4e682; -} - -a.status_button.active { - color: #fff; -} - -span.warning { - color: black; - background: orange; - font-size: small; -} - -a.inactive { - color: #aaa; -} - -a.inactive.current { - color: #5af; -} - -pre { - font-family: Menlo, Monaco, "Courier New", monospace; -} - -.vbox { - display: flex; - flex-direction: column; -} - -.scrollable { - position: relative; - overflow-y: scroll; -} - -.scrollable > * { - position: absolute; -} - -.squishy { - flex-grow: 1; -} - -.stretchy { - flex-grow: 1; -} - -.hbox { - display: flex; - flex-direction: row; -} - -.space-between { - justify-content: space-between; -} - -header, footer { - height: 26px; - background: cornflowerblue; - padding: 5px 0 0 5px; -} - -.main { - flex: 1; -} - -article { - flex: 5; - border-top: solid 2px; - border-bottom: solid 2px; - visibility: hidden; -} - -nav { - border: solid 2px; - font-size: 12px; - flex: 1; -} - -nav > *:first-child { - border-bottom: solid 2px; -} - -nav > * { - padding-left: 5px; - padding-right: 5px; -}