Skip to content

Switch MDN annos to ship as just a code string, and get hydrated on load. #3319 - #3324

Open
tabatkins wants to merge 4 commits into
mainfrom
mdn
Open

tabatkins wants to merge 4 commits into
mainfrom
mdn

Conversation

@tabatkins

Copy link
Copy Markdown
Collaborator

Regression: some features had a small description previously, but that seems to no longer be part of the code format.

@tabatkins tabatkins mentioned this pull request Sep 18, 2026
7 tasks done
Comment thread bikeshed/mdn/mdn-anno.js
// has ever understood has to keep working. Evolve the format by adding a branch in
// `hydrate`, never by redefining a version that has already shipped.

const MDN_URL = 'https://developer.mozilla.org/en-US/docs/Web/';

@zcorpan zcorpan Sep 24, 2026 •

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 file needs to be updated to include latest changes in whatwg/whatwg.org#506, see comments in whatwg/wattsi#170

// comes from CSS, keyed off the browser id in the row's class.
function browserRow(slot, cell) {
const { state, version, title } = readCell(cell, slot);
return element('span', { class: `${slot.id} ${state}` },

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.

bikeshed/mdn/mdn-anno.css is missing a rule for .unknown.

Comment thread bikeshed/mdn/mdnspeclinks.py Outdated
Comment thread bikeshed/mdn/mdnspeclinks.py Outdated
Comment on lines +163 to +164
# feature = slug "|" level "|" cells ["|" caniuse-feature "," caniuse-title]
code = cleanCodeText(feature["slug"]) + "|"

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 needs a change similar to whatwg/wattsi@efcb210 to fix the broken links issue.

Comment thread bikeshed/mdn/mdn-anno.js Outdated
Comment thread bikeshed/mdn/mdnspeclinks.py Outdated
Comment thread bikeshed/mdn/mdnspeclinks.py Outdated
Comment thread bikeshed/mdn/mdnspeclinks.py Outdated
Comment on lines +266 to +271
if "prefix" in support or "alternative_name" in support:
caveat = "$"
elif "partial_implementation" in support:
caveat = "*"
elif "flags" in support:
caveat = "^"

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 think flag > prefix > partial is better. Some features have 2 applied (partial + prefix, flag + prefix or flag + partial).

Suggested change
if "prefix" in support or "alternative_name" in support:
caveat = "$"
elif "partial_implementation" in support:
caveat = "*"
elif "flags" in support:
caveat = "^"
if "flags" in support:
caveat = "^"
elif "prefix" in support or "alternative_name" in support:
caveat = "$"
elif "partial_implementation" in support:
caveat = "*"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I'm fine with that order. Wrt your last sentence, do you mean that a cell can have multiple caveats? Or just that a support entry can have multiple caveat-causing things, and you prefer this particular order of processing?

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.

The latter.

Comment on lines +157 to +159
def encodeFeatureData(features: list[MdnFeatureT]) -> str:
fullCode = "v1|" + ("~".join(codeFromFeature(x) for x in features))
return fullCode

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.

Distinct BCD features can share an MDN page and identical support data. This could deduplicate identical records. (whatwg/wattsi#170 now does.)

Suggested change
def encodeFeatureData(features: list[MdnFeatureT]) -> str:
fullCode = "v1|" + ("~".join(codeFromFeature(x) for x in features))
return fullCode
def encodeFeatureData(features: list[MdnFeatureT]) -> str:
# Deduplicate
codes = dict.fromkeys(codeFromFeature(x) for x in features)
return "v1|" + "~".join(codes)

Comment thread bikeshed/mdn/mdnspeclinks.py
Comment thread bikeshed/mdn/mdnspeclinks.py Outdated
@zcorpan

zcorpan commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Comment by Claude:

whatwg/wattsi#170 and whatwg/whatwg.org#506 now add an optional fifth field to v1, for when several records in a panel share an MDN article but not their support data, which a reader otherwise can't tell apart (whatwg/html#12987):

feature = article "|" level "|" cells ["|" caniuse ["|" label]]

A labelled record without caniuse data gets an empty caniuse field, so the script now checks if (caniuse) rather than caniuse !== undefined, and shows the label after the article link, e.g. Attributes/disabled (<textarea>). Syncing mdn-anno.js with whatwg/whatwg.org#506 picks both up, and a script without them just ignores the field.

On Bikeshed's data this would label 316 records in 51 panels, mostly WebGL methods, where each article has a WebGLRenderingContext and a WebGL2RenderingContext record with different support. Below is a version of encodeFeatureData (lines 157–159) that does it, and also covers the dedup suggested above. Only records that have a filename get labelled. The label is the element for html/elements/* or the file's name otherwise, then the file path if that doesn't tell them apart (at-rules/namespace vs selectors/namespace), then BCD's name, and nothing if none of those do. I checked it against all 294 data files: no group gets a repeated label, and stripping the labels gives exactly the deduped output.

Python
def encodeFeatureData(features: list[MdnFeatureT]) -> str:
    # Distinct BCD features can share an MDN page. Merge the ones that encode identically,
    # and where one article still has several records, label each with what it's for.
    records: dict[str, list[MdnFeatureT]] = {}
    for feature in features:
        records.setdefault(codeFromFeature(feature), []).append(feature)
    # Entries without a "filename" aren't from BCD itself, so there's nothing to label them with.
    fromBcd = {code: [f for f in fs if f.get("filename")] for code, fs in records.items()}
    groups: dict[str, list[str]] = {}
    for code, bcd in fromBcd.items():
        if bcd:
            groups.setdefault(code.split("|", 1)[0], []).append(code)
    labels: dict[str, str] = {}
    for codes in groups.values():
        if len(codes) > 1:
            labels |= distinctLabels(codes, fromBcd)
    return "v1|" + "~".join(
        code + ("|" if code.count("|") == 2 else "") + "|" + cleanCodeText(labels[code]) if code in labels else code
        for code in records
    )


def distinctLabels(codes: list[str], fromBcd: dict[str, list[MdnFeatureT]]) -> dict[str, str]:
    # Name the features the first way that tells every record apart: by element or file,
    # then by file path, then by BCD feature name. If none does, a label wouldn't help.
    for describe in (featureLabel, featurePath, lambda f: f.get("name", "")):
        labels = {code: ", ".join(dict.fromkeys(describe(f) for f in fromBcd[code])) for code in codes}
        if len(set(labels.values())) == len(labels):
            return labels
    return {}


def featureLabel(feature: MdnFeatureT) -> str:
    # The element for html/elements/*, otherwise the file's own name, e.g. the interface for api/*.
    filename = feature.get("filename", "")
    name = filename.rsplit("/", 1)[-1].removesuffix(".json")
    return f"<{name}>" if filename.startswith("html/elements/") else name


def featurePath(feature: MdnFeatureT) -> str:
    # e.g. "at-rules/namespace" rather than "selectors/namespace".
    return feature.get("filename", "").split("/", 1)[-1].removesuffix(".json")

Wattsi also warns about entries without a filename that shadow a BCD one, as they're probably stale in mdn-spec-links' .local/html.json (speced/mdn-spec-links#854). Maybe worth doing here too.

zcorpan added a commit to whatwg/whatwg.org that referenced this pull request Sep 25, 2026
Bikeshed uses 6px too as of speced/bikeshed#3324.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

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.

2 participants