Skip to content

feat: new CG specification profiles - #5482

Draft
deniak wants to merge 16 commits into
mainfrom
feat/cg-redesign-identity-assets
Draft

deniak wants to merge 16 commits into
mainfrom
feat/cg-redesign-identity-assets

Conversation

@deniak

@deniak deniak commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor
  • Introducing 2 new profiles CG-LIVING and CG-SNAPSHOT following the upcoming updates with the CG spec lifecycle. These profiles use different headers (see mockups) and rely on assets and metadata. The existing profiles CG-DRAFT and CG-FINAL remain untouched.
  • The new profiles come with 2 configuration options cgMaturity (draft, transferred or unmaintained) and transferredTo (only applies if cgMaturity = transferred)

Description of the new processing files:

  • src/w3c/templates/cg-headers.js builds the redesign headers for the 4 variants (draft, transferred, unmaintained and snapshot) and adds the different containers (with a data-cg-region attribute) that cg-metadata fills when the spec loads
  • src/w3c/cg-sections.js adds the "Get involved" and "Usage guidance" sections
  • src/w3c/cg-spec.js emits three new tags that cg-metadata relies on to fetch the appropriate metadata
  • src/w3c/templates/cg-sotd.js reduces the SotD to what the editors wrote (we do not have required paragraphs for the new profiles)

Some URLs are still subject to change so it's not ready to be merged.

deniak added 9 commits October 6, 2026 09:38
- CG-LIVING
- CG-SNAPSHOT

Include the cgbgStatus and new CG assets (base.css, cg-spec.css, dark.css, cg-fixup.js and cg-metadata.js) for these new profiles.
Introduce <meta> tags required by the new profiles.
Run some validation.
…ata + introduce new boilerplates depending on the type of CG specs
@deniak
deniak force-pushed the feat/cg-redesign-identity-assets branch from 8585b0b to a938dcf Compare October 6, 2026 05:38
@deniak
deniak requested a review from marcoscaceres October 6, 2026 07:02
@marcoscaceres
marcoscaceres requested review from sidvishnoi and a balanced review from Copilot October 6, 2026 09:36
@marcoscaceres

Copy link
Copy Markdown
Contributor

@sidvishnoi, do you mind reviewing this first if you have cycles. If you're busy, happy to dive in.

Comment thread src/w3c/templates/cg-headers.js Outdated
const COMMUNITY = "https://www.w3.org/community/";
const INCUBATION = "https://incubation.w3.org/";

const chevron = () =>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only called once, so we can probably just inline it. Does this need any ARIA stuff?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in 4a36ea9

Comment thread examples/cg-living.html
@@ -0,0 +1,52 @@
<!doctype html>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure we should add this example at all to be honest.

Comment thread src/w3c/templates/cg-headers.js Outdated
* @param {string} noScriptText
* @param {"div" | "li"} as
*/
export function region(name, noScriptText, as = "div") {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe more clear:

Suggested change
export function region(name, noScriptText, as = "div") {
export function region(name, noScriptText, elementName = "div") {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in a885e77

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Type-qualified and joint group configurations currently generate incorrect links and header markup.

Review effort: Balanced
Findings: 4 Medium severity · 2 Low severity

Open (6)
What changed in this PR

Adds redesigned CG-LIVING and CG-SNAPSHOT Community Group profiles with dedicated headers, metadata, assets, and supporting sections.

Changes:

  • Adds CG profile configuration, validation, templates, and pipeline modules.
  • Integrates external CG assets and metadata regions.
  • Adds comprehensive integration and unit coverage plus an example document.
File Description
tests/​unit/​w3c/​cg-headers-spec.js Tests snapshot-index URL generation.
tests/​spec/​w3c/​cg-spec.js Covers profiles, metadata, assets, and variants.
src/​w3c/​templates/​cg-sotd.js Adds the redesigned minimal SotD.
src/​w3c/​templates/​cg-headers.js Builds redesigned CG headers.
src/​w3c/​style.js Selects CG-specific assets.
src/​w3c/​headers.js Registers statuses and templates.
src/​w3c/​defaults.js Validates new configuration options.
src/​w3c/​cg-spec.js Emits CG metadata identity.
src/​w3c/​cg-sections.js Adds involvement and usage sections.
src/​w3c/​cg-assets.js Loads and restores CG assets.
src/​type-helper.d.ts Types the new configuration.
profiles/​w3c.js Registers the new modules.
examples/​cg-living.html Demonstrates the living profile.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/w3c/cg-sections.js Outdated
Comment thread src/w3c/templates/cg-headers.js Outdated
// TODO:
// - `conf.group` is an array for joint publications
// - `conf.group` is an id
const group = typeof conf.group === "string" ? conf.group.split("/")[0] : "";

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in c5d3368

Comment on lines +272 to +273
the Contributors to the ${titleNodes} Specification, published by the
<a href="${conf.wgURI}">${conf.wg}</a> under the ${agreement}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this stage, my expectation is that CG specs will be produced by a single CG

Comment thread tests/unit/w3c/cg-headers-spec.js
Comment thread src/w3c/defaults.js Outdated
Comment on lines +179 to +181
The text of this specification and the status information support
for this specification are expected to change in place at this
address.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ianbjacobs See this copilot suggestion on the text we expect at the top of the specs.

@marcoscaceres marcoscaceres left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some initial feedback...

* @param {"div" | "li"} elementName
*/
export function region(name, noScriptText, elementName = "div") {
const message = document.createElement("p");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this can probably just be a hyperHTML template. Easier to read.

const group =
typeof conf.group === "string" ? conf.group.split("/", 2).at(-1) : "";
if (!group || !conf.shortName) return "";
const base = `${INCUBATION}groups/${encodeURIComponent(group)}/specs/`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe safer/cleaner to use new URL(path , INCUBATION) here and have it return the .href?

if (conf.specStatus !== "CG-SNAPSHOT") return "";
if (!conf.shortName || !conf.publishDate) return "";
const dated = `${conf.shortName}-${concatDate(conf.publishDate)}`;
return `${INCUBATION}specs/${encodeURIComponent(dated)}/`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above... use new URL() for URL parsing.

</li>
</ul>
</div>`;
default:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default: should probably be a RespecError to catch unsupported/unexpected cases.

* @param {string} noScriptText
* @param {"div" | "li"} elementName
*/
export function region(name, noScriptText, elementName = "div") {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: createRegion() maybe?

Comment thread src/w3c/cg-assets.js
*/
function createScript(path) {
const src = cgAssetUrl(path);
const script = path.endsWith("cg-metadata.js")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above... this seems somewhat fragile... something like createScript(path, options = {defer: false, async: false}) might be better

Comment thread src/w3c/cg-sections.js
// is no one page to send a reader to for a joint publication.
const joinURL =
typeof conf.group === "string"
? `${COMMUNITY}${conf.group.split("/", 2).at(-1)}/join`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above... might be better to use new URL to construct these URLs.

Comment thread src/w3c/cg-sections.js
"usage-guidance",
"The usage guidance for this specification is loaded from the status metadata, which needs JavaScript."
)}
${DISCLAIMER}`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DISCLAIMER can probably just be inlined.

const message = document.createElement("p");
message.className = "cg-metadata-unavailable";
message.textContent = noScriptText;
const fallback = document.createElement("noscript");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure any other feature uses noscript... given fixup.js will presumably be loaded, I wonder things will break regardless if JS is disabled?

Comment thread src/w3c/defaults.js
}
}

const CG_MATURITIES = ["draft", "transferred", "unmaintained"];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused about "transferred"... if the document has been transferred, won't it just be a WD or ED? or is the expectation that transferred things would still be maintained? My experience has been that once transferred, they just transition to an appropriate W3C status.

@sidvishnoi sidvishnoi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do some more passes after trying it locally..

Comment on lines +92 to +95
function noticeBox(conf) {
switch (cgVariant(conf)) {
case "snapshot":
return html`<div class="box box--information">

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the templates here can be moved into individual functions, so it's cleaner. e.g. noticeBoxSnapshot(conf), noticeBoxTransferred(conf)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants