Skip to content

feat: render inherited API class members from the parent doc - #1214

Draft
claude[bot] wants to merge 1 commit into
mainfrom
inherited-api-members
Draft

claude[bot] wants to merge 1 commit into
mainfrom
inherited-api-members

Conversation

@claude

@claude claude Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Requested by Will Anderson · Slack thread

Description of Change

Before: A class page only shows what its own markdown file documents. BrowserWindow looks complete solely because electron/electron duplicates almost all of BaseWindow's sections into browser-window.md (and still misses contentView, getContentView, setContentView, the persisted-state-restored event and the static clearPersistedState). WebContentsView and ImageView say they extend View but show none of View's events, methods or properties.

After: Pages render inherited members from the parent doc at build time. Each injected member keeps its heading, badges, history block and body, followed by an Inherited from BaseWindow note linking to the parent page. BrowserWindow's anchors are unchanged (only the five members it never documented are added, and there are no -1 slug suffixes). WebContentsView and ImageView gain View's bounds-changed event, children property and nine instance methods, with the receiver rewritten where it differs (view.image. on ImageView, including same-page anchors in the bodies).

How: A new remark plugin, src/transformers/api-inherited-members.ts, registered first in beforeDefaultRemarkPlugins, parses the ## Class: Child extends \Parent` heading, loads the sibling parent doc (BaseWindowbase-window.md, walking the whole extendschain with a cycle guard;EventTargethas no doc and is skipped), and appends the members the child does not already declare to the matching depth-3 section (creating missing sections in canonical order) — so electron/electron can later drop the duplicatedBrowserWindowsections without a visible change on the site. Injected headings carry the classapi-inherited-member. Tests use the Node test runner (yarn test`, added to the PR workflow).

Verification

  • node --test "src/**/*.spec.ts" — 18/18 pass, over the real docs/latest/api files plus synthetic fixtures: BrowserWindow gains exactly parent − child per section (today: Event: 'persisted-state-restored', BrowserWindow.clearPersistedState(name), win.contentView, win.setContentView(view), win.getContentView()), keeps every existing heading with no duplicates; WebContentsView gains every View member appended after its own; ImageView receiver/anchor rewrite; WebSocket, a class without extends, and a doc outside api/ are untouched; running twice is idempotent; grandparent chain, nearest-ancestor-wins, section ordering, history-block adjacency, link-definition carry-over and cycle guard.
  • yarn lint components: tsc --noEmit, oxfmt --check ., oxlint docusaurus.config.ts src scripts, markdownlint-cli2 — all clean.
  • yarn build (docusaurus build --locale en) and inspected the generated HTML:
    • build/docs/latest/api/browser-window/index.html: 215 h3/h4 headings, 0 duplicate ids, 0 ids with a numeric suffix; the five injected h4s have ids event-persisted-state-restored, browserwindowclearpersistedstatename, wincontentview, winsetcontentviewview, wingetcontentview, TOC entries (contentView, setContentView, …) and the note <em>Inherited from <a href=/docs/latest/api/base-window><code>BaseWindow</code></a></em>; the > [!NOTE] inside persisted-state-restored renders as an admonition.
    • build/docs/latest/api/web-contents-view/index.html: sections now new WebContentsView, Instance Events (bounds-changed), Instance Properties (webContents, then inherited children with its Readonly badge), Instance Methods (addChildViewgetVisible); 11 injected headings, 11 notes, TOC entries for all, no duplicate ids.
    • build/docs/latest/api/image-view/index.html: same members as image.*; the body link to view.getBounds() now points to #imagegetbounds; ImageView's own setImage history table still renders.
    • Caveat: in this sandbox electronjs.org is unreachable, so the releases plugin's headers/index.json fetch was stubbed locally (not committed) and the /fiddle/ page failed to render for the same network reason; all docs pages were generated. None of the members injected on these pages has a history block or platform badge in the source, so that adjacency is covered by the synthetic test rather than the build.

Open questions for reviewers

  • Full-section injection (what this does) vs a compact "Inherited from View: addChildView, setBounds, …" link list per section?
  • Algolia DocSearch record cap: BrowserWindow's record count is unchanged today; should injected members be excluded from the crawler via the api-inherited-member class, like api-options-class.ts does for option lists?
  • Should electron/electron deduplicate browser-window.md afterwards (render-time inheritance was proposed by nornagon in feat: replace BrowserView with WebContentsView electron#35658)? With this plugin that removal would be invisible on the site, but docs-parser/electron.d.ts consumers would need their own handling.
  • Parent docs are parsed with plain GFM (not MDX) and cached for the process lifetime (a yarn start needs a restart to pick up parent edits). Translated locales only inherit when the translated parent file exists.

Checklist

🤖 Generated with Claude Code

https://claude.ai/code/session_014dqqJFHsxFxatj9ZozxoT4


Generated by Claude Code

Add a remark plugin (`src/transformers/api-inherited-members.ts`) that
reads the `## Class: Child extends `Parent`` heading of an API doc,
loads the sibling parent doc (`BaseWindow` -> `base-window.md`, walking
the whole `extends` chain) and injects every member the child does not
already declare into the matching section (Static Methods, Static
Properties, Instance Events, Instance Properties, Instance Methods),
with an "Inherited from" note linking to the parent page. Receivers and
class names in injected headings are rewritten for the child.

Members the child already documents are never injected, so pages that
duplicate their parent today (BrowserWindow) keep every existing anchor
and only gain the handful of BaseWindow members they never documented.
WebContentsView and ImageView gain View's members.

The plugin runs first in `beforeDefaultRemarkPlugins` so injected
headings get ids and TOC entries and injected bodies go through the
admonition, label, history and link transforms. Tests use the Node test
runner (`yarn test`, also run in CI).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014dqqJFHsxFxatj9ZozxoT4
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying electron-website with  Cloudflare Pages  Cloudflare Pages

Latest commit: 601669a
Status: ✅  Deploy successful!
Preview URL: https://66ae85ec.electron-website.pages.dev
Branch Preview URL: https://inherited-api-members.electron-website.pages.dev

View logs

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.

1 participant