Skip to content

Bug 2085052 - For @mentions in comments, allow autocompletion when typing @ like github does - #2810

Open
dklawren wants to merge 6 commits into
mozilla:masterfrom
dklawren:2085052
Open

dklawren wants to merge 6 commits into
mozilla:masterfrom
dklawren:2085052

Conversation

@dklawren

@dklawren dklawren commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator

Typing @ and two or more characters in a comment box on an existing bug lists accounts whose nickname matches; picking one inserts "@nick ". Reuses /rest/user/suggest (an @-prefixed match is nickname-only). Lives in the Needinfo extension and is loaded only where a mention takes effect (mentions enabled, logged in, editbugs on the product).

…ping @ like github does

Typing @ and two or more characters in a comment box on an existing bug lists accounts whose nickname matches; picking one
  inserts "@nick ". Reuses /rest/user/suggest (an @-prefixed match is nickname-only). Lives in the Needinfo extension and is loaded only where a mention takes effect (mentions enabled, logged in, editbugs on the product).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Stale autocomplete suggestions and missing caret validation can insert the wrong mention or delete intervening text when a suggestion is accepted.

4 open issues
What changed in this PR

Adds nickname-based @mention autocomplete to comment editors through the Needinfo extension, reusing /rest/user/suggest.

Changes:

  • Adds debounced suggestions, keyboard selection, and nickname insertion.
  • Loads autocomplete only for eligible logged-in users commenting on existing bugs.
  • Adds API tests for nickname matching, disabled accounts, and authentication.
File Description
extensions/​Needinfo/​web/​styles/​mention-autocomplete.css Styles the suggestion popup using shared autocomplete rules.
extensions/​Needinfo/​web/​js/​mention-autocomplete.js Implements mention detection, suggestions, positioning, and selection.
extensions/​Needinfo/​template/​en/​default/​hook/​global/​header-start.html.tmpl Conditionally loads autocomplete assets and defines the accessible label.
extensions/​Needinfo/​t/​bmo/​mention-suggest.t Tests the user-suggestion API behavior needed by autocomplete.

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Autocomplete can suppress valid mentions because it scans fenced-block backticks and can swallow Enter or Tab after selection changes invalidate the active mention.

2 open issues
4 resolved since last review

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Nickname uniqueness is inferred from a response capped at 25 accounts, so an ambiguous @mention can be offered even though saving it notifies neither account.

No open issues 🎉

1 previously missed issue

In code that hasn't changed since last review

Medium severity Autocomplete can offer nicknames that are ambiguous across all accounts

extensions/​Needinfo/​web/​js/​mention-autocomplete.js:296

user/suggest limits its response to 25 accounts (Bugzilla/API/V1/UserObject.pm::suggest), so counting only those results cannot establish that a nickname is unique. If one enabled account named alice is returned but another falls outside that limit, this offers @alice even though _users_for_mentions rejects it as ambiguous and saving notifies neither account. Check uniqueness against all enabled accounts server-side, or return server-computed ambiguity information with each suggestion.

2 resolved since last review

Review effort: Balanced

@dklawren

dklawren commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator Author

Nickname uniqueness is inferred from a response capped at 25 accounts, so an ambiguous @mention can be offered even though saving it notifies neither account.

Production has no duplicate nicknames today. I checked with the column's own collation (utf8mb4_unicode_520_ci), counting disabled accounts too. _generate_nickname refuses any nickname another account already holds, so the 25-account cap only matters if a duplicate exists, and none do. A UNIQUE index to enforce this in the schema will be handled in bug 2089200. Leaving this as is.

@dklawren
dklawren requested review from Xzzz and cgsheeh November 4, 2026 21:50

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

Very nice, looking forward to using this! 😉

counts.set(nick.toLowerCase(), (counts.get(nick.toLowerCase()) ?? 0) + 1);
});

return users.filter(

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.

On a restricted bug, will this suggest users who can't see it? _mentioned_users silently drops them on save, so the commenter could think they pinged someone when they didn't. Would it be worth passing the bug id so the server can filter with can_see_bug, or is the comment preview considered enough of a safety net here?


// A code span opens and closes on backtick runs of the same length within a paragraph.
const before = masked.slice(0, position);
const paragraphStart = Math.max(0, before.search(/\n[ \t]*\n(?![\s\S]*\n[ \t]*\n)/));

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.

Does the (?![\s\S]*\n[ \t]*\n) lookahead rescan to the end of before for every blank line, making this quadratic on long comments with many paragraphs (e.g. a pasted log)? Since it runs on every keystroke while typing a mention, would something like [...before.matchAll(/\n[ \t]*\n/g)].at(-1)?.index ?? 0 be simpler and linear?

* not follow a word character, `@`, `.`, `/` or `-`, so email addresses and paths don't trigger
* it, and the nickname uses the same character set.
*/
static TRIGGER = /(?<![\p{Alphabetic}\p{M}\p{Nd}\p{Pc}@./-])@([\p{Alphabetic}\p{Nd}|._-]*)$/u;

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.

These regexes (and isIgnored) have to stay in sync with _extract_mentions by hand. Could we add a matching note in _extract_mentions pointing back at this file, so someone changing the Perl side knows to update the JS too?

# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.

# The @mention autocomplete (extensions/Needinfo/web/js/mention-autocomplete.js)

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.

This test covers the existing /rest/user/suggest behaviour, but none of the new client-side logic (trigger regex, quote/code-span/fence handling, self and duplicate-nick filtering). Is there a reasonable way to cover that, e.g. a Selenium test in qa/t, or is manual testing the plan for now?

@Xzzz Xzzz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, thanks! I cant wait to see it in action too :)

dklawren and others added 2 commits November 6, 2026 17:35
- Only suggest accounts that can see the bug: /rest/user/suggest takes an
  optional bug_id and leaves out users failing can_see_bug, since
  _mentioned_users drops them on save. The caller must be able to see the
  bug too. Bugs in no groups skip the per-user check.
- Find the paragraph start in linear time instead of rescanning the text
  for every blank line.
- Point _extract_mentions at the JS rules that mirror it.
- Add a Selenium test for the client-side logic: filtering, insertion and
  the contexts where mentions are ignored.

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