[gold] Port dots-legend-sk to TypeScript.
Bug: skia:10246
Change-Id: Ib562f48cadce8b7e34d26279b69c656a59eed6d7
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/397336
Commit-Queue: Leandro Lovisolo <lovisolo@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
diff --git a/golden/modules/dots-legend-sk/dots-legend-sk-demo.js b/golden/modules/dots-legend-sk/dots-legend-sk-demo.ts
similarity index 73%
rename from golden/modules/dots-legend-sk/dots-legend-sk-demo.js
rename to golden/modules/dots-legend-sk/dots-legend-sk-demo.ts
index 9f2df5b..0e02717 100644
--- a/golden/modules/dots-legend-sk/dots-legend-sk-demo.js
+++ b/golden/modules/dots-legend-sk/dots-legend-sk-demo.ts
@@ -1,7 +1,8 @@
import './index';
-import { $$ } from 'common-sk/modules/dom';
+import { DigestStatus } from '../rpc_types';
+import { DotsLegendSk } from './dots-legend-sk';
-const someDigests = [
+const someDigests: DigestStatus[] = [
{ digest: 'ce0a9d2b546b25e00e39a33860cb72b6', status: 'untriaged' },
{ digest: '34e87ca0f753cf4c884fa01af6c08be9', status: 'positive' },
{ digest: '8ee9a2c61e9f12e6243f07423302f26a', status: 'negative' },
@@ -9,7 +10,7 @@
{ digest: 'dcccd6998b47f60ab28dcff17ae57ed2', status: 'positive' },
];
-const tooManyDigests = [
+const tooManyDigests: DigestStatus[] = [
...someDigests,
{ digest: '92d9faf80a25750629118018716387df', status: 'positive' },
{ digest: '1bc4771dcee95d97b2758a1e1945cc40', status: 'untriaged' },
@@ -18,14 +19,15 @@
{ digest: 'b00cb97f0d4dd7b22fb9af5378918d9f', status: 'untriaged' },
];
-function newDotsLegendSk(parentSelector, id, digests, clID, test) {
- const dotsLegendSk = document.createElement('dots-legend-sk');
+function newDotsLegendSk(
+ parentSelector: string, id: string, digests: DigestStatus[], clID: string, test: string) {
+ const dotsLegendSk = new DotsLegendSk();
dotsLegendSk.id = id;
dotsLegendSk.digests = digests;
dotsLegendSk.changeListID = clID;
dotsLegendSk.test = test;
dotsLegendSk.totalDigests = digests.length;
- $$(parentSelector).appendChild(dotsLegendSk);
+ document.querySelector(parentSelector)!.appendChild(dotsLegendSk);
}
newDotsLegendSk(
diff --git a/golden/modules/dots-legend-sk/dots-legend-sk.js b/golden/modules/dots-legend-sk/dots-legend-sk.js
deleted file mode 100644
index 1a80f46..0000000
--- a/golden/modules/dots-legend-sk/dots-legend-sk.js
+++ /dev/null
@@ -1,162 +0,0 @@
-/**
- * @module modules/dots-legend-sk
- * @description <h2><code>dots-legend-sk</code></h2>
- *
- * A legend for the dots-sk element.
- */
-
-import { define } from 'elements-sk/define';
-import { html } from 'lit-html';
-import { ElementSk } from '../../../infra-sk/modules/ElementSk';
-import {
- DOT_STROKE_COLORS,
- DOT_FILL_COLORS,
- MAX_UNIQUE_DIGESTS,
-} from '../dots-sk/constants';
-import { detailHref, diffPageHref } from '../common';
-
-import 'elements-sk/icon/cancel-icon-sk';
-import 'elements-sk/icon/check-circle-icon-sk';
-import 'elements-sk/icon/help-icon-sk';
-
-const template = (el) => html`
- ${el._digests
- .slice(0, MAX_UNIQUE_DIGESTS - 1)
- .map((digest, index) => digestTemplate(digest, index, el))}
-
- ${lastDigest(el)}
-`;
-
-const digestTemplate = (digest, index, el) => html`
- ${dotTemplate(index)}
- <a target=_blank class=digest href="${el._digestDetailHref(index)}">
- ${digest.digest}
- </a>
- ${statusIconTemplate(digest.status)}
- ${index > 0
- ? html`<a target=_blank class=diff href="${el._digestDiffHref(index)}">
- diff
- </a>`
- : html`<span></span>`}
-`;
-
-const lastDigest = (el) => {
- // If the API returns fewer digests than MAX_UNIQUE_DIGESTS, we should compare against
- // the reported totalDigests to determine if we need to display nothing (no more digests),
- // the last digest (if it exactly matches the maximum) or the message saying there were too
- // many digests to display them all.
- if (el.totalDigests < MAX_UNIQUE_DIGESTS) {
- return '';
- }
- if (el.totalDigests === MAX_UNIQUE_DIGESTS) {
- return digestTemplate(el.digests[MAX_UNIQUE_DIGESTS - 1], MAX_UNIQUE_DIGESTS - 1, el);
- }
- return oneOfManyOtherDigestsTemplate(el.totalDigests);
-};
-
-const oneOfManyOtherDigestsTemplate = (totalDigests) => html`
- ${dotTemplate(MAX_UNIQUE_DIGESTS - 1)}
- <span class=one-of-many-other-digests>
- One of ${totalDigests - (MAX_UNIQUE_DIGESTS - 1)} other digests
- (${totalDigests} in total).
- </span>
-`;
-
-const dotTemplate = (index) => {
- const style = `border-color: ${DOT_STROKE_COLORS[index]};`
- + `background-color: ${DOT_FILL_COLORS[index]};`;
- return html`<div class=dot style="${style}"></div>`;
-};
-
-const statusIconTemplate = (status) => {
- switch (status) {
- case 'negative':
- return html`<cancel-icon-sk class=negative-icon></cancel-icon-sk>`;
- case 'positive':
- return html`
- <check-circle-icon-sk class=positive-icon></check-circle-icon-sk>
- `;
- case 'untriaged':
- return html`<help-icon-sk class=untriaged-icon></help-icon-sk>`;
- default:
- throw `Unknown status: "${status}"`;
- }
-};
-
-define('dots-legend-sk', class extends ElementSk {
- constructor() {
- super(template);
- this._digests = [];
- this._changeListID = '';
- this._crs = '';
- this._test = '';
- this._totalDigests = 0;
- }
-
- connectedCallback() {
- super.connectedCallback();
- this._render();
- }
-
- /**
- * @prop digests {Array} An array of {digest: 'a4f32...', status: 'positive'}
- * objects.
- */
- get digests() { return this._digests; }
-
- set digests(digests) {
- this._digests = digests;
- this._render();
- }
-
- /**
- * @prop changeListID {string} The changelist id (or empty string if this is the master branch).
- */
- get changeListID() { return this._changeListID; }
-
- set changeListID(id) {
- this._changeListID = id;
- this._render();
- }
-
- /**
- * @prop crs {string} The Code Review System (e.g. "gerrit") if changeListID is set.
- */
- get crs() { return this._crs; }
-
- set crs(c) {
- this._crs = c;
- this._render();
- }
-
- /**
- * @prop test {string} Test name.
- */
- get test() { return this._test; }
-
- set test(test) {
- this._test = test;
- this._render();
- }
-
- /**
- * @prop totalDigests {Number} The total number of digests that were seen in this group of traces,
- * which can be more than digests.length, due to the fact that the backend limits the length
- * of digests when it sends it to us.
- */
- get totalDigests() { return this._totalDigests; }
-
- set totalDigests(td) {
- this._totalDigests = td;
- this._render();
- }
-
- _digestDetailHref(index) {
- return detailHref(this._test, this._digests[index].digest, this.changeListID, this.crs);
- }
-
- _digestDiffHref(index) {
- return diffPageHref(this._test, this._digests[0].digest, this._digests[index].digest,
- this.changeListID, this.crs);
- }
-});
diff --git a/golden/modules/dots-legend-sk/dots-legend-sk.ts b/golden/modules/dots-legend-sk/dots-legend-sk.ts
new file mode 100644
index 0000000..dd6860d
--- /dev/null
+++ b/golden/modules/dots-legend-sk/dots-legend-sk.ts
@@ -0,0 +1,158 @@
+/**
+ * @module modules/dots-legend-sk
+ * @description <h2><code>dots-legend-sk</code></h2>
+ *
+ * A legend for the dots-sk element.
+ */
+
+import { define } from 'elements-sk/define';
+import { html } from 'lit-html';
+import { ElementSk } from '../../../infra-sk/modules/ElementSk';
+import {
+ DOT_STROKE_COLORS,
+ DOT_FILL_COLORS,
+ MAX_UNIQUE_DIGESTS,
+} from '../dots-sk/constants';
+import { detailHref, diffPageHref } from '../common';
+import { DigestStatus, Label } from '../rpc_types';
+
+import 'elements-sk/icon/cancel-icon-sk';
+import 'elements-sk/icon/check-circle-icon-sk';
+import 'elements-sk/icon/help-icon-sk';
+
+export class DotsLegendSk extends ElementSk {
+ private static template = (el: DotsLegendSk) => html`
+ ${el._digests
+ .slice(0, MAX_UNIQUE_DIGESTS - 1)
+ .map((digest, index) => DotsLegendSk.digestTemplate(el, digest, index))}
+
+ ${DotsLegendSk.lastDigest(el)}
+ `;
+
+ private static digestTemplate = (el: DotsLegendSk, digest: DigestStatus, index: number) => html`
+ ${DotsLegendSk.dotTemplate(index)}
+ <a target=_blank class=digest href="${el.digestDetailHref(index)}">
+ ${digest.digest}
+ </a>
+ ${DotsLegendSk.statusIconTemplate(digest.status)}
+ ${index > 0
+ ? html`<a target=_blank class=diff href="${el.digestDiffHref(index)}">
+ diff
+ </a>`
+ : html`<span></span>`}
+ `;
+
+ private static lastDigest = (el: DotsLegendSk) => {
+ // If the API returns fewer digests than MAX_UNIQUE_DIGESTS, we should compare against
+ // the reported totalDigests to determine if we need to display nothing (no more digests),
+ // the last digest (if it exactly matches the maximum) or the message saying there were too
+ // many digests to display them all.
+ if (el.totalDigests < MAX_UNIQUE_DIGESTS) {
+ return '';
+ }
+ if (el.totalDigests === MAX_UNIQUE_DIGESTS) {
+ return DotsLegendSk.digestTemplate(
+ el, el.digests[MAX_UNIQUE_DIGESTS - 1], MAX_UNIQUE_DIGESTS - 1);
+ }
+ return DotsLegendSk.oneOfManyOtherDigestsTemplate(el.totalDigests);
+ };
+
+ private static oneOfManyOtherDigestsTemplate = (totalDigests: number) => html`
+ ${DotsLegendSk.dotTemplate(MAX_UNIQUE_DIGESTS - 1)}
+ <span class=one-of-many-other-digests>
+ One of ${totalDigests - (MAX_UNIQUE_DIGESTS - 1)} other digests
+ (${totalDigests} in total).
+ </span>
+ `;
+
+ private static dotTemplate = (index: number) => {
+ const style = `border-color: ${DOT_STROKE_COLORS[index]};`
+ + `background-color: ${DOT_FILL_COLORS[index]};`;
+ return html`<div class=dot style="${style}"></div>`;
+ };
+
+ private static statusIconTemplate = (status: Label) => {
+ switch (status) {
+ case 'negative':
+ return html`<cancel-icon-sk class=negative-icon></cancel-icon-sk>`;
+ case 'positive':
+ return html`
+ <check-circle-icon-sk class=positive-icon></check-circle-icon-sk>
+ `;
+ case 'untriaged':
+ return html`<help-icon-sk class=untriaged-icon></help-icon-sk>`;
+ default:
+ throw `Unknown status: "${status}"`;
+ }
+ };
+
+ private _digests: DigestStatus[] = [];
+ private _changeListID = '';
+ private _crs = '';
+ private _test = '';
+ private _totalDigests = 0;
+
+ constructor() {
+ super(DotsLegendSk.template);
+ }
+
+ connectedCallback() {
+ super.connectedCallback();
+ this._render();
+ }
+
+ /** The digests to show. */
+ get digests(): DigestStatus[] { return this._digests; }
+
+ set digests(digests: DigestStatus[]) {
+ this._digests = digests;
+ this._render();
+ }
+
+ /** The changelist ID (or empty string if this is the master branch). */
+ get changeListID(): string { return this._changeListID; }
+
+ set changeListID(id: string) {
+ this._changeListID = id;
+ this._render();
+ }
+
+ /** The Code Review System (e.g. "gerrit") if changeListID is set. */
+ get crs(): string { return this._crs; }
+
+ set crs(c: string) {
+ this._crs = c;
+ this._render();
+ }
+
+ /** Test name. */
+ get test(): string { return this._test; }
+
+ set test(test: string) {
+ this._test = test;
+ this._render();
+ }
+
+ /**
+ * The total number of digests that were seen in this group of traces, which can be more than
+ * digests.length, due to the fact that the backend limits the length of digests when it sends it
+ * to us.
+ */
+ get totalDigests(): number { return this._totalDigests; }
+
+ set totalDigests(td: number) {
+ this._totalDigests = td;
+ this._render();
+ }
+
+ private digestDetailHref(index: number): string {
+ return detailHref(this._test, this._digests[index].digest, this.changeListID, this.crs);
+ }
+
+ private digestDiffHref(index: number): string {
+ return diffPageHref(this._test, this._digests[0].digest, this._digests[index].digest,
+ this.changeListID, this.crs);
+ }
+}
+
+define('dots-legend-sk', DotsLegendSk);
diff --git a/golden/modules/dots-legend-sk/dots-legend-sk_test.js b/golden/modules/dots-legend-sk/dots-legend-sk_test.ts
similarity index 83%
rename from golden/modules/dots-legend-sk/dots-legend-sk_test.js
rename to golden/modules/dots-legend-sk/dots-legend-sk_test.ts
index 1a3b266..32dbb29 100644
--- a/golden/modules/dots-legend-sk/dots-legend-sk_test.js
+++ b/golden/modules/dots-legend-sk/dots-legend-sk_test.ts
@@ -6,11 +6,13 @@
MAX_UNIQUE_DIGESTS,
} from '../dots-sk/constants';
import { setUpElementUnderTest } from '../../../infra-sk/modules/test_util';
+import { DotsLegendSk } from './dots-legend-sk';
+import { expect } from 'chai';
describe('dots-legend-sk', () => {
- const newInstance = setUpElementUnderTest('dots-legend-sk');
+ const newInstance = setUpElementUnderTest<DotsLegendSk>('dots-legend-sk');
- let dotsLegendSk;
+ let dotsLegendSk: DotsLegendSk;
beforeEach(() => dotsLegendSk = newInstance());
describe('with less than MAX_UNIQUE_DIGESTS unique digests', () => {
@@ -50,7 +52,7 @@
});
it('renders digest links correctly', () => {
- const digestLinkFor = (d) => `/detail?test=My%20Test&digest=${d}`;
+ const digestLinkFor = (d: string) => `/detail?test=My%20Test&digest=${d}`;
expect(digestLinks(dotsLegendSk)).to.deep.equal([
digestLinkFor('00000000000000000000000000000000'),
digestLinkFor('11111111111111111111111111111111'),
@@ -71,8 +73,8 @@
});
it('renders diff links correctly', () => {
- const diffLinkFor = (d) => '/diff?test=My%20Test&left=00000000000000000000000000000000'
- + `&right=${d}`;
+ const diffLinkFor =
+ (d: string) => `/diff?test=My%20Test&left=00000000000000000000000000000000&right=${d}`;
expect(diffLinks(dotsLegendSk)).to.deep.equal([
diffLinkFor('11111111111111111111111111111111'),
diffLinkFor('22222222222222222222222222222222'),
@@ -89,8 +91,8 @@
});
it('renders digest links correctly', () => {
- const digestLinkFor = (d) => `/detail?test=My%20Test&digest=${d}`
- + '&changelist_id=123456&crs=gerrit';
+ const digestLinkFor = (d:string) =>
+ `/detail?test=My%20Test&digest=${d}&changelist_id=123456&crs=gerrit`;
expect(digestLinks(dotsLegendSk)).to.deep.equal([
digestLinkFor('00000000000000000000000000000000'),
digestLinkFor('11111111111111111111111111111111'),
@@ -101,8 +103,9 @@
});
it('renders diff links correctly', () => {
- const diffLinkFor = (d) => '/diff?test=My%20Test&left=00000000000000000000000000000000'
- + `&right=${d}&changelist_id=123456&crs=gerrit`;
+ const diffLinkFor = (d: string) =>
+ '/diff?test=My%20Test&left=00000000000000000000000000000000' +
+ `&right=${d}&changelist_id=123456&crs=gerrit`;
expect(diffLinks(dotsLegendSk)).to.deep.equal([
diffLinkFor('11111111111111111111111111111111'),
diffLinkFor('22222222222222222222222222222222'),
@@ -175,8 +178,8 @@
});
it('renders diff links correctly', () => {
- const diffLinkFor = (d) => '/diff?test=My%20Test&left=00000000000000000000000000000000'
- + `&right=${d}`;
+ const diffLinkFor = (d: string) =>
+ `/diff?test=My%20Test&left=00000000000000000000000000000000&right=${d}`;
expect(diffLinks(dotsLegendSk)).to.deep.equal([
diffLinkFor('11111111111111111111111111111111'),
diffLinkFor('22222222222222222222222222222222'),
@@ -255,8 +258,8 @@
});
it('renders diff links correctly', () => {
- const diffLinkFor = (d) => '/diff?test=My%20Test&left=00000000000000000000000000000000'
- + `&right=${d}`;
+ const diffLinkFor = (d: string) =>
+ `/diff?test=My%20Test&left=00000000000000000000000000000000&right=${d}`;
expect(diffLinks(dotsLegendSk)).to.deep.equal([
diffLinkFor('11111111111111111111111111111111'),
diffLinkFor('22222222222222222222222222222222'),
@@ -272,29 +275,30 @@
// Takes a color represented as an RGB string (e.g. "rgb(10, 187, 204)") and
// returns the equivalent hex string (e.g. "#0ABBCC").
-const rgbToHex = (rgb) => `#${rgb.match(/rgb\((\d+), (\d+), (\d+)\)/)
+const rgbToHex = (rgb: string): string => `#${rgb.match(/rgb\((\d+), (\d+), (\d+)\)/)!
.slice(1) // ['10', '187', '204'].
- .map((x) => parseInt(x)) // [10, 187, 204]
- .map((x) => x.toString(16)) // ['a', 'bb', 'cc']
- .map((x) => x.padStart(2, '0')) // ['0a', 'bb', 'cc']
- .map((x) => x.toUpperCase()) // ['0A', 'BB', 'CC']
+ .map((x: string) => parseInt(x)) // [10, 187, 204]
+ .map((x: number) => x.toString(16)) // ['a', 'bb', 'cc']
+ .map((x: string) => x.padStart(2, '0')) // ['0a', 'bb', 'cc']
+ .map((x: string) => x.toUpperCase()) // ['0A', 'BB', 'CC']
.join('')}`; // '0ABBCC'
// Returns the dot colors as an array of arrays of the form
// ["stroke color", "fill color"], where the colors are represented as hex
// strings (e.g. "#AABBCC").
-const dotColors = (dotsLegendSk) => $('div.dot', dotsLegendSk)
- .map((dot) => [
- rgbToHex(dot.style.borderColor),
- rgbToHex(dot.style.backgroundColor),
- ]);
+const dotColors = (dotsLegendSk: DotsLegendSk): [string, string][] =>
+ $<HTMLDivElement>('div.dot', dotsLegendSk).map((dot) => [
+ rgbToHex(dot.style.borderColor),
+ rgbToHex(dot.style.backgroundColor),
+ ]);
-const digests = (dotsLegendSk) => $('a.digest, span.one-of-many-other-digests', dotsLegendSk)
- .map((a) => a.innerText.trim());
+const digests = (dotsLegendSk: DotsLegendSk): string[] =>
+ $<HTMLElement>('a.digest, span.one-of-many-other-digests', dotsLegendSk)
+ .map((a) => a.innerText.trim());
-// Returns the status icons as an array of strings. Possible values are
+// Returns the status icons as an array of strings. Possible values are
// are "negative", "positive", "untriaged".
-const statusIcons = (dotsLegendSk) => $([
+const statusIcons = (dotsLegendSk: DotsLegendSk): string[] => $([
'cancel-icon-sk.negative-icon',
'check-circle-icon-sk.positive-icon',
'help-icon-sk.untriaged-icon',
@@ -303,11 +307,13 @@
// Takes an URL string (e.g. "http://example.com/search?q=hello") and returns
// only the path and query string (e.g. "/search?q=hello").
-const urlToPathAndQueryString = (urlStr) => {
+const urlToPathAndQueryString = (urlStr: string): string => {
const url = new URL(urlStr);
return url.pathname + url.search;
};
-const digestLinks = (dotsLegendSk) => $('a.digest', dotsLegendSk).map((a) => urlToPathAndQueryString(a.href));
+const digestLinks = (dotsLegendSk: DotsLegendSk): string[] =>
+ $<HTMLAnchorElement>('a.digest', dotsLegendSk).map((a) => urlToPathAndQueryString(a.href));
-const diffLinks = (dotsLegendSk) => $('a.diff', dotsLegendSk).map((a) => urlToPathAndQueryString(a.href));
+const diffLinks = (dotsLegendSk: DotsLegendSk): string[] =>
+ $<HTMLAnchorElement>('a.diff', dotsLegendSk).map((a) => urlToPathAndQueryString(a.href));
diff --git a/golden/modules/dots-legend-sk/index.js b/golden/modules/dots-legend-sk/index.ts
similarity index 100%
rename from golden/modules/dots-legend-sk/index.js
rename to golden/modules/dots-legend-sk/index.ts