diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2022-05-21 11:01:02 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2022-05-23 11:53:38 +0200 |
| commit | ecb7480009671f03b559ca19b0f4507f9e98e8e2 (patch) | |
| tree | 7c0e76d54763df38b07defd26e9e8394a0d29a7f | |
| parent | c06b338683a7a14ed2e9db22c5b5dae9c5fa5db6 (diff) | |
pkg/html/pages: switch to go:embed
We use clumsy generate scripts that embed some static files.
Switch to the new go:embed thing (added in Go 1.16):
https://pkg.go.dev/embed
It's much nicer, does not require separate generate step
and does not lead to additional diffs in code reviews.
go:embed can only embed "files read from the package directory or subdirectories",
so we need to move these assets to the package dir.
| -rw-r--r-- | Makefile | 2 | ||||
| l---------[-rw-r--r--] | dashboard/app/static/common.js | 102 | ||||
| l---------[-rw-r--r--] | dashboard/app/static/style.css | 301 | ||||
| -rw-r--r-- | pkg/html/pages/common.js | 101 | ||||
| -rwxr-xr-x | pkg/html/pages/gen.sh | 14 | ||||
| -rw-r--r-- | pkg/html/pages/pages.go | 9 | ||||
| -rw-r--r-- | pkg/html/pages/style.css (renamed from pkg/html/pages/generated.go) | 108 |
7 files changed, 111 insertions, 526 deletions
@@ -238,7 +238,7 @@ generate: $(MAKE) format generate_go: format_cpp - $(GO) generate ./pkg/csource ./executor ./pkg/ifuzz ./pkg/build ./pkg/html/pages + $(GO) generate ./pkg/csource ./executor ./pkg/ifuzz ./pkg/build generate_fidl: ifeq ($(TARGETOS),fuchsia) diff --git a/dashboard/app/static/common.js b/dashboard/app/static/common.js index 95e6c8f61..7e926878f 100644..120000 --- a/dashboard/app/static/common.js +++ b/dashboard/app/static/common.js @@ -1,101 +1 @@ -// Copyright 2018 syzkaller project authors. All rights reserved. -// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. - -function sortTable(item, colName, conv, desc = false) { - table = item.parentNode.parentNode.parentNode.parentNode; - rows = table.rows; - col = findColumnByName(rows[0].getElementsByTagName("th"), colName); - values = []; - for (i = 1; i < rows.length; i++) - values.push([conv(rows[i].getElementsByTagName("td")[col].textContent), rows[i]]); - if (desc) - desc = !isSorted(values.slice().reverse()) - else - desc = isSorted(values); - values.sort(function(a, b) { - if (a[0] == b[0]) return 0; - if (desc && a[0] > b[0] || !desc && a[0] < b[0]) return -1; - return 1; - }); - for (i = 0; i < values.length; i++) - table.tBodies[0].appendChild(values[i][1]); - return false; -} - -function findColumnByName(headers, colName) { - for (i = 0; i < headers.length; i++) { - if (headers[i].textContent == colName) - return i; - } - return 0; -} - -function isSorted(values) { - for (i = 0; i < values.length - 1; i++) { - if (values[i][0] > values[i + 1][0]) - return false; - } - return true; -} - -function textSort(v) { return v == "" ? "zzz" : v.toLowerCase(); } -function numSort(v) { return -parseInt(v); } -function floatSort(v) { return -parseFloat(v); } -function reproSort(v) { return v == "C" ? 0 : v == "syz" ? 1 : 2; } -function patchedSort(v) { return v == "" ? -1 : parseInt(v); } -function lineSort(v) { return -v.split(/\r\n|\r|\n/g).length } - -function timeSort(v) { - if (v == "now") - return 0; - m = v.indexOf('m'); - h = v.indexOf('h'); - d = v.indexOf('d'); - if (m > 0 && h < 0) - return parseInt(v); - if (h > 0 && m > 0) - return parseInt(v) * 60 + parseInt(v.substring(h + 1)); - if (d > 0 && h > 0) - return parseInt(v) * 60 * 24 + parseInt(v.substring(d + 1)) * 60; - if (d > 0) - return parseInt(v) * 60 * 24; - return 1000000000; -} - - - -function findAncestorByClass (el, cls) { - while ((el = el.parentElement) && !el.classList.contains(cls)); - return el; -} - -function deleteInputGroup(node) { - group = findAncestorByClass(node, "input-group") - values = findAncestorByClass(group, "input-values") - if (!values) { - return false - } - count = values.querySelectorAll('.input-group').length - if (count == 1) { - // If it's the only input, just clear it. - input = group.querySelector('input') - input.value = "" - } else { - group.remove() - } - return false -} - -function addInputGroup(node) { - values = findAncestorByClass(node, "input-values") - groups = values.querySelectorAll(".input-group") - if (groups.length == 0) { - // Something strange has happened. - return false - } - lastGroup = groups[groups.length - 1] - newGroup = lastGroup.cloneNode(true) - newGroup.querySelector('input').value = "" - values.insertBefore(newGroup, lastGroup.nextSibling) - return false -} +../../../pkg/html/pages/common.js
\ No newline at end of file diff --git a/dashboard/app/static/style.css b/dashboard/app/static/style.css index 7a2ca851a..08a4fd05b 100644..120000 --- a/dashboard/app/static/style.css +++ b/dashboard/app/static/style.css @@ -1,300 +1 @@ -#topbar { - padding: 5px 10px; - background: #E0EBF5; -} - -#topbar a { - color: #375EAB; - text-decoration: none; -} - -h1, h2, h3, h4 { - margin: 0; - padding: 0; - color: #375EAB; - font-weight: bold; -} - -.navigation_tab { - border: 1px solid black; - padding: 4px; - margin: 4px; -} - -.navigation_tab_selected { - font-weight: bold; - border: 2px solid black; - padding: 4px; - margin: 4px; -} - -.position_table .navigation { - padding-top: 15px; - padding-bottom: 6px; -} - -table { - border: 1px solid #ccc; - margin: 20px 5px; - border-collapse: collapse; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; -} - -table caption { - font-weight: bold; -} - -table td, table th { - vertical-align: top; - padding: 2px 8px; - text-overflow: ellipsis; - overflow: hidden; -} - -.namespace { - font-weight: bold; - font-size: large; - color: #375EAB; -} - -.position_table { - border: 0px; - margin: 0px; - width: 100%; - border-collapse: collapse; -} - -.position_table td, .position_table tr { - vertical-align: center; - padding: 0px; -} - -.position_table .namespace_td { - width: 100%; - padding-top: 10px; - padding-left: 20px; -} - -.position_table .search { - text-align: right; -} - -.list_table td, .list_table th { - border-left: 1px solid #ccc; -} - -.list_table th { - background: #F4F4F4; -} - -.list_table tr:nth-child(2n) { - background: #F4F4F4; -} - -.list_table tr:hover { - background: #ffff99; -} - -.list_table .namespace { - width: 100pt; - max-width: 100pt; -} - -.list_table .title { - width: 350pt; - max-width: 350pt; -} - -.list_table .commit_list { - width: 500pt; - max-width: 500pt; -} - -.list_table .tag { - font-family: monospace; - font-size: 8pt; - max-width: 60pt; -} - -.list_table .opts { - width: 40pt; - max-width: 40pt; -} - -.list_table .status { - width: 250pt; - max-width: 250pt; -} - -.list_table .patched { - width: 60pt; - max-width: 60pt; - text-align: center; -} - -.list_table .kernel { - width: 80pt; - max-width: 80pt; -} - -.list_table .maintainers { - width: 150pt; - max-width: 150pt; -} - -.list_table .result { - width: 60pt; - max-width: 60pt; -} - -.list_table .stat { - width: 55pt; - font-family: monospace; - text-align: right; -} - -.list_table .bisect_status { - width: 75pt; - max-width: 75pt; - font-family: monospace; - text-align: right; -} - -.list_table .date { - width: 60pt; - max-width: 60pt; - font-family: monospace; - text-align: right; -} - -.list_table .stat_name { - width: 150pt; - max-width: 150pt; - font-family: monospace; -} - -.list_table .stat_value { - width: 120pt; - max-width: 120pt; - font-family: monospace; -} - -.bad { - color: #f00; - font-weight: bold; -} - -.inactive { - color: #888; -} - -.plain { - text-decoration: none; -} - -textarea { - width:100%; - font-family: monospace; -} - -.mono { - font-family: monospace; -} - -.info_link { - color: #25a7db; - text-decoration: none; -} - -.page { - position: relative; - width: 100%; -} - -aside { - position: absolute; - top: 0; - left: 0; - bottom: 0; - width: 290px; - margin-top: 5px; -} - -.panel { - border: 1px solid #aaa; - border-radius: 5px; - margin-bottom: 5px; - margin-top: 5px; -} - -.panel h1 { - font-size: 16px; - margin: 0; - padding: 2px 8px; -} - -.panel select { - padding: 5px; - border: 0; - width: 100%; -} - -.panel label { - margin-left: 7px; -} - -.main-content { - position: absolute; - top: 0; - left: 300px; - right: 5px; - min-height: 200px; - overflow: hidden; -} - -.graph_help { - position: absolute; - top: 115px; - left: 10px; - z-index: 1; - text-decoration: none; - font-weight: bold; - font-size: xx-large; - color: blue; -} - -#graph_div { - height: 85vh; -} - -#crash_div { - align: left; - width: 90%; - height: 400px; - margin: 0 0; - overflow: scroll; - border: 1px solid #777; - padding: 0px; - background: transparent; -} - -#crash_div pre { - margin: 1px; -} - -.input-values { - margin-left: 7px; - margin-bottom: 7px; -} - -.input-group { - margin-top: 7px; - margin-bottom: 7px; - display: block; -} - -.input-group button { - width: 20pt; -} +../../../pkg/html/pages/style.css
\ No newline at end of file diff --git a/pkg/html/pages/common.js b/pkg/html/pages/common.js new file mode 100644 index 000000000..95e6c8f61 --- /dev/null +++ b/pkg/html/pages/common.js @@ -0,0 +1,101 @@ +// Copyright 2018 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +function sortTable(item, colName, conv, desc = false) { + table = item.parentNode.parentNode.parentNode.parentNode; + rows = table.rows; + col = findColumnByName(rows[0].getElementsByTagName("th"), colName); + values = []; + for (i = 1; i < rows.length; i++) + values.push([conv(rows[i].getElementsByTagName("td")[col].textContent), rows[i]]); + if (desc) + desc = !isSorted(values.slice().reverse()) + else + desc = isSorted(values); + values.sort(function(a, b) { + if (a[0] == b[0]) return 0; + if (desc && a[0] > b[0] || !desc && a[0] < b[0]) return -1; + return 1; + }); + for (i = 0; i < values.length; i++) + table.tBodies[0].appendChild(values[i][1]); + return false; +} + +function findColumnByName(headers, colName) { + for (i = 0; i < headers.length; i++) { + if (headers[i].textContent == colName) + return i; + } + return 0; +} + +function isSorted(values) { + for (i = 0; i < values.length - 1; i++) { + if (values[i][0] > values[i + 1][0]) + return false; + } + return true; +} + +function textSort(v) { return v == "" ? "zzz" : v.toLowerCase(); } +function numSort(v) { return -parseInt(v); } +function floatSort(v) { return -parseFloat(v); } +function reproSort(v) { return v == "C" ? 0 : v == "syz" ? 1 : 2; } +function patchedSort(v) { return v == "" ? -1 : parseInt(v); } +function lineSort(v) { return -v.split(/\r\n|\r|\n/g).length } + +function timeSort(v) { + if (v == "now") + return 0; + m = v.indexOf('m'); + h = v.indexOf('h'); + d = v.indexOf('d'); + if (m > 0 && h < 0) + return parseInt(v); + if (h > 0 && m > 0) + return parseInt(v) * 60 + parseInt(v.substring(h + 1)); + if (d > 0 && h > 0) + return parseInt(v) * 60 * 24 + parseInt(v.substring(d + 1)) * 60; + if (d > 0) + return parseInt(v) * 60 * 24; + return 1000000000; +} + + + +function findAncestorByClass (el, cls) { + while ((el = el.parentElement) && !el.classList.contains(cls)); + return el; +} + +function deleteInputGroup(node) { + group = findAncestorByClass(node, "input-group") + values = findAncestorByClass(group, "input-values") + if (!values) { + return false + } + count = values.querySelectorAll('.input-group').length + if (count == 1) { + // If it's the only input, just clear it. + input = group.querySelector('input') + input.value = "" + } else { + group.remove() + } + return false +} + +function addInputGroup(node) { + values = findAncestorByClass(node, "input-values") + groups = values.querySelectorAll(".input-group") + if (groups.length == 0) { + // Something strange has happened. + return false + } + lastGroup = groups[groups.length - 1] + newGroup = lastGroup.cloneNode(true) + newGroup.querySelector('input').value = "" + values.insertBefore(newGroup, lastGroup.nextSibling) + return false +} diff --git a/pkg/html/pages/gen.sh b/pkg/html/pages/gen.sh deleted file mode 100755 index a326138b2..000000000 --- a/pkg/html/pages/gen.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2020 syzkaller project authors. All rights reserved. -# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. - -set -eu - -echo '// Code generated by pkg/html/html.go. DO NOT EDIT.' > generated.go -echo 'package pages' >> generated.go -echo 'const style = `' >> generated.go -cat ../../../dashboard/app/static/style.css >> generated.go -echo '`' >> generated.go -echo 'const js = `' >> generated.go -cat ../../../dashboard/app/static/common.js >> generated.go -echo '`' >> generated.go diff --git a/pkg/html/pages/pages.go b/pkg/html/pages/pages.go index 0040c8617..51bc902c7 100644 --- a/pkg/html/pages/pages.go +++ b/pkg/html/pages/pages.go @@ -1,11 +1,10 @@ // Copyright 2022 syzkaller project authors. All rights reserved. // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. -//go:generate ./gen.sh - package pages import ( + _ "embed" // for go:embed directives "fmt" "html/template" "io/fs" @@ -28,3 +27,9 @@ func getHeadTemplate() string { const headTempl = `<style type="text/css" media="screen">%v</style><script>%v</script>` return fmt.Sprintf(headTempl, style, js) } + +//go:embed style.css +var style string + +//go:embed common.js +var js string diff --git a/pkg/html/pages/generated.go b/pkg/html/pages/style.css index 56f5e2d5f..7a2ca851a 100644 --- a/pkg/html/pages/generated.go +++ b/pkg/html/pages/style.css @@ -1,7 +1,3 @@ -// Code generated by pkg/html/html.go. DO NOT EDIT. -package pages - -const style = ` #topbar { padding: 5px 10px; background: #E0EBF5; @@ -302,107 +298,3 @@ aside { .input-group button { width: 20pt; } -` -const js = ` -// Copyright 2018 syzkaller project authors. All rights reserved. -// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. - -function sortTable(item, colName, conv, desc = false) { - table = item.parentNode.parentNode.parentNode.parentNode; - rows = table.rows; - col = findColumnByName(rows[0].getElementsByTagName("th"), colName); - values = []; - for (i = 1; i < rows.length; i++) - values.push([conv(rows[i].getElementsByTagName("td")[col].textContent), rows[i]]); - if (desc) - desc = !isSorted(values.slice().reverse()) - else - desc = isSorted(values); - values.sort(function(a, b) { - if (a[0] == b[0]) return 0; - if (desc && a[0] > b[0] || !desc && a[0] < b[0]) return -1; - return 1; - }); - for (i = 0; i < values.length; i++) - table.tBodies[0].appendChild(values[i][1]); - return false; -} - -function findColumnByName(headers, colName) { - for (i = 0; i < headers.length; i++) { - if (headers[i].textContent == colName) - return i; - } - return 0; -} - -function isSorted(values) { - for (i = 0; i < values.length - 1; i++) { - if (values[i][0] > values[i + 1][0]) - return false; - } - return true; -} - -function textSort(v) { return v == "" ? "zzz" : v.toLowerCase(); } -function numSort(v) { return -parseInt(v); } -function floatSort(v) { return -parseFloat(v); } -function reproSort(v) { return v == "C" ? 0 : v == "syz" ? 1 : 2; } -function patchedSort(v) { return v == "" ? -1 : parseInt(v); } -function lineSort(v) { return -v.split(/\r\n|\r|\n/g).length } - -function timeSort(v) { - if (v == "now") - return 0; - m = v.indexOf('m'); - h = v.indexOf('h'); - d = v.indexOf('d'); - if (m > 0 && h < 0) - return parseInt(v); - if (h > 0 && m > 0) - return parseInt(v) * 60 + parseInt(v.substring(h + 1)); - if (d > 0 && h > 0) - return parseInt(v) * 60 * 24 + parseInt(v.substring(d + 1)) * 60; - if (d > 0) - return parseInt(v) * 60 * 24; - return 1000000000; -} - - - -function findAncestorByClass (el, cls) { - while ((el = el.parentElement) && !el.classList.contains(cls)); - return el; -} - -function deleteInputGroup(node) { - group = findAncestorByClass(node, "input-group") - values = findAncestorByClass(group, "input-values") - if (!values) { - return false - } - count = values.querySelectorAll('.input-group').length - if (count == 1) { - // If it's the only input, just clear it. - input = group.querySelector('input') - input.value = "" - } else { - group.remove() - } - return false -} - -function addInputGroup(node) { - values = findAncestorByClass(node, "input-values") - groups = values.querySelectorAll(".input-group") - if (groups.length == 0) { - // Something strange has happened. - return false - } - lastGroup = groups[groups.length - 1] - newGroup = lastGroup.cloneNode(true) - newGroup.querySelector('input').value = "" - values.insertBefore(newGroup, lastGroup.nextSibling) - return false -} -` |
