From 80c60ae64659e32eead29f13c839d698ec59603b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20C=C3=A1ceres?= Date: Wed, 16 Jun 2021 09:30:31 +1000 Subject: [PATCH] fix(w3c/headers): allow overriding latestVersion: (#3625) --- src/w3c/headers.js | 87 +++++++++++++++++++--------------- tests/spec/w3c/headers-spec.js | 48 ++++++++++++++++++- 2 files changed, 95 insertions(+), 40 deletions(-) diff --git a/src/w3c/headers.js b/src/w3c/headers.js index dff1d18597..0db33eacff 100644 --- a/src/w3c/headers.js +++ b/src/w3c/headers.js @@ -63,8 +63,7 @@ // PAG on the document. // - thisVersion: the URI to the dated current version of the specification. ONLY ever use this for CG/BG // documents, for all others it is autogenerated. -// - latestVersion: the URI to the latest (undated) version of the specification. ONLY ever use this for CG/BG -// documents, for all others it is autogenerated. +// - latestVersion: the URI to the latest version of the specification. // - prevVersion: the URI to the previous (dated) version of the specification. ONLY ever use this for CG/BG // documents, for all others it is autogenerated. // - subjectPrefix: the string that is expected to be used as a subject prefix when posting to the mailing @@ -108,6 +107,14 @@ const W3CDate = new Intl.DateTimeFormat(["en-AU"], { day: "2-digit", }); +/** + * Resolves against https://www.w3.org. + * @param {string} href + */ +function w3Url(href) { + return new URL(href, "https://www.w3.org/").href; +} + const status2maturity = { LS: "WD", LD: "WD", @@ -121,6 +128,13 @@ const status2maturity = { "WG-NOTE": "NOTE", }; +const publicationSpaces = { + "Member-SUBM": "/Submission", + "Team-SUBM": "/TeamSubmission/", + finding: "/2001/tag/doc", + "draft-finding": "/2001/tag/doc", +}; + const status2rdf = { NOTE: "w3p:NOTE", WD: "w3p:WD", @@ -369,27 +383,25 @@ export function run(conf) { showWarning(msg, name); } } - conf.maturity = status2maturity[conf.specStatus] - ? status2maturity[conf.specStatus] - : conf.specStatus; - let publishSpace = "TR"; - if (conf.specStatus === "Member-SUBM") publishSpace = "Submission"; - else if (conf.specStatus === "Team-SUBM") publishSpace = "TeamSubmission"; - if (conf.isRegular) - conf.thisVersion = `https://www.w3.org/${publishSpace}/${conf.publishDate.getUTCFullYear()}/${ - conf.maturity - }-${conf.shortName}-${concatDate(conf.publishDate)}/`; + const maturity = status2maturity[conf.specStatus] || conf.specStatus; + const pubSpace = publicationSpaces[conf.specStatus] || "/TR"; + if (conf.isRegular) { + const { shortName, publishDate } = conf; + const year = conf.publishDate.getUTCFullYear(); + const date = concatDate(publishDate); + const docVersion = `${maturity}-${shortName}-${date}`; + conf.thisVersion = w3Url(`${pubSpace}/${year}/${docVersion}/`); + } if (conf.specStatus === "ED") conf.thisVersion = conf.edDraftURI; - const skipLatestVersion = - conf.specStatus === "ED" && conf.latestVersion === null; - if (conf.isRegular && !skipLatestVersion) - conf.latestVersion = `https://www.w3.org/${publishSpace}/${conf.shortName}/`; - if (conf.isTagFinding) { - conf.latestVersion = `https://www.w3.org/2001/tag/doc/${conf.shortName}`; - conf.thisVersion = `${conf.latestVersion}-${ISODate.format( - conf.publishDate - )}`; + + const latestPath = `${pubSpace}/${conf.shortName}`; + + if (conf.latestVersion !== null) { + conf.latestVersion = conf.latestVersion + ? w3Url(`${conf.latestVersion}`) + : w3Url(`${pubSpace}/${conf.shortName}/`); } + if (conf.previousPublishDate) { if (!conf.previousMaturity && !conf.isTagFinding) { const msg = "`previousPublishDate` is set, but not `previousMaturity`."; @@ -401,21 +413,22 @@ export function run(conf) { "previousPublishDate" ); - const pmat = status2maturity[conf.previousMaturity] - ? status2maturity[conf.previousMaturity] - : conf.previousMaturity; - if (conf.isTagFinding) { - conf.prevVersion = `${conf.latestVersion}-${ISODate.format( - conf.previousPublishDate - )}`; - } else if (conf.isCGBG) { + const prevMaturity = + status2maturity[conf.previousMaturity] ?? conf.previousMaturity; + if (conf.isTagFinding && conf.latestVersion) { + const pubDate = ISODate.format(conf.publishDate); + conf.thisVersion = w3Url(`${latestPath}-${pubDate}`); + const prevPubDate = ISODate.format(conf.previousPublishDate); + conf.prevVersion = w3Url(`${latestPath}-${prevPubDate}}`); + } else if (conf.isCGBG || conf.isBasic) { conf.prevVersion = conf.prevVersion || ""; - } else if (conf.isBasic) { - conf.prevVersion = ""; } else { - conf.prevVersion = `https://www.w3.org/TR/${conf.previousPublishDate.getUTCFullYear()}/${pmat}-${ - conf.shortName - }-${concatDate(conf.previousPublishDate)}/`; + const year = conf.previousPublishDate.getUTCFullYear(); + const { shortName } = conf; + const date = concatDate(conf.previousPublishDate); + conf.prevVersion = w3Url( + `${pubSpace}/${year}/${prevMaturity}-${shortName}-${date}/` + ); } } else { if ( @@ -436,7 +449,7 @@ export function run(conf) { if (!conf.prevVersion) conf.prevVersion = ""; } if (conf.prevRecShortname && !conf.prevRecURI) - conf.prevRecURI = `https://www.w3.org/TR/${conf.prevRecShortname}`; + conf.prevRecURI = w3Url(`${pubSpace}/${conf.prevRecShortname}`); if (!conf.formerEditors) conf.formerEditors = []; if (conf.editors) { // Move any editors with retiredDate to formerEditors. @@ -647,9 +660,7 @@ export function run(conf) { conf.recNotExpected = conf.noRecTrack || conf.recNotExpected ? true - : !conf.isRecTrack && - conf.maturity == "WD" && - conf.specStatus !== "FPWD-NOTE"; + : !conf.isRecTrack && maturity == "WD" && conf.specStatus !== "FPWD-NOTE"; if (conf.noRecTrack && recTrackStatus.includes(conf.specStatus)) { const msg = `Document configured as [\`noRecTrack\`](https://github.com/w3c/respec/wiki/noRecTrack), but its status ("${conf.specStatus}") puts it on the W3C Rec Track.`; const hint = `Status cannot be any of: ${recTrackStatus.join(", ")}.`; diff --git a/tests/spec/w3c/headers-spec.js b/tests/spec/w3c/headers-spec.js index aa3facd351..18e7cf8677 100644 --- a/tests/spec/w3c/headers-spec.js +++ b/tests/spec/w3c/headers-spec.js @@ -1214,6 +1214,50 @@ describe("W3C — Headers", () => { expect(latestVersionLink).toBeNull(); expect(latestVersionEl.textContent.trim()).toBe("none"); }); + + it("allows overriding latest published version to a different location", async () => { + const ops = makeStandardOps({ + shortName: "spec", + specStatus: "CR", + latestVersion: "https://somewhere.else/", + }); + const doc = await makeRSDoc(ops); + + const terms = [...doc.querySelectorAll("dt")]; + const latestVersion = terms.find( + el => el.textContent.trim() === "Latest published version:" + ); + expect(latestVersion).toBeTruthy(); + const latestVersionEl = latestVersion.nextElementSibling; + expect(latestVersionEl.localName).toBe("dd"); + const latestVersionLink = latestVersionEl.querySelector("a"); + expect(latestVersionLink.href).toBe("https://somewhere.else/"); + expect(latestVersionEl.textContent.trim()).toBe( + "https://somewhere.else/" + ); + }); + it("allows resolves latestVersion using w3c.org as the base", async () => { + const ops = makeStandardOps({ + shortName: "some-spec", + level: 3, + specStatus: "CR", + latestVersion: "TR/its-here", + }); + const doc = await makeRSDoc(ops); + + const terms = [...doc.querySelectorAll("dt")]; + const latestVersion = terms.find( + el => el.textContent.trim() === "Latest published version:" + ); + expect(latestVersion).toBeTruthy(); + const latestVersionEl = latestVersion.nextElementSibling; + expect(latestVersionEl.localName).toBe("dd"); + const latestVersionLink = latestVersionEl.querySelector("a"); + expect(latestVersionLink.href).toBe("https://www.w3.org/TR/its-here"); + expect(latestVersionEl.textContent.trim()).toBe( + "https://www.w3.org/TR/its-here" + ); + }); }); describe("prevED", () => { @@ -1769,7 +1813,7 @@ describe("W3C — Headers", () => { wg: "WGNAME", wgURI: "http://WG", thisVersion: "http://THIS", - latestVersion: "http://LATEST", + latestVersion: "https://some.places/LATEST", }; Object.assign(ops.config, newProps); const doc = await makeRSDoc(ops); @@ -1788,7 +1832,7 @@ describe("W3C — Headers", () => { expect(terms[1].textContent).toBe("Latest published version:"); expect(terms[1].nextElementSibling.localName).toBe("dd"); expect(terms[1].nextElementSibling.textContent).toContain( - "http://LATEST" + "https://some.places/LATEST" ); const sotd = doc.getElementById("sotd"); expect(sotd.querySelectorAll("a[href='http://WG']")).toHaveSize(1);