Steps to reproduce
- Reload the chatbox page (fresh state, no prior interaction).
- Click the "Emotes" button. Panel opens with emote icons.
- Click any emote.
Expected
The emote tag (e.g. :)) is inserted into the message textarea at the
cursor position.
Actual
Nothing happens. The emote is not inserted. No error in the browser
console.
Workaround
Click into the message textarea first (give it focus / move the cursor),
then open the emote panel and click an emote. Emote inserts correctly.
After this first successful interaction, subsequent emote clicks work
normally — until the next page reload, when the bug returns.
Diagnosis
The emote panel HTML (returned by r_emote() in e107 core
core_functions.php) registers a click handler that calls
addtext(value, true):
$('.addEmote').click(function(){
val = $(this).attr('data-emote')
addtext(val, true);
return false;
});
addtext() inserts text at a previously-stored cursor position, which is
saved by storeCaret(). The textarea has three inline event handlers
that call storeCaret():
If the user has not clicked, typed, or selected text in the textarea
before clicking an emote, storeCaret() has never run, no cursor
position is stored, and addtext() has nowhere to insert the emote — so
the call silently does nothing.
This is a pre-existing bug in the plugin, not a regression from any
recent change. It surfaced during testing of the markup cleanup PR
(#N — the menu-surface markup cleanup), which is unrelated to the
JavaScript event flow.
Verified that:
- The click handler is correctly attached
($._data($('.addEmote')[0], 'events').click[0].handler shows the
r_emote() handler)
- The
addtext function is loaded globally
(typeof addtext returns "function")
- Emote
<a> elements have the addEmote class
($('.addEmote').length returns 28)
The chain works once storeCaret() has been called at least once.
Possible fixes
Several approaches, ordered from quickest to most thorough:
-
Initialize cursor position when emote panel opens. Add a JS hook
on the "Emotes" button click that calls storeCaret() on the
textarea (or focuses the textarea) before showing the panel. Smallest
change.
-
Make addtext() self-sufficient. Change addtext() (in e107
core) to fall back to "append at end" when no stored caret position
exists. This is a core fix and benefits all plugins using the same
pattern.
-
Replace the legacy storeCaret/addtext pair with modern textarea
APIs. setRangeText() and selectionStart/selectionEnd are
widely supported. This belongs in the planned JS extraction PR
(chatbox.js) rather than as a quick fix.
Recommended: defer the proper fix to the JS extraction PR, where the
inline onclick="storeCaret(this);" attributes are being removed
anyway. Until then, document the workaround.
Steps to reproduce
Expected
The emote tag (e.g.
:)) is inserted into the message textarea at thecursor position.
Actual
Nothing happens. The emote is not inserted. No error in the browser
console.
Workaround
Click into the message textarea first (give it focus / move the cursor),
then open the emote panel and click an emote. Emote inserts correctly.
After this first successful interaction, subsequent emote clicks work
normally — until the next page reload, when the bug returns.
Diagnosis
The emote panel HTML (returned by
r_emote()in e107 corecore_functions.php) registers a click handler that callsaddtext(value, true):addtext()inserts text at a previously-stored cursor position, which issaved by
storeCaret(). The textarea has three inline event handlersthat call
storeCaret():If the user has not clicked, typed, or selected text in the textarea
before clicking an emote,
storeCaret()has never run, no cursorposition is stored, and
addtext()has nowhere to insert the emote — sothe call silently does nothing.
This is a pre-existing bug in the plugin, not a regression from any
recent change. It surfaced during testing of the markup cleanup PR
(#N — the menu-surface markup cleanup), which is unrelated to the
JavaScript event flow.
Verified that:
(
$._data($('.addEmote')[0], 'events').click[0].handlershows ther_emote()handler)addtextfunction is loaded globally(
typeof addtextreturns"function")<a>elements have theaddEmoteclass(
$('.addEmote').lengthreturns 28)The chain works once
storeCaret()has been called at least once.Possible fixes
Several approaches, ordered from quickest to most thorough:
Initialize cursor position when emote panel opens. Add a JS hook
on the "Emotes" button click that calls
storeCaret()on thetextarea (or focuses the textarea) before showing the panel. Smallest
change.
Make
addtext()self-sufficient. Changeaddtext()(in e107core) to fall back to "append at end" when no stored caret position
exists. This is a core fix and benefits all plugins using the same
pattern.
Replace the legacy
storeCaret/addtextpair with modern textareaAPIs.
setRangeText()andselectionStart/selectionEndarewidely supported. This belongs in the planned JS extraction PR
(
chatbox.js) rather than as a quick fix.Recommended: defer the proper fix to the JS extraction PR, where the
inline
onclick="storeCaret(this);"attributes are being removedanyway. Until then, document the workaround.