* [Buildroot] [PATCH v2 1/2] support/scripts/pkg-stats: move to procedurally generated row/column clases @ 2022-08-05 20:01 Sen Hastings 2022-08-05 20:01 ` [Buildroot] [PATCH v1 2/2] support/scripts/pkg-stats: optimize CSS selector usage Sen Hastings 2022-08-06 21:51 ` [Buildroot] [PATCH v2 1/2] support/scripts/pkg-stats: move to procedurally generated row/column clases Thomas Petazzoni via buildroot 0 siblings, 2 replies; 7+ messages in thread From: Sen Hastings @ 2022-08-05 20:01 UTC (permalink / raw) To: buildroot; +Cc: Sen Hastings Rather than having pre-baked classes in the markup for sorting purposes, all the cells in package-grid are iterated over at load time and given a row/column class. example: https://sen-h.github.io/pkg-stats/b6f4cbddb14233c3ab3fdfea1e486c14871cfb2a.html Signed-off-by: Sen Hastings <sen@phobosdpl.com> --- v1->v2: * fixed current version class attributes being rendered as inner text * added link to example html --- support/scripts/pkg-stats | 160 ++++++++++++++++---------------------- 1 file changed, 68 insertions(+), 92 deletions(-) diff --git a/support/scripts/pkg-stats b/support/scripts/pkg-stats index d32abd7225..39da5e5593 100755 --- a/support/scripts/pkg-stats +++ b/support/scripts/pkg-stats @@ -758,6 +758,17 @@ addedCSSRules = [ addedCSSRules.forEach(rule => styleSheet.insertRule(rule)); +window.addEventListener('DOMContentLoaded', (event) => { + gridArray = Array.from(document.getElementById("package-grid").children); + let l = row = 0; + gridArray.forEach(cell =>{ + if (l != 13){ l++ } + else { l = 1; row++; }; + + cell.classList.add("c" + l, "ir" + row); + }); +}); + function sortGrid(sortLabel){ let i = 0; let pkgSortArray = [], sortedPkgArray = [], pkgStringSortArray = [], pkgNumSortArray = []; @@ -774,14 +785,11 @@ function sortGrid(sortLabel){ const styleSheet = styleElement.sheet; columnValues.shift(); - columnValues.forEach((listing) => { + columnValues.forEach((listing) => { let sortArr = []; - sortArr[0] = listing.id.replace(sortLabel+"_", ""); - if (!listing.innerText){ - sortArr[1] = -1; - } else { - sortArr[1] = listing.innerText; - }; + sortArr[0] = listing.classList[listing.classList.length - 1]; + sortArr[1] = listing.innerText; + if (!listing.innerText){sortArr[1] = -1;}; pkgSortArray.push(sortArr); }); pkgSortArray.forEach((listing) => { @@ -821,13 +829,12 @@ function sortGrid(sortLabel){ addedCSSRules.forEach(rule => styleSheet.insertRule(rule)); }; -function expandField(fieldId){ - const field = document.getElementById(fieldId); +function expandField(field){ const fieldText = field.firstElementChild.innerText; const fieldTotal = fieldText.split(' ')[2]; if (fieldText == "see all " + fieldTotal + triangleDown){ - field.firstElementChild.innerText = "see less " + fieldTotal + triangleUp; + field.firstElementChild.innerText = "see less " + fieldTotal + triangleUp; field.style.height = "auto"; } else { field.firstElementChild.innerText = "see all " + fieldTotal + triangleDown; @@ -919,80 +926,59 @@ def boolean_str(b): def dump_html_pkg(f, pkg): - pkg_css_class = pkg.path.replace("/", "_")[:-3] - f.write(f'<div id=\"package__{pkg_css_class}\" \ - class=\"package data _{pkg_css_class}\">{pkg.path}</div>\n') + f.write(f'<div class=\"data\">{pkg.path}</div>\n') # Patch count - data_field_id = f'patch_count__{pkg_css_class}' - div_class = ["centered patch_count data"] - div_class.append(f'_{pkg_css_class}') + div_class = ["centered data"] if pkg.patch_count == 0: div_class.append("nopatches") elif pkg.patch_count < 5: div_class.append("somepatches") else: div_class.append("lotsofpatches") - f.write(f' <div id=\"{data_field_id}\" class=\"{" ".join(div_class)} \ - \">{str(pkg.patch_count)}</div>\n') + f.write(f' <div class=\"{" ".join(div_class)}\">{str(pkg.patch_count)}</div>\n') # Infrastructure - data_field_id = f'infrastructure__{pkg_css_class}' infra = infra_str(pkg.infras) - div_class = ["centered infrastructure data"] - div_class.append(f'_{pkg_css_class}') + div_class = ["centered data"] if infra == "Unknown": div_class.append("wrong") else: div_class.append("correct") - f.write(f' <div id=\"{data_field_id}\" class=\"{" ".join(div_class)} \ - \">{infra_str(pkg.infras)}</div>\n') + f.write(f' <div class=\"{" ".join(div_class)}\">{infra_str(pkg.infras)}</div>\n') # License - data_field_id = f'license__{pkg_css_class}' - div_class = ["centered license data"] - div_class.append(f'_{pkg_css_class}') + div_class = ["centered data"] if pkg.is_status_ok('license'): div_class.append("correct") else: div_class.append("wrong") - f.write(f' <div id=\"{data_field_id}\" class=\"{" ".join(div_class)} \ - \">{boolean_str(pkg.is_status_ok("license"))}</div>\n') + f.write(f' <div class=\"{" ".join(div_class)}\">{boolean_str(pkg.is_status_ok("license"))}</div>\n') # License files - data_field_id = f'license_files__{pkg_css_class}' - div_class = ["centered license_files data"] - div_class.append(f'_{pkg_css_class}') + div_class = ["centered data"] if pkg.is_status_ok('license-files'): div_class.append("correct") else: div_class.append("wrong") - f.write(f' <div id=\"{data_field_id}\" class=\"{" ".join(div_class)} \ - \">{boolean_str(pkg.is_status_ok("license-files"))}</div>\n') + f.write(f' <div class=\"{" ".join(div_class)}\">{boolean_str(pkg.is_status_ok("license-files"))}</div>\n') # Hash - data_field_id = f'hash_file__{pkg_css_class}' - div_class = ["centered hash_file data"] - div_class.append(f'_{pkg_css_class}') + div_class = ["centered data"] if pkg.is_status_ok('hash'): div_class.append("correct") else: div_class.append("wrong") - f.write(f' <div id=\"{data_field_id}\" class=\"{" ".join(div_class)} \ - \">{boolean_str(pkg.is_status_ok("hash"))}</div>\n') + f.write(f' <div class=\"{" ".join(div_class)}\">{boolean_str(pkg.is_status_ok("hash"))}</div>\n') # Current version - data_field_id = f'current_version__{pkg_css_class}' if len(pkg.current_version) > 20: current_version = pkg.current_version[:20] + "..." else: current_version = pkg.current_version - f.write(f' <div id=\"{data_field_id}\" \ - class=\"centered current_version data _{pkg_css_class}\">{current_version}</div>\n') + f.write(f' <div class=\"centered data\">{current_version}</div>\n') # Latest version - data_field_id = f'latest_version__{pkg_css_class}' - div_class.append(f'_{pkg_css_class}') - div_class.append("latest_version data") + div_class = ["centered data"] if pkg.latest_version['status'] == RM_API_STATUS_ERROR: div_class.append("version-error") if pkg.latest_version['version'] is None: @@ -1020,22 +1006,18 @@ def dump_html_pkg(f, pkg): else: latest_version_text += "found by guess" - f.write(f' <div id=\"{data_field_id}\" class=\"{" ".join(div_class)}\">{latest_version_text}</div>\n') + f.write(f' <div class=\"{" ".join(div_class)}\">{latest_version_text}</div>\n') # Warnings - data_field_id = f'warnings__{pkg_css_class}' - div_class = ["centered warnings data"] - div_class.append(f'_{pkg_css_class}') + div_class = ["centered data"] if pkg.warnings == 0: div_class.append("correct") else: div_class.append("wrong") - f.write(f' <div id=\"{data_field_id}\" class=\"{" ".join(div_class)}\">{pkg.warnings}</div>\n') + f.write(f' <div class=\"{" ".join(div_class)}\">{pkg.warnings}</div>\n') # URL status - data_field_id = f'upstream_url__{pkg_css_class}' - div_class = ["centered upstream_url data"] - div_class.append(f'_{pkg_css_class}') + div_class = ["centered data"] url_str = pkg.status['url'][1] if pkg.status['url'][0] in ("error", "warning"): div_class.append("missing_url") @@ -1045,12 +1027,10 @@ def dump_html_pkg(f, pkg): else: div_class.append("good_url") url_str = "<a href=\"%s\">Link</a>" % pkg.url - f.write(f' <div id=\"{data_field_id}\" class=\"{" ".join(div_class)}\">{url_str}</div>\n') + f.write(f' <div class=\"{" ".join(div_class)}\">{url_str}</div>\n') # CVEs - data_field_id = f'cves__{pkg_css_class}' - div_class = ["centered cves data"] - div_class.append(f'_{pkg_css_class}') + div_class = ["centered data"] if len(pkg.cves) > 10: div_class.append("collapse") if pkg.is_status_ok("cve"): @@ -1061,10 +1041,10 @@ def dump_html_pkg(f, pkg): div_class.append("cve-ok") else: div_class.append("cve-unknown") - f.write(f' <div id=\"{data_field_id}\" class=\"{" ".join(div_class)}\">\n') + f.write(f' <div class=\"{" ".join(div_class)}\">\n') if len(pkg.cves) > 10: cve_total = len(pkg.cves) + 1 - f.write(f' <div onclick=\"expandField(\'{data_field_id}\')\" \ + f.write(f' <div onclick=\"expandField(this.parentElement)\" \ class=\"see-more centered cve_ignored\">see all ({cve_total}) ▾</div>\n') if pkg.is_status_error("cve"): for cve in pkg.cves: @@ -1078,20 +1058,16 @@ def dump_html_pkg(f, pkg): f.write(" </div>\n") # CVEs Ignored - data_field_id = f'ignored_cves__{pkg_css_class}' - div_class = ["centered data ignored_cves"] - div_class.append(f'_{pkg_css_class}') + div_class = ["centered data"] if pkg.ignored_cves: div_class.append("cve_ignored") - f.write(f' <div id=\"{data_field_id}\" class=\"{" ".join(div_class)}\">\n') + f.write(f' <div class=\"{" ".join(div_class)}\">\n') for ignored_cve in pkg.ignored_cves: f.write(" <a href=\"https://security-tracker.debian.org/tracker/%s\">%s</a><br/>\n" % (ignored_cve, ignored_cve)) f.write(" </div>\n") # CPE ID - data_field_id = f'cpe_id__{pkg_css_class}' - div_class = ["left cpe_id data"] - div_class.append(f'_{pkg_css_class}') + div_class = ["data"] if pkg.is_status_ok("cpe"): div_class.append("cpe-ok") elif pkg.is_status_error("cpe"): @@ -1100,7 +1076,7 @@ def dump_html_pkg(f, pkg): div_class.append("cpe-ok") else: div_class.append("cpe-unknown") - f.write(f' <div id=\"{data_field_id}\" class=\"{" ".join(div_class)}\">\n') + f.write(f' <div class=\"{" ".join(div_class)}\">\n') if pkg.cpeid: cpeid_begin = ":".join(pkg.cpeid.split(":")[0:4]) + ":" cpeid_formatted = pkg.cpeid.replace(cpeid_begin, cpeid_begin + "<wbr>") @@ -1122,32 +1098,32 @@ def dump_html_pkg(f, pkg): def dump_html_all_pkgs(f, packages): f.write(""" <div id=\"package-grid\"> -<div style="grid-column: 1;" onclick="sortGrid(this.id)" id=\"package\" - class=\"package data label\"><span>Package</span><span></span></div> -<div style="grid-column: 2;" onclick="sortGrid(this.id)" id=\"patch_count\" - class=\"centered patch_count data label\"><span>Patch count</span><span></span></div> -<div style="grid-column: 3;" onclick="sortGrid(this.id)" id=\"infrastructure\" - class=\"centered infrastructure data label\">Infrastructure<span></span></div> -<div style="grid-column: 4;" onclick="sortGrid(this.id)" id=\"license\" - class=\"centered license data label\"><span>License</span><span></span></div> -<div style="grid-column: 5;" onclick="sortGrid(this.id)" id=\"license_files\" - class=\"centered license_files data label\"><span>License files</span><span></span></div> -<div style="grid-column: 6;" onclick="sortGrid(this.id)" id=\"hash_file\" - class=\"centered hash_file data label\"><span>Hash file</span><span></span></div> -<div style="grid-column: 7;" onclick="sortGrid(this.id)" id=\"current_version\" - class=\"centered current_version data label\"><span>Current version</span><span></span></div> -<div style="grid-column: 8;" onclick="sortGrid(this.id)" id=\"latest_version\" - class=\"centered latest_version data label\"><span>Latest version</span><span></span></div> -<div style="grid-column: 9;" onclick="sortGrid(this.id)" id=\"warnings\" - class=\"centered warnings data label\"><span>Warnings</span><span></span></div> -<div style="grid-column: 10;" onclick="sortGrid(this.id)" id=\"upstream_url\" - class=\"centered upstream_url data label\"><span>Upstream URL</span><span></span></div> -<div style="grid-column: 11;" onclick="sortGrid(this.id)" id=\"cves\" - class=\"centered cves data label\"><span>CVEs</span><span></span></div> -<div style="grid-column: 12;" onclick="sortGrid(this.id)" id=\"ignored_cves\" - class=\"centered ignored_cves data label\"><span>CVEs Ignored</span><span></span></div> -<div style="grid-column: 13;" onclick="sortGrid(this.id)" id=\"cpe_id\" - class=\"centered cpe_id data label\"><span>CPE ID</span><span></span></div> +<div style="grid-column: 1;" onclick="sortGrid(this.id)" id=\"c1\" + class=\"data label\"><span>Package</span><span></span></div> +<div style="grid-column: 2;" onclick="sortGrid(this.id)" id=\"c2\" + class=\"centered data label\"><span>Patch count</span><span></span></div> +<div style="grid-column: 3;" onclick="sortGrid(this.id)" id=\"c3\" + class=\"centered data label\">Infrastructure<span></span></div> +<div style="grid-column: 4;" onclick="sortGrid(this.id)" id=\"c4\" + class=\"centered data label\"><span>License</span><span></span></div> +<div style="grid-column: 5;" onclick="sortGrid(this.id)" id=\"c5\" + class=\"centered data label\"><span>License files</span><span></span></div> +<div style="grid-column: 6;" onclick="sortGrid(this.id)" id=\"c6\" + class=\"centered data label\"><span>Hash file</span><span></span></div> +<div style="grid-column: 7;" onclick="sortGrid(this.id)" id=\"c7\" + class=\"centered data label\"><span>Current version</span><span></span></div> +<div style="grid-column: 8;" onclick="sortGrid(this.id)" id=\"c8\" + class=\"centered data label\"><span>Latest version</span><span></span></div> +<div style="grid-column: 9;" onclick="sortGrid(this.id)" id=\"c9\" + class=\"centered data label\"><span>Warnings</span><span></span></div> +<div style="grid-column: 10;" onclick="sortGrid(this.id)" id=\"c10\" + class=\"centered data label\"><span>Upstream URL</span><span></span></div> +<div style="grid-column: 11;" onclick="sortGrid(this.id)" id=\"c11\" + class=\"centered data label\"><span>CVEs</span><span></span></div> +<div style="grid-column: 12;" onclick="sortGrid(this.id)" id=\"c12\" + class=\"centered data label\"><span>CVEs Ignored</span><span></span></div> +<div style="grid-column: 13;" onclick="sortGrid(this.id)" id=\"c13\" + class=\"data label\"><span>CPE ID</span><span></span></div> """) for pkg in sorted(packages): dump_html_pkg(f, pkg) -- 2.34.1 _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Buildroot] [PATCH v1 2/2] support/scripts/pkg-stats: optimize CSS selector usage 2022-08-05 20:01 [Buildroot] [PATCH v2 1/2] support/scripts/pkg-stats: move to procedurally generated row/column clases Sen Hastings @ 2022-08-05 20:01 ` Sen Hastings 2022-08-06 21:55 ` Thomas Petazzoni via buildroot 2022-08-06 21:51 ` [Buildroot] [PATCH v2 1/2] support/scripts/pkg-stats: move to procedurally generated row/column clases Thomas Petazzoni via buildroot 1 sibling, 1 reply; 7+ messages in thread From: Sen Hastings @ 2022-08-05 20:01 UTC (permalink / raw) To: buildroot; +Cc: Sen Hastings Having lots of CSS selector declarations adds up, especially at 70k+ elements. This reduces the number of CSS selectors printed in the markup to the bare minimum, by using pseudo-classes and tag names as selectors. example: https://sen-h.github.io/pkg-stats/9ad05210dcd9e4fb6b6a45be87c0fbb3e022085b.html Signed-off-by: Sen Hastings <sen@phobosdpl.com> --- v1->v2: * added link to example html --- support/scripts/pkg-stats | 132 ++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 62 deletions(-) diff --git a/support/scripts/pkg-stats b/support/scripts/pkg-stats index 39da5e5593..654b918911 100755 --- a/support/scripts/pkg-stats +++ b/support/scripts/pkg-stats @@ -845,7 +845,20 @@ function expandField(field){ <style> -.see-more{ +div { + text-align: center; + border: solid 1px gray; +} +#results-grid div{ + text-align: left; +} +#package-grid div:nth-child(13n+1), #package-grid div:nth-child(13n+13) { + text-align: left; +} +#package-grid div:nth-child(13){ + text-align: center; +} +.see-more { display: none; } @@ -859,6 +872,7 @@ function expandField(field){ padding: 10px 2px 10px 2px; } #package-grid, #results-grid { + border: none; display: grid; grid-gap: 2px; grid-template-columns: 1fr repeat(12, min-content); @@ -866,21 +880,15 @@ function expandField(field){ #results-grid { grid-template-columns: 3fr 1fr; } -.data { - border: solid 1px gray; +.correct, .nopatches, .good_url, .version-good, .cpe-ok, .cve-ok { + background: #d2ffc4; } -.centered { - text-align: center; +.wrong, .lotsofpatches, .invalid_url, .version-needs-update, .cpe-nok, .cve-nok { + background: #ff9a69; +} +.somepatches, .missing_url, .version-unknown, .cpe-unknown, .cve-unknown { + background: #ffd870; } - .correct, .nopatches, .good_url, .version-good, .cpe-ok, .cve-ok { - background: #d2ffc4; - } - .wrong, .lotsofpatches, .invalid_url, .version-needs-update, .cpe-nok, .cve-nok { - background: #ff9a69; - } - .somepatches, .missing_url, .version-unknown, .cpe-unknown, .cve-unknown { - background: #ffd870; - } .cve_ignored, .version-error { background: #ccc; } @@ -926,9 +934,9 @@ def boolean_str(b): def dump_html_pkg(f, pkg): - f.write(f'<div class=\"data\">{pkg.path}</div>\n') + f.write(f'<div>{pkg.path}</div>\n') # Patch count - div_class = ["centered data"] + div_class = [] if pkg.patch_count == 0: div_class.append("nopatches") elif pkg.patch_count < 5: @@ -939,7 +947,7 @@ def dump_html_pkg(f, pkg): # Infrastructure infra = infra_str(pkg.infras) - div_class = ["centered data"] + div_class = [] if infra == "Unknown": div_class.append("wrong") else: @@ -947,7 +955,7 @@ def dump_html_pkg(f, pkg): f.write(f' <div class=\"{" ".join(div_class)}\">{infra_str(pkg.infras)}</div>\n') # License - div_class = ["centered data"] + div_class = [] if pkg.is_status_ok('license'): div_class.append("correct") else: @@ -955,7 +963,7 @@ def dump_html_pkg(f, pkg): f.write(f' <div class=\"{" ".join(div_class)}\">{boolean_str(pkg.is_status_ok("license"))}</div>\n') # License files - div_class = ["centered data"] + div_class = [] if pkg.is_status_ok('license-files'): div_class.append("correct") else: @@ -963,7 +971,7 @@ def dump_html_pkg(f, pkg): f.write(f' <div class=\"{" ".join(div_class)}\">{boolean_str(pkg.is_status_ok("license-files"))}</div>\n') # Hash - div_class = ["centered data"] + div_class = [] if pkg.is_status_ok('hash'): div_class.append("correct") else: @@ -975,10 +983,10 @@ def dump_html_pkg(f, pkg): current_version = pkg.current_version[:20] + "..." else: current_version = pkg.current_version - f.write(f' <div>class=\"centered data\" {current_version}</div>\n') + f.write(f' <div>{current_version}</div>\n') # Latest version - div_class = ["centered data"] + div_class = [] if pkg.latest_version['status'] == RM_API_STATUS_ERROR: div_class.append("version-error") if pkg.latest_version['version'] is None: @@ -1009,7 +1017,7 @@ def dump_html_pkg(f, pkg): f.write(f' <div class=\"{" ".join(div_class)}\">{latest_version_text}</div>\n') # Warnings - div_class = ["centered data"] + div_class = [] if pkg.warnings == 0: div_class.append("correct") else: @@ -1017,7 +1025,7 @@ def dump_html_pkg(f, pkg): f.write(f' <div class=\"{" ".join(div_class)}\">{pkg.warnings}</div>\n') # URL status - div_class = ["centered data"] + div_class = [] url_str = pkg.status['url'][1] if pkg.status['url'][0] in ("error", "warning"): div_class.append("missing_url") @@ -1030,7 +1038,7 @@ def dump_html_pkg(f, pkg): f.write(f' <div class=\"{" ".join(div_class)}\">{url_str}</div>\n') # CVEs - div_class = ["centered data"] + div_class = [] if len(pkg.cves) > 10: div_class.append("collapse") if pkg.is_status_ok("cve"): @@ -1045,7 +1053,7 @@ def dump_html_pkg(f, pkg): if len(pkg.cves) > 10: cve_total = len(pkg.cves) + 1 f.write(f' <div onclick=\"expandField(this.parentElement)\" \ - class=\"see-more centered cve_ignored\">see all ({cve_total}) ▾</div>\n') + style=\"text-align: center;\" class=\"see-more cve_ignored\">see all ({cve_total}) ▾</div>\n') if pkg.is_status_error("cve"): for cve in pkg.cves: f.write(" <a href=\"https://security-tracker.debian.org/tracker/%s\">%s</a><br/>\n" % (cve, cve)) @@ -1058,16 +1066,16 @@ def dump_html_pkg(f, pkg): f.write(" </div>\n") # CVEs Ignored - div_class = ["centered data"] if pkg.ignored_cves: - div_class.append("cve_ignored") - f.write(f' <div class=\"{" ".join(div_class)}\">\n') + f.write(" <div class=\"cve_ignored\">\n") + else: + f.write(" <div>\n") for ignored_cve in pkg.ignored_cves: f.write(" <a href=\"https://security-tracker.debian.org/tracker/%s\">%s</a><br/>\n" % (ignored_cve, ignored_cve)) f.write(" </div>\n") # CPE ID - div_class = ["data"] + div_class = [] if pkg.is_status_ok("cpe"): div_class.append("cpe-ok") elif pkg.is_status_error("cpe"): @@ -1099,31 +1107,31 @@ def dump_html_all_pkgs(f, packages): f.write(""" <div id=\"package-grid\"> <div style="grid-column: 1;" onclick="sortGrid(this.id)" id=\"c1\" - class=\"data label\"><span>Package</span><span></span></div> + class=\"label\"><span>Package</span><span></span></div> <div style="grid-column: 2;" onclick="sortGrid(this.id)" id=\"c2\" - class=\"centered data label\"><span>Patch count</span><span></span></div> + class=\"label\"><span>Patch count</span><span></span></div> <div style="grid-column: 3;" onclick="sortGrid(this.id)" id=\"c3\" - class=\"centered data label\">Infrastructure<span></span></div> + class=\"label\">Infrastructure<span></span></div> <div style="grid-column: 4;" onclick="sortGrid(this.id)" id=\"c4\" - class=\"centered data label\"><span>License</span><span></span></div> + class=\"label\"><span>License</span><span></span></div> <div style="grid-column: 5;" onclick="sortGrid(this.id)" id=\"c5\" - class=\"centered data label\"><span>License files</span><span></span></div> + class=\"label\"><span>License files</span><span></span></div> <div style="grid-column: 6;" onclick="sortGrid(this.id)" id=\"c6\" - class=\"centered data label\"><span>Hash file</span><span></span></div> + class=\"label\"><span>Hash file</span><span></span></div> <div style="grid-column: 7;" onclick="sortGrid(this.id)" id=\"c7\" - class=\"centered data label\"><span>Current version</span><span></span></div> + class=\"label\"><span>Current version</span><span></span></div> <div style="grid-column: 8;" onclick="sortGrid(this.id)" id=\"c8\" - class=\"centered data label\"><span>Latest version</span><span></span></div> + class=\"label\"><span>Latest version</span><span></span></div> <div style="grid-column: 9;" onclick="sortGrid(this.id)" id=\"c9\" - class=\"centered data label\"><span>Warnings</span><span></span></div> + class=\"label\"><span>Warnings</span><span></span></div> <div style="grid-column: 10;" onclick="sortGrid(this.id)" id=\"c10\" - class=\"centered data label\"><span>Upstream URL</span><span></span></div> + class=\"label\"><span>Upstream URL</span><span></span></div> <div style="grid-column: 11;" onclick="sortGrid(this.id)" id=\"c11\" - class=\"centered data label\"><span>CVEs</span><span></span></div> + class=\"label\"><span>CVEs</span><span></span></div> <div style="grid-column: 12;" onclick="sortGrid(this.id)" id=\"c12\" - class=\"centered data label\"><span>CVEs Ignored</span><span></span></div> + class=\"label\"><span>CVEs Ignored</span><span></span></div> <div style="grid-column: 13;" onclick="sortGrid(this.id)" id=\"c13\" - class=\"data label\"><span>CPE ID</span><span></span></div> + class=\"label\"><span>CPE ID</span><span></span></div> """) for pkg in sorted(packages): dump_html_pkg(f, pkg) @@ -1135,43 +1143,43 @@ def dump_html_stats(f, stats): f.write("<div class=\"data\" id=\"results-grid\">\n") infras = [infra[6:] for infra in stats.keys() if infra.startswith("infra-")] for infra in infras: - f.write(" <div class=\"data\">Packages using the <i>%s</i> infrastructure</div><div class=\"data\">%s</div>\n" % + f.write(" <div>Packages using the <i>%s</i> infrastructure</div><div>%s</div>\n" % (infra, stats["infra-%s" % infra])) - f.write(" <div class=\"data\">Packages having license information</div><div class=\"data\">%s</div>\n" % + f.write(" <div>Packages having license information</div><div>%s</div>\n" % stats["license"]) - f.write(" <div class=\"data\">Packages not having license information</div><div class=\"data\">%s</div>\n" % + f.write(" <div>Packages not having license information</div><div>%s</div>\n" % stats["no-license"]) - f.write(" <div class=\"data\">Packages having license files information</div><div class=\"data\">%s</div>\n" % + f.write(" <div>Packages having license files information</div><div>%s</div>\n" % stats["license-files"]) - f.write(" <div class=\"data\">Packages not having license files information</div><div class=\"data\">%s</div>\n" % + f.write(" <div>Packages not having license files information</div><div>%s</div>\n" % stats["no-license-files"]) - f.write(" <div class=\"data\">Packages having a hash file</div><div class=\"data\">%s</div>\n" % + f.write(" <div>Packages having a hash file</div><div>%s</div>\n" % stats["hash"]) - f.write(" <div class=\"data\">Packages not having a hash file</div><div class=\"data\">%s</div>\n" % + f.write(" <div>Packages not having a hash file</div><div>%s</div>\n" % stats["no-hash"]) - f.write(" <div class=\"data\">Total number of patches</div><div class=\"data\">%s</div>\n" % + f.write(" <div>Total number of patches</div><div>%s</div>\n" % stats["patches"]) - f.write("<div class=\"data\">Packages having a mapping on <i>release-monitoring.org</i></div><div class=\"data\">%s</div>\n" % + f.write("<div>Packages having a mapping on <i>release-monitoring.org</i></div><div>%s</div>\n" % stats["rmo-mapping"]) - f.write("<div class=\"data\">Packages lacking a mapping on <i>release-monitoring.org</i></div><div class=\"data\">%s</div>\n" % + f.write("<div>Packages lacking a mapping on <i>release-monitoring.org</i></div><div>%s</div>\n" % stats["rmo-no-mapping"]) - f.write("<div class=\"data\">Packages that are up-to-date</div><div class=\"data\">%s</div>\n" % + f.write("<div>Packages that are up-to-date</div><div>%s</div>\n" % stats["version-uptodate"]) - f.write("<div class=\"data\">Packages that are not up-to-date</div><div class=\"data\">%s</div>\n" % + f.write("<div>Packages that are not up-to-date</div><div>%s</div>\n" % stats["version-not-uptodate"]) - f.write("<div class=\"data\">Packages with no known upstream version</div><div class=\"data\">%s</div>\n" % + f.write("<div>Packages with no known upstream version</div><div>%s</div>\n" % stats["version-unknown"]) - f.write("<div class=\"data\">Packages affected by CVEs</div><div class=\"data\">%s</div>\n" % + f.write("<div>Packages affected by CVEs</div><div>%s</div>\n" % stats["pkg-cves"]) - f.write("<div class=\"data\">Total number of CVEs affecting all packages</div><div class=\"data\">%s</div>\n" % + f.write("<div>Total number of CVEs affecting all packages</div><div>%s</div>\n" % stats["total-cves"]) - f.write("<div class=\"data\">Packages affected by unsure CVEs</div><div class=\"data\">%s</div>\n" % + f.write("<div>Packages affected by unsure CVEs</div><div>%s</div>\n" % stats["pkg-unsure-cves"]) - f.write("<div class=\"data\">Total number of unsure CVEs affecting all packages</div><div class=\"data\">%s</div>\n" % + f.write("<div>Total number of unsure CVEs affecting all packages</div><div>%s</div>\n" % stats["total-unsure-cves"]) - f.write("<div class=\"data\">Packages with CPE ID</div><div class=\"data\">%s</div>\n" % + f.write("<div>Packages with CPE ID</div><div>%s</div>\n" % stats["cpe-id"]) - f.write("<div class=\"data\">Packages without CPE ID</div><div class=\"data\">%s</div>\n" % + f.write("<div>Packages without CPE ID</div><div>%s</div>\n" % stats["no-cpe-id"]) f.write("</div>\n") -- 2.34.1 _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Buildroot] [PATCH v1 2/2] support/scripts/pkg-stats: optimize CSS selector usage 2022-08-05 20:01 ` [Buildroot] [PATCH v1 2/2] support/scripts/pkg-stats: optimize CSS selector usage Sen Hastings @ 2022-08-06 21:55 ` Thomas Petazzoni via buildroot 0 siblings, 0 replies; 7+ messages in thread From: Thomas Petazzoni via buildroot @ 2022-08-06 21:55 UTC (permalink / raw) To: Sen Hastings; +Cc: buildroot Hello Sen, On Fri, 5 Aug 2022 15:01:14 -0500 Sen Hastings <sen@phobosdpl.com> wrote: > Having lots of CSS selector declarations adds up, especially at 70k+ > elements. > > This reduces the number of CSS selectors printed in the markup > to the bare minimum, by using pseudo-classes and tag names as selectors. Not sure how this works. Is there a significant size benefit? Sometimes having a dumb but obvious solution is better than having a smart but convoluted solution. > +div { > + text-align: center; > + border: solid 1px gray; > +} > +#results-grid div{ > + text-align: left; > +} > +#package-grid div:nth-child(13n+1), #package-grid div:nth-child(13n+13) { > + text-align: left; > +} > +#package-grid div:nth-child(13){ > + text-align: center; What is this 13 magic number? Also, unrelated to this, when I look at the currently generated HTML, it looks odd. I see things like this: <div id="upstream_url__package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream" class="centered upstream_url data _package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream good_url"><a href="https://github.com/xbmc/audiodecoder.vgmstream">Link</a></div> Why do we have these crazy id values now? why does the class property contain a value such as _package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream? Thanks! Thomas -- Thomas Petazzoni, co-owner and CEO, Bootlin Embedded Linux and Kernel engineering and training https://bootlin.com _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Buildroot] [PATCH v2 1/2] support/scripts/pkg-stats: move to procedurally generated row/column clases 2022-08-05 20:01 [Buildroot] [PATCH v2 1/2] support/scripts/pkg-stats: move to procedurally generated row/column clases Sen Hastings 2022-08-05 20:01 ` [Buildroot] [PATCH v1 2/2] support/scripts/pkg-stats: optimize CSS selector usage Sen Hastings @ 2022-08-06 21:51 ` Thomas Petazzoni via buildroot 2022-08-30 6:32 ` Sen Hastings 1 sibling, 1 reply; 7+ messages in thread From: Thomas Petazzoni via buildroot @ 2022-08-06 21:51 UTC (permalink / raw) To: Sen Hastings; +Cc: buildroot Hello, On Fri, 5 Aug 2022 15:01:13 -0500 Sen Hastings <sen@phobosdpl.com> wrote: > Rather than having pre-baked classes in the markup for sorting purposes, > all the cells in package-grid are iterated over at load time and given > a row/column class. > > example: https://sen-h.github.io/pkg-stats/b6f4cbddb14233c3ab3fdfea1e486c14871cfb2a.html > > Signed-off-by: Sen Hastings <sen@phobosdpl.com> I am probably not versed enough into HTML/CSS/JS sorcery, but I don't understand the benefit of this. Could you explain a bit more? > function sortGrid(sortLabel){ > let i = 0; > let pkgSortArray = [], sortedPkgArray = [], pkgStringSortArray = [], pkgNumSortArray = []; > @@ -774,14 +785,11 @@ function sortGrid(sortLabel){ > const styleSheet = styleElement.sheet; > > columnValues.shift(); > - columnValues.forEach((listing) => { > + columnValues.forEach((listing) => { This is a spurious change. > if (fieldText == "see all " + fieldTotal + triangleDown){ > - field.firstElementChild.innerText = "see less " + fieldTotal + triangleUp; > + field.firstElementChild.innerText = "see less " + fieldTotal + triangleUp; This is also a spurious change. Thanks! Thomas -- Thomas Petazzoni, co-owner and CEO, Bootlin Embedded Linux and Kernel engineering and training https://bootlin.com _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Buildroot] [PATCH v2 1/2] support/scripts/pkg-stats: move to procedurally generated row/column clases 2022-08-06 21:51 ` [Buildroot] [PATCH v2 1/2] support/scripts/pkg-stats: move to procedurally generated row/column clases Thomas Petazzoni via buildroot @ 2022-08-30 6:32 ` Sen Hastings 0 siblings, 0 replies; 7+ messages in thread From: Sen Hastings @ 2022-08-30 6:32 UTC (permalink / raw) To: buildroot; +Cc: sen, thomas.petazzoni On 8/6/22 16:51, Thomas Petazzoni wrote: > Hello, > > On Fri, 5 Aug 2022 15:01:13 -0500 > Sen Hastings <sen@phobosdpl.com> wrote: > >> Rather than having pre-baked classes in the markup for sorting purposes, >> all the cells in package-grid are iterated over at load time and given >> a row/column class. >> >> example: https://sen-h.github.io/pkg-stats/b6f4cbddb14233c3ab3fdfea1e486c14871cfb2a.html >> >> Signed-off-by: Sen Hastings <sen@phobosdpl.com> > > I am probably not versed enough into HTML/CSS/JS sorcery, but I don't > understand the benefit of this. Could you explain a bit more? > Sure. It turns out it's a lot cheaper (smaller) to have the client just iterate over every single cell and give it a row/column class selector instead of shipping it out with them. sortGrid() sorts by virtue of all the elements in a column sharing the same class (which originally was also the column label) and all the elements in a row also sharing the same class (which originally was also the package name). The problem (previously) was that some package names were duplicated across rows. For instance look at these two cells in the package column: <div id="package_barebox" class="package data barebox">boot/barebox/barebox.mk</div> <div id="package_barebox" class="package data barebox">boot/barebox/barebox/barebox.mk</div> these are the beginning cells of two rows and they both share the *same* class selector "barebox". Can't have that because we need every row to have a unique class assigned to it. Otherwise when we sort this happens: |label | label | label |...| label | |class1 | class1 | class1 |...|class1 | |class1 | class1 | class1 |...|class1 | becomes: |label | label | label |...| label | |class1 | class1 | class1 |...|class1 |class1 | class1 | class1 |...|class1 | sortGrid pulls all elements by row class selector and gives them an explicit grid-row assignment So now we have 26 elements in a row instead of 13 :p The fix at the time, (see: https://git.buildroot.net/buildroot/commit/?id=786f8b45672ebdd432f6af5b7595d3d16013433b) was to use the package path but with "_" instead of "/", so: boot_barebox_barebox and boot_barebox_barebox_barebox respectively. Also class selectors can't start with numbers so we prepend an "_" to for the sake of packages like 4th and 18xx-ti-utils. The problem I noticed was that having id="column_name__some_really_really_long_path_name" class="centered data _some_really_really_long_path_name" for every element added up after 70k+ elements. the old pkg-stats (https://git.buildroot.net/buildroot/commit/?id=eae86599ca81c943821bac33f424669520a3fa8c) when given the current package list gives me an html file sitting at about 2.9MB. example: https://sen-h.github.io/pkg-stats/eae86599ca81c943821bac33f424669520a3fa8c.html The current pkg-stats gives me a whopping 7MB file. example: https://sen-h.github.io/pkg-stats/c245575.html but you can see this whittled down by [PATCH v2 1/2]: https://sen-h.github.io/pkg-stats/b6f4cbddb14233c3ab3fdfea1e486c14871cfb2a.html (3.2M) and then by [PATCH v1 2/2]: https://sen-h.github.io/pkg-stats/9ad05210dcd9e4fb6b6a45be87c0fbb3e022085b.html (2.6M) in essence, we go from: <div id="upstream_url__package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream" class="centered upstream_url data _package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream good_url"><a href="https://github.com/xbmc/audiodecoder.vgmstream">Link</a></div> and then with [PATCH v2 1/2]: <div class="centered data good_url"><a href="https://github.com/xbmc/audiodecoder.vgmstream">Link</a></div> which after our column/row class assignment script runs becomes: <div class="centered data good_url c10 ir755"><a href="https://github.com/xbmc/audiodecoder.vgmstream">Link</a></div> and finally with [PATCH v2 2/2]: <div class="good_url"><a href="https://github.com/xbmc/audiodecoder.vgmstream">Link</a></div> and once again after the script runs: <div class="good_url c10 ir755"><a href="https://github.com/xbmc/audiodecoder.vgmstream">Link</a></div> and here's the old sorttable version just for comparison: <td class="centered missing_url invalid_url"><a href="https://github.com/xbmc/audiodecoder.vgmstream">invalid (err)</a></td> So why not just ship the class selectors "cX irX" for every element instead of generating them client side? I experimented with that but once again it's a size thing. Every order of magnitude (10-100-1000) adds another digit (character) to the ir (initial row) class selector. Right now it's about 300k which doesn't seem like much but could really add up over time. The pages being generated right now would be considered *quite* big by most standards, so I'm really just trying to whittle everything down to the absolute bare minimum. >> function sortGrid(sortLabel){ >> let i = 0; >> let pkgSortArray = [], sortedPkgArray = [], pkgStringSortArray = [], pkgNumSortArray = []; >> @@ -774,14 +785,11 @@ function sortGrid(sortLabel){ >> const styleSheet = styleElement.sheet; >> >> columnValues.shift(); >> - columnValues.forEach((listing) => { >> + columnValues.forEach((listing) => { > > This is a spurious change. > >> if (fieldText == "see all " + fieldTotal + triangleDown){ >> - field.firstElementChild.innerText = "see less " + fieldTotal + triangleUp; >> + field.firstElementChild.innerText = "see less " + fieldTotal + triangleUp; > > This is also a spurious change. > Shoot, those are pretty spurious. I'll go ahead and fix that. [note: I originally sent this out on the 2022-08-08, but not as reply to the previous message, so it just showed up as a normal submission to the mailing list. Re-submitting it for the sake of posterity.] > Thanks! > > Thomas _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Buildroot] [PATCH v2 1/2] support/scripts/pkg-stats: move to procedurally generated row/column clases @ 2022-08-08 22:23 Sen Hastings 2022-08-08 22:23 ` [Buildroot] [PATCH v1 2/2] support/scripts/pkg-stats: optimize CSS selector usage Sen Hastings 0 siblings, 1 reply; 7+ messages in thread From: Sen Hastings @ 2022-08-08 22:23 UTC (permalink / raw) To: Thomas Petazzoni; +Cc: Sen Hastings, buildroot On 8/6/22 16:51, Thomas Petazzoni wrote: > Hello, > > On Fri, 5 Aug 2022 15:01:13 -0500 > Sen Hastings <sen@phobosdpl.com> wrote: > >> Rather than having pre-baked classes in the markup for sorting purposes, >> all the cells in package-grid are iterated over at load time and given >> a row/column class. >> >> example: https://sen-h.github.io/pkg-stats/b6f4cbddb14233c3ab3fdfea1e486c14871cfb2a.html >> >> Signed-off-by: Sen Hastings <sen@phobosdpl.com> > > I am probably not versed enough into HTML/CSS/JS sorcery, but I don't > understand the benefit of this. Could you explain a bit more? > Sure. It turns out it's a lot cheaper (smaller) to have the client just iterate over every single cell and give it a row/column class selector instead of shipping it out with them. sortGrid() sorts by virtue of all the elements in a column sharing the same class (which originally was also the column label) and all the elements in a row also sharing the same class (which originally was also the package name). The problem (previously) was that some package names were duplicated across rows. For instance look at these two cells in the package column: <div id="package_barebox" class="package data barebox">boot/barebox/barebox.mk</div> <div id="package_barebox" class="package data barebox">boot/barebox/barebox/barebox.mk</div> these are the beginning cells of two rows and they both share the *same* class selector "barebox". Can't have that because we need every row to have a unique class assigned to it. Otherwise when we sort this happens: |label | label | label |...| label | |class1 | class1 | class1 |...|class1 | |class1 | class1 | class1 |...|class1 | becomes: |label | label | label |...| label | |class1 | class1 | class1 |...|class1 |class1 | class1 | class1 |...|class1 | sortGrid pulls all elements by row class selector and gives them an explicit grid-row assignment So now we have 26 elements in a row instead of 13 :p The fix at the time, (see: https://git.buildroot.net/buildroot/commit/?id=786f8b45672ebdd432f6af5b7595d3d16013433b) was to use the package path but with "_" instead of "/", so: boot_barebox_barebox and boot_barebox_barebox_barebox respectively. Also class selectors can't start with numbers so we prepend an "_" to for the sake of packages like 4th and 18xx-ti-utils. The problem I noticed was that having id="column_name__some_really_really_long_path_name" class="centered data _some_really_really_long_path_name" for every element added up after 70k+ elements. the old pkg-stats (https://git.buildroot.net/buildroot/commit/?id=eae86599ca81c943821bac33f424669520a3fa8c) when given the current package list gives me an html file sitting at about 2.9MB. example: https://sen-h.github.io/pkg-stats/eae86599ca81c943821bac33f424669520a3fa8c.html The current pkg-stats gives me a whopping 7MB file. example: https://sen-h.github.io/pkg-stats/c245575.html but you can see this whittled down by [PATCH v2 1/2]: https://sen-h.github.io/pkg-stats/b6f4cbddb14233c3ab3fdfea1e486c14871cfb2a.html (3.2M) and then by [PATCH v1 2/2]: https://sen-h.github.io/pkg-stats/9ad05210dcd9e4fb6b6a45be87c0fbb3e022085b.html (2.6M) in essence, we go from: <div id="upstream_url__package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream" class="centered upstream_url data _package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream good_url"><a href="https://github.com/xbmc/audiodecoder.vgmstream">Link</a></div> and then with [PATCH v2 1/2]: <div class="centered data good_url"><a href="https://github.com/xbmc/audiodecoder.vgmstream">Link</a></div> which after our column/row class assignment script runs becomes: <div class="centered data good_url c10 ir755"><a href="https://github.com/xbmc/audiodecoder.vgmstream">Link</a></div> and finally with [PATCH v2 2/2]: <div class="good_url"><a href="https://github.com/xbmc/audiodecoder.vgmstream">Link</a></div> and once again after the script runs: <div class="good_url c10 ir755"><a href="https://github.com/xbmc/audiodecoder.vgmstream">Link</a></div> and here's the old sorttable version just for comparison: <td class="centered missing_url invalid_url"><a href="https://github.com/xbmc/audiodecoder.vgmstream">invalid (err)</a></td> So why not just ship the class selectors "cX irX" for every element instead of generating them client side? I experimented with that but once again it's a size thing. Every order of magnitude (10-100-1000) adds another digit (character) to the ir (initial row) class selector. Right now it's about 300k which doesn't seem like much but could really add up over time. The pages being generated right now would be considered *quite* big by most standards, so I'm really just trying to whittle everything down to the absolute bare minimum. >> function sortGrid(sortLabel){ >> let i = 0; >> let pkgSortArray = [], sortedPkgArray = [], pkgStringSortArray = [], pkgNumSortArray = []; >> @@ -774,14 +785,11 @@ function sortGrid(sortLabel){ >> const styleSheet = styleElement.sheet; >> >> columnValues.shift(); >> - columnValues.forEach((listing) => { >> + columnValues.forEach((listing) => { > > This is a spurious change. > >> if (fieldText == "see all " + fieldTotal + triangleDown){ >> - field.firstElementChild.innerText = "see less " + fieldTotal + triangleUp; >> + field.firstElementChild.innerText = "see less " + fieldTotal + triangleUp; > > This is also a spurious change. > Shoot, those are pretty spurious. I'll go ahead and fix that. > Thanks! > > Thomas _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Buildroot] [PATCH v1 2/2] support/scripts/pkg-stats: optimize CSS selector usage 2022-08-08 22:23 Sen Hastings @ 2022-08-08 22:23 ` Sen Hastings 2022-08-30 6:34 ` Sen Hastings 0 siblings, 1 reply; 7+ messages in thread From: Sen Hastings @ 2022-08-08 22:23 UTC (permalink / raw) To: Thomas Petazzoni; +Cc: Sen Hastings, buildroot On 8/6/22 16:55, Thomas Petazzoni wrote: > Hello Sen, > > On Fri, 5 Aug 2022 15:01:14 -0500 > Sen Hastings <sen@phobosdpl.com> wrote: > >> Having lots of CSS selector declarations adds up, especially at 70k+ >> elements. >> >> This reduces the number of CSS selectors printed in the markup >> to the bare minimum, by using pseudo-classes and tag names as selectors. > > Not sure how this works. See my explination below about magic number 13. :-) >Is there a significant size benefit? Absolutely. I actually had a cover letter for v0 of the patchset: https://lore.kernel.org/buildroot/20220805185821.261049-1-sen@phobosdpl.com/ Just as a quick rundown: The old pkg-stats, (https://git.buildroot.net/buildroot/commit/?id=eae86599ca81c943821bac33f424669520a3fa8c) when given the current package list gives me an html file sitting at about 2.9MB. example: https://sen-h.github.io/pkg-stats/eae86599ca81c943821bac33f424669520a3fa8c.html The current pkg-stats gives me a whopping 7MB file. example: https://sen-h.github.io/pkg-stats/c245575.html but you can see this whittled down by [PATCH v2 1/2]: https://sen-h.github.io/pkg-stats/b6f4cbddb14233c3ab3fdfea1e486c14871cfb2a.html (3.2M) and then by [PATCH v1 2/2]: https://sen-h.github.io/pkg-stats/9ad05210dcd9e4fb6b6a45be87c0fbb3e022085b.html (2.6M) > Sometimes having a dumb but obvious solution is better than having a > smart but convoluted solution. Although I admit nth-child seems exotic, I think it's actually pretty straightforward. CSS is of course all about cascade and layers of specificity, and I definitely think the size savings is worth it. > >> +div { >> + text-align: center; >> + border: solid 1px gray; >> +} >> +#results-grid div{ >> + text-align: left; >> +} >> +#package-grid div:nth-child(13n+1), #package-grid div:nth-child(13n+13) { >> + text-align: left; >> +} >> +#package-grid div:nth-child(13){ >> + text-align: center; > > What is this 13 magic number? 13 is the the number of columns. Rather than giving every item that needs to be centered a "centered" class selector, we center all div elements and then selectively left-align the ones we want. div { text-align: center;}: centers all div elements, which includes the cells in the grid. #package-grid div:nth-child(13n+1): selects the first element in the grid and then every 13th+1 element thereafter: (13*0)+1 = 1, (13*1)+1 = 14, (13*2)+1 = 27 etc... this effectively targets every cell in the left-most column. #package-grid div:nth-child(13n+13): selects the 13th element in the grid and then every 13th element thereafter: (13*0)+13 = 13, (13*1)+13 = 26, (13*2)+13 = 39 etc... this effectively targets every cell in the right-most column. so our columns go from this: 1 2 3 4-12 13 | label | label | label |...| label | | data | data | data |...| data | to this: 1 2 3 4-12 13 |label | label | label |...|label | |data | data | data |...|data | Except that traditionally the right-most column label is centered. (at least that's how it was when I started) so we use: #package-grid div:nth-child(13){text-align: center;} to center *just* the right-most column label (the 13th element) so now it's: 1 2 3 4-12 13 |label | label | label |...| label | |data | data | data |...|data | see: https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child#examples > > Also, unrelated to this, when I look at the currently generated HTML, > it looks odd. I see things like this: > > <div id="upstream_url__package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream" class="centered upstream_url data _package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream good_url"><a href="https://github.com/xbmc/audiodecoder.vgmstream">Link</a></div> > > Why do we have these crazy id values now? why does the class property > contain a value such as > _package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream? Good question. It has to do with sortGrid() needing unique class selectors per row. see: https://git.buildroot.net/buildroot/commit/?id=786f8b45672ebdd432f6af5b7595d3d16013433b sortGrid() sorts by virtue of all the elements in a column sharing the same class (which orginally was also the column label) and all the elements in a row also sharing the same class (which originally was also the package name). The problem (previously) was that some package names were duplicated across rows. For instance look at these two cells in the package column: <div id="package_barebox" class="package data barebox">boot/barebox/barebox.mk</div> <div id="package_barebox" class="package data barebox">boot/barebox/barebox/barebox.mk</div> these are the beginning cells of two rows and they both share the *same* class selector "barebox". Can't have that because we need every row to have a unique class assigned to it. Otherwise when we sort this happens: |label | label | label |...| label | |class1 | class1 | class1 |...|class1 | |class1 | class1 | class1 |...|class1 | becomes: |label | label | label |...| label | |class1 | class1 | class1 |...|class1 |class1 | class1 | class1 |...|class1 | sortGrid pulls all elements by row class selector and gives them an explicit grid-row assignment. So now we have 26 elements in a row instead of 13 :p The fix at the time,was to use the package path but with "_" instead of "/", so: boot_barebox_barebox and boot_barebox_barebox_barebox respectively. Also class selectors can't start with numbers so we prepend an "_" to for the sake of packages like 4th and 18xx-ti-utils. sortGrid (used to) derive the package class selector for the whole row by stripping it out of the id. sortArr[0] = listing.id.replace(sortLabel+"_", ""); so: sortArr[0] = "upstream_url__package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream".replace("upstream_url_", "") yielding: sortArr[0] = "_package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream" PATCH v2 1/2 does away with this and uses programmatically generated column/row class selectors. I understand that javascript probably isn't a langauge most people on the mailing list are familiar with, especially when it comes to the DOM api. So this email (and the previous one) are more of "why" and less of a "how", but if it would be helpful I could do a line-by-line walkthrough of sortGrid() just to go through how everything works. Hope that helps. > Thanks! > > Thomas _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Buildroot] [PATCH v1 2/2] support/scripts/pkg-stats: optimize CSS selector usage 2022-08-08 22:23 ` [Buildroot] [PATCH v1 2/2] support/scripts/pkg-stats: optimize CSS selector usage Sen Hastings @ 2022-08-30 6:34 ` Sen Hastings 0 siblings, 0 replies; 7+ messages in thread From: Sen Hastings @ 2022-08-30 6:34 UTC (permalink / raw) To: sen; +Cc: thomas.petazzoni, buildroot On 8/6/22 16:55, Thomas Petazzoni wrote: > Hello Sen, > > On Fri, 5 Aug 2022 15:01:14 -0500 > Sen Hastings <sen@phobosdpl.com> wrote: > >> Having lots of CSS selector declarations adds up, especially at 70k+ >> elements. >> >> This reduces the number of CSS selectors printed in the markup >> to the bare minimum, by using pseudo-classes and tag names as selectors. > > Not sure how this works. See my explination below about magic number 13. :-) >Is there a significant size benefit? Absolutely. I actually had a cover letter for v0 of the patchset: https://lore.kernel.org/buildroot/20220805185821.261049-1-sen@phobosdpl.com/ Just as a quick rundown: The old pkg-stats, (https://git.buildroot.net/buildroot/commit/?id=eae86599ca81c943821bac33f424669520a3fa8c) when given the current package list gives me an html file sitting at about 2.9MB. example: https://sen-h.github.io/pkg-stats/eae86599ca81c943821bac33f424669520a3fa8c.html The current pkg-stats gives me a whopping 7MB file. example: https://sen-h.github.io/pkg-stats/c245575.html but you can see this whittled down by [PATCH v2 1/2]: https://sen-h.github.io/pkg-stats/b6f4cbddb14233c3ab3fdfea1e486c14871cfb2a.html (3.2M) and then by [PATCH v1 2/2]: https://sen-h.github.io/pkg-stats/9ad05210dcd9e4fb6b6a45be87c0fbb3e022085b.html (2.6M) > Sometimes having a dumb but obvious solution is better than having a > smart but convoluted solution. Although I admit nth-child seems exotic, I think it's actually pretty straightforward. CSS is of course all about cascade and layers of specificity, and I definitely think the size savings is worth it. > >> +div { >> + text-align: center; >> + border: solid 1px gray; >> +} >> +#results-grid div{ >> + text-align: left; >> +} >> +#package-grid div:nth-child(13n+1), #package-grid div:nth-child(13n+13) { >> + text-align: left; >> +} >> +#package-grid div:nth-child(13){ >> + text-align: center; > > What is this 13 magic number? 13 is the the number of columns. Rather than giving every item that needs to be centered a "centered" class selector, we center all div elements and then selectively left-align the ones we want. div { text-align: center;}: centers all div elements, which includes the cells in the grid. #package-grid div:nth-child(13n+1): selects the first element in the grid and then every 13th+1 element thereafter: (13*0)+1 = 1, (13*1)+1 = 14, (13*2)+1 = 27 etc... this effectively targets every cell in the left-most column. #package-grid div:nth-child(13n+13): selects the 13th element in the grid and then every 13th element thereafter: (13*0)+13 = 13, (13*1)+13 = 26, (13*2)+13 = 39 etc... this effectively targets every cell in the right-most column. so our columns go from this: 1 2 3 4-12 13 | label | label | label |...| label | | data | data | data |...| data | to this: 1 2 3 4-12 13 |label | label | label |...|label | |data | data | data |...|data | Except that traditionally the right-most column label is centered. (at least that's how it was when I started) so we use: #package-grid div:nth-child(13){text-align: center;} to center *just* the right-most column label (the 13th element) so now it's: 1 2 3 4-12 13 |label | label | label |...| label | |data | data | data |...|data | see: https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child#examples > > Also, unrelated to this, when I look at the currently generated HTML, > it looks odd. I see things like this: > > <div id="upstream_url__package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream" class="centered upstream_url data _package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream good_url"><a href="https://github.com/xbmc/audiodecoder.vgmstream">Link</a></div> > > Why do we have these crazy id values now? why does the class property > contain a value such as > _package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream? Good question. It has to do with sortGrid() needing unique class selectors per row. see: https://git.buildroot.net/buildroot/commit/?id=786f8b45672ebdd432f6af5b7595d3d16013433b sortGrid() sorts by virtue of all the elements in a column sharing the same class (which orginally was also the column label) and all the elements in a row also sharing the same class (which originally was also the package name). The problem (previously) was that some package names were duplicated across rows. For instance look at these two cells in the package column: <div id="package_barebox" class="package data barebox">boot/barebox/barebox.mk</div> <div id="package_barebox" class="package data barebox">boot/barebox/barebox/barebox.mk</div> these are the beginning cells of two rows and they both share the *same* class selector "barebox". Can't have that because we need every row to have a unique class assigned to it. Otherwise when we sort this happens: |label | label | label |...| label | |class1 | class1 | class1 |...|class1 | |class1 | class1 | class1 |...|class1 | becomes: |label | label | label |...| label | |class1 | class1 | class1 |...|class1 |class1 | class1 | class1 |...|class1 | sortGrid pulls all elements by row class selector and gives them an explicit grid-row assignment. So now we have 26 elements in a row instead of 13 :p The fix at the time,was to use the package path but with "_" instead of "/", so: boot_barebox_barebox and boot_barebox_barebox_barebox respectively. Also class selectors can't start with numbers so we prepend an "_" to for the sake of packages like 4th and 18xx-ti-utils. sortGrid (used to) derive the package class selector for the whole row by stripping it out of the id. sortArr[0] = listing.id.replace(sortLabel+"_", ""); so: sortArr[0] = "upstream_url__package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream".replace("upstream_url_", "") yielding: sortArr[0] = "_package_kodi-audiodecoder-vgmstream_kodi-audiodecoder-vgmstream" PATCH v2 1/2 does away with this and uses programmatically generated column/row class selectors. I understand that javascript probably isn't a langauge most people on the mailing list are familiar with, especially when it comes to the DOM api. So this email (and the previous one) are more of "why" and less of a "how", but if it would be helpful I could do a line-by-line walkthrough of sortGrid() just to go through how everything works. Hope that helps. [note: I originally sent this out on the 2022-08-08, but not as reply to the previous message, so it just showed up as a normal submission to the mailing list. Re-submitting it for the sake of posterity.] > Thanks! > > Thomas _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2022-08-30 6:34 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-08-05 20:01 [Buildroot] [PATCH v2 1/2] support/scripts/pkg-stats: move to procedurally generated row/column clases Sen Hastings 2022-08-05 20:01 ` [Buildroot] [PATCH v1 2/2] support/scripts/pkg-stats: optimize CSS selector usage Sen Hastings 2022-08-06 21:55 ` Thomas Petazzoni via buildroot 2022-08-06 21:51 ` [Buildroot] [PATCH v2 1/2] support/scripts/pkg-stats: move to procedurally generated row/column clases Thomas Petazzoni via buildroot 2022-08-30 6:32 ` Sen Hastings -- strict thread matches above, loose matches on Subject: below -- 2022-08-08 22:23 Sen Hastings 2022-08-08 22:23 ` [Buildroot] [PATCH v1 2/2] support/scripts/pkg-stats: optimize CSS selector usage Sen Hastings 2022-08-30 6:34 ` Sen Hastings
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox