Skip to content

Meta: use and prefer $closest from select-dom - #9325

Merged
fregante merged 9 commits into
mainfrom
copilot/update-select-dom-to-v10
May 2, 2026
Merged

fregante merged 9 commits into
mainfrom
copilot/update-select-dom-to-v10

Conversation

Copilot AI commented May 1, 2026 •

Copy link
Copy Markdown
Contributor

Upgrades select-dom to v10 and migrates all .closest() and .querySelector() calls to the new $closest/$closestOptional/$() API.

Rules:

  • element.closest(sel)! → $closest(sel, element)
  • element.closest(sel) / ?.closest() → $closestOptional(sel, element)
  • element.querySelector(sel)! → $(sel, element)

ESLint rule (eslint-rules/select-dom.js)

  • Added auto-fix handler for element.closest(sel) — detects TSNonNullExpression parent to pick $closest vs $closestOptional

ESLint config (eslint.config.js)

  • Added $closest and $closestOptional to the array-with-comments and single-element-array selectors
  • Removed [callee.property.name=closest] (no longer needed)
  • New lint rule: TSNonNullExpression > CallExpression > [name=$closest] — flags unnecessary ! since $closest already throws

Source migration (~70 files)

  • All .closest() calls replaced via eslint --fix
  • Remaining .querySelector() calls on $closest(...) results replaced with $() in action-pr-link, comments-time-machine-links, quick-file-edit, release-download-count, restore-file, status-subscription, options/feature-list
  • select-dom imports updated in every affected file
  • cross-deleted-pr-branches: added explicit !lastBranchAction guard before $closest call to avoid throwing when the element is absent
  • dom-formatters: removed now-unnecessary String() wrapper — $closestOptional accepts readonly string[] directly in v10
  • one-click-review-submission: inlined legacyActionsRow intermediate variable to a single line
  • prevent-link-loss: wrapped multi-selector array onto multiple lines for readability
  • actionable-pr-view-file: merged with main's refactor (new handleMenuOpening/isDeletedFile/getFilePath), updated remaining .closest() calls to $closest; import expanded to multi-line by formatter
  • batch-mark-files-as-viewed: merged with main's handleClick routing structure, updated all three .closest(fileSelector)! calls (remember, batchToggle, onAltClick) to $closest

Test fix (test/setup-file.js)

  • Added Element to the linkedom globals so $closestOptional's instanceof Element check works correctly in the Vitest environment

Test URLs

Screenshot

@fregante fregante changed the title Update select-dom to v10, replace .closest() with $closest/$closestOptional Meta: use and prefer $closest from select-dom May 1, 2026

@fregante fregante 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.

In some comments I mentioned using $(). I'm referring to replacing querySelector

Comment thread source/features/action-pr-link.tsx Outdated
Comment thread source/features/comments-time-machine-links.tsx Outdated
Comment thread source/features/comments-time-machine-links.tsx Outdated
Comment thread source/features/comments-time-machine-links.tsx Outdated
Comment thread source/features/cross-deleted-pr-branches.tsx Outdated
Comment thread source/features/release-download-count.tsx Outdated
Comment thread source/features/restore-file.tsx Outdated
Comment thread source/features/status-subscription.tsx Outdated
Comment thread source/github-helpers/dom-formatters.tsx Outdated
Comment thread source/options/feature-list.tsx Outdated
…remove String() wrapper

Agent-Logs-Url: https://github.com/refined-github/refined-github/sessions/f5656b6b-dc1b-4934-a413-dd87e3c67879

Co-authored-by: fregante <1402241+fregante@users.noreply.github.com>
Copilot AI requested a review from fregante May 1, 2026 10:37
Comment thread source/features/one-click-review-submission.tsx Outdated
Comment thread source/features/prevent-link-loss.tsx Outdated
const fileLink = fileIcon
.closest('.react-directory-filename-column')!
.querySelector('a.Link--primary')!;
const fileLink = $('a.Link--primary', $closest('.react-directory-filename-column', fileIcon));

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.

Unfortunate readability downgrade, but now we get better errors 🥲

Copilot AI requested a review from fregante May 1, 2026 10:43
@fregante
fregante marked this pull request as ready for review May 1, 2026 10:49
@fregante

fregante commented May 1, 2026

Copy link
Copy Markdown
Member

@copilot Vitest is failing

…ional instanceof check

Agent-Logs-Url: https://github.com/refined-github/refined-github/sessions/00b45907-aff2-4d0b-92ab-e05740b7736a

Co-authored-by: fregante <1402241+fregante@users.noreply.github.com>

Copilot AI commented May 1, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Vitest is failing

Fixed in 2f04abb. select-dom v10's $closestOptional does baseElement instanceof Element, but the test environment (linkedom) doesn't set Element as a global. Added 'Element' to the globals list in test/setup-file.js — all 5 tests in shorten-link.test.ts now pass.

@fregante fregante 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 might be biased but I think this is fantastic. Virtually every .closest() call we had was followed by !, so this addresses a real issue.

There are 3/4 instances of reduces readability like:

event
  .delegateTarget
  .closest('div')
  .querySelector('a')

becoming:

$('a', $closest('div', event.delegateTarget))

but we could either accept it or revert it (in the future, if we think it's bad and not just "a bad change")

We could also wrap it this way to retain some readability, but it only works if the selectors are long

$(
  'a.Link--primary',
  $closest(
    '.react-directory-filename-column',
    event.delegateTarget
  ),
)

@fregante fregante added the meta Related to Refined GitHub itself label May 1, 2026
@SunsetTechuila

SunsetTechuila commented May 1, 2026 •

Copy link
Copy Markdown
Contributor

$ could return an extended instance of Element with the $closest method: $('a').$closest('div')

@fregante

fregante commented May 1, 2026

Copy link
Copy Markdown
Member

$ could return an extended instance of Element with the $closest method: $('a').$closest('div')

I don't want to reinvent jQuery. I've gone back and forth on this kind of magic and I've settled on simple independent functions. See also:

@fregante

fregante commented May 1, 2026

Copy link
Copy Markdown
Member

See also my other attempts at similar magic:

@fregante

fregante commented May 1, 2026

Copy link
Copy Markdown
Member

I'll merge this after the release

@fregante
fregante marked this pull request as draft May 1, 2026 12:23
@fregante
fregante marked this pull request as ready for review May 1, 2026 16:30
…-dom-to-v10

# Conflicts:
#	source/features/actionable-pr-view-file.tsx
#	source/features/batch-mark-files-as-viewed.tsx

Co-authored-by: fregante <1402241+fregante@users.noreply.github.com>

This comment was marked as resolved.

Copilot AI requested a review from fregante May 1, 2026 16:36

@fregante fregante 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.

Will merge after 26.5.1

@fregante

fregante commented May 1, 2026

Copy link
Copy Markdown
Member

@copilot run "npm run fix"

Copilot AI commented May 1, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run "npm run fix"

Done in b4c07ce. The only change was a formatting fix in actionable-pr-view-file.tsx — the single-line select-dom import was expanded to multi-line. The vitest failures reported by the script are pre-existing (selectors + event-listener-loop tests failing due to GitHub UI changes), not related to this PR.

Copilot AI requested a review from fregante May 1, 2026 21:11
@fregante
fregante merged commit d14d4eb into main May 2, 2026
10 checks passed
@fregante
fregante deleted the copilot/update-select-dom-to-v10 branch May 2, 2026 11:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

meta Related to Refined GitHub itself

Development

Successfully merging this pull request may close these issues.

3 participants