Skip to content

[3.0] Theme split (wave 1, part 4) — Replace the jQuery At.js and Caret.js plugins - #9335

Merged
live627 merged 5 commits into
SimpleMachines:release-3.0from
albertlast:3.0/theme-mentions
Aug 2, 2026
Merged

[3.0] Theme split (wave 1, part 4) — Replace the jQuery At.js and Caret.js plugins#9335
live627 merged 5 commits into
SimpleMachines:release-3.0from
albertlast:3.0/theme-mentions

Conversation

@albertlast

@albertlast albertlast commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Wave 1, part 4 of breaking up #7933. No theme templates touched.

What changes

Mentions were the last thing pulling jquery.atwho.min.js and jquery.caret.min.js in. Both are replaced with vanilla ports that keep the same API — atwho(element, config) and caret(element, …) — and mentions.js is rewritten to match: fetch() instead of $.ajax(), DOMParser instead of jQuery's XML handling, Array.prototype.some instead of the for (i in fails) loop that leaked a global.

The At.js credit stays, since these are ports of it rather than a replacement.

Binding changes too

mentions.js used to bind on document ready by hunting for .sceditor-container:

$('.sceditor-container').find('textarea').atwho(atwhoConfig);
var iframe = $('.sceditor-container').find('iframe')[0];

which meant guessing when SCEditor had finished setting itself up. It is now registered as an SCEditor plugin and attaches on signalReady, to both the source textarea and the WYSIWYG iframe body. Display and Post add mentions to the editor's plugins option, which Editor::setSCEditorOptions() already supports. The plain-textarea case, for when SCEditor is not loaded at all, is handled separately.

atwho.css is now loaded explicitly rather than relying on the rules living in index.css.

One fix on top of #7933

The ported render() loops to the configured limit rather than to the number of results:

for (let i = 0; i < limit; i++) {
	let item = items[i];
	item["atwho-at"] = this.context.at;   // TypeError when i >= items.length

limit is 10, so any search matching fewer than ten members threw on the first missing entry — and it threw before show(), which is the last line of render(). The result was a dropdown that got populated and highlighted but was never displayed, so mentions looked completely dead for any search narrow enough to be useful. Bounded by Math.min(limit, items.length).

Testing

With mentions enabled, on both the full post page and the quick reply:

  • Typing @ad shows the dropdown at the caret (display: block, positioned, not at 0,0) with admin listed.
  • Pressing Enter inserts @admin and closes the dropdown.
  • Works in the source-mode textarea and in the WYSIWYG iframe body.
  • atwhoConfig.callbacks.remoteFilter('ad', …) returns [{name: "admin"}], confirming the rewritten fetch and XML parsing.
  • jQuery.fn.atwho is undefined; atwho and caret are globals.

Unrelated and pre-existing: the post page logs Uncaught ReferenceError: oEditorHandle_message is not defined on release-3.0 too. Not touched here.

🤖 Generated with Claude Code

@albertlast albertlast mentioned this pull request Aug 1, 2026
@albertlast albertlast changed the title [3.0] Theme split 3/24 — Replace the jQuery At.js and Caret.js plugins [3.0] Theme split (wave 1, part 4) — Replace the jQuery At.js and Caret.js plugins Aug 1, 2026
@jdarwood007 jdarwood007 added this to the 3.0 Alpha 5 milestone Aug 1, 2026
Comment thread Themes/default/scripts/mentions.js Outdated
albertlast added a commit to albertlast/SMF2.1 that referenced this pull request Aug 2, 2026
Review feedback on SimpleMachines#9335: the rewritten remoteFilter hand-rolled the
fetch, the X-SMF-AJAX header, the credentials handling, the ok check
and the DOMParser step. smc_Request.fetchXML() (added in SimpleMachines#8884) already
does all five, so call that instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
albertlast and others added 4 commits August 2, 2026 11:41
…et.js plugins

Mentions were the last thing pulling jquery.atwho.min.js and jquery.caret.min.js
in, on the post and topic display pages. Replace both with vanilla ports that
keep the same API, and rewrite mentions.js to match: fetch() instead of
$.ajax(), DOMParser instead of jQuery's XML handling.

Binding also changes. mentions.js used to attach on document ready by hunting
for .sceditor-container, which meant guessing when the editor had finished
setting itself up. It is now an SCEditor plugin, so it attaches on signalReady
to both the source textarea and the WYSIWYG iframe body, and the plain
textarea case is handled separately for when SCEditor is not present at all.

The stylesheet the plugin needs is now loaded explicitly rather than relying
on the rules being in index.css.

Wave 1, part 4 of breaking up SimpleMachines#7933.

Co-Authored-By: John Rayes <live627@gmail.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The render loop ran to the configured limit rather than to the number of
results, so a search matching fewer members than the limit threw on the
first missing entry. That happened before show(), leaving the dropdown
populated but never displayed.
Review feedback on SimpleMachines#9337: multi-line comments should be the
/* * ... */ variant rather than stacked // lines.
Review feedback on SimpleMachines#9335: the rewritten remoteFilter hand-rolled the
fetch, the X-SMF-AJAX header, the credentials handling, the ok check
and the DOMParser step. smc_Request.fetchXML() (added in SimpleMachines#8884) already
does all five, so call that instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment thread Themes/default/css/atwho.css Outdated
@@ -0,0 +1,47 @@
.atwho-view {
background: var(--mentions-bg);

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.

Do we deliberately use non-existent CSS variables here in anticipation of future changes which will probably define them in variables.css?

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.

Deliberately, yes — they are the tokens variables.css brings in a later part of the split. But you were right to ask, because the intermediate state was not harmless, and I had not checked it properly.

An unresolvable var() with no fallback is invalid at computed-value time. That is not the same as the declaration being dropped: the property falls back to its initial value, not to the rule it was overriding. So background: var(--mentions-bg) in atwho.css beat background: #fff from the /* Mentions */ block in index.css and then resolved to transparent. Same for the border, radius, shadow, min-width and the .cur highlight.

Measured on the dropdown as it renders today:

background   rgba(0, 0, 0, 0)     <- index.css said #fff
border       none 0px             <- index.css said 1px solid #ddd
box-shadow   none
min-width    0px
.cur         rgba(0, 0, 0, 0)     <- index.css said #3366ff

In the browser that is bare text floating over the editor: no panel, no border, and the selected entry indistinguishable from the rest.

Fixed in 789757a by giving every reference the value variables.css is going to supply as its fallback:

background: var(--mentions-bg, #fff);
border-color: var(--mentions-border-color, hsl(0, 0%, 85%));

That way the panel is correct now and picks up the token the moment one exists, with nothing here to revisit when variables.css lands. It renders as a white panel with a light border, a 1px radius, the soft shadow and a blue highlight on the current entry, which is what both variables.css and the block it replaces describe.

Three things worth passing on while I was in there:

  • --mentions-item-border-radius and --mentions-item-box-shadow have no counterpart in variables.css either, so those two declarations were dead in the finished theme as well. Removed rather than given an invented value.
  • variables.css has --mentions-item-font-weight: 50px and --mentions-item-font-weight_current: 50px. A font-weight in px is invalid, so those resolve to normal even once the tokens exist. The fallbacks here say normal to match what actually renders, but the token is worth correcting when that file arrives.
  • The /* Mentions */ block in index.css is gone. atwho.css now covers everything it did, and the rules it does not cover style <strong> and <small>, which the replacement never emits — matches are marked up with <b>.

atwho.css referenced seventeen --mentions-* custom properties that nothing
defines yet; they arrive with variables.css in a later part of the split.

An unresolvable var() with no fallback is invalid at computed-value time,
so each property fell back to its initial value rather than to the rule it
was overriding in index.css. The dropdown therefore lost its background,
border, radius, shadow, min-width and the highlight on the selected entry,
and rendered as bare text over the editor.

Each reference now carries the value variables.css is going to supply, so
the panel looks the way it should today and picks up the token as soon as
there is one, with nothing to remove here when that happens.

Two of the references have no counterpart in variables.css at all,
--mentions-item-border-radius and --mentions-item-box-shadow, so those
declarations are gone rather than given an invented value.

The old /* Mentions */ block in index.css goes with them. atwho.css now
covers everything it did, and the parts it does not cover style <strong>
and <small> elements that the replacement no longer emits - matches are
marked up with <b>.

Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
@live627
live627 merged commit 61e3aaa into SimpleMachines:release-3.0 Aug 2, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants