chat: Allow `chatNewMessage` hook to control rendering
parent
2597b940f4
commit
f1f4ed7c58
|
@ -54,6 +54,8 @@
|
||||||
* The `chatNewMessage` client-side hook context has new properties:
|
* The `chatNewMessage` client-side hook context has new properties:
|
||||||
* `message`: Provides access to the raw message object so that plugins can
|
* `message`: Provides access to the raw message object so that plugins can
|
||||||
see the original unprocessed message text and any added metadata.
|
see the original unprocessed message text and any added metadata.
|
||||||
|
* `rendered`: Allows plugins to completely override how the message is
|
||||||
|
rendered in the UI.
|
||||||
|
|
||||||
# 1.8.14
|
# 1.8.14
|
||||||
|
|
||||||
|
|
|
@ -285,11 +285,11 @@ Called from: `src/static/js/chat.js`
|
||||||
|
|
||||||
This hook runs on the client side whenever a chat message is received from the
|
This hook runs on the client side whenever a chat message is received from the
|
||||||
server. It can be used to create different notifications for chat messages. Hook
|
server. It can be used to create different notifications for chat messages. Hook
|
||||||
functions can modify the `author`, `authorName`, `duration`, `sticky`, `text`,
|
functions can modify the `author`, `authorName`, `duration`, `rendered`,
|
||||||
and `timeStr` context properties to change how the message is processed. The
|
`sticky`, `text`, and `timeStr` context properties to change how the message is
|
||||||
`text` and `timeStr` properties may contain HTML and come pre-sanitized; plugins
|
processed. The `text` and `timeStr` properties may contain HTML and come
|
||||||
should be careful to sanitize any added user input to avoid introducing an XSS
|
pre-sanitized; plugins should be careful to sanitize any added user input to
|
||||||
vulnerability.
|
avoid introducing an XSS vulnerability.
|
||||||
|
|
||||||
Context properties:
|
Context properties:
|
||||||
|
|
||||||
|
@ -302,6 +302,11 @@ Context properties:
|
||||||
time correction and a default `userId` property if missing. Plugins must not
|
time correction and a default `userId` property if missing. Plugins must not
|
||||||
modify this object. Warning: Unlike `text`, `message.text` is not
|
modify this object. Warning: Unlike `text`, `message.text` is not
|
||||||
pre-sanitized or processed in any way.
|
pre-sanitized or processed in any way.
|
||||||
|
* `rendered` - Used to override the default message rendering. Initially set to
|
||||||
|
`null`. If the hook function sets this to a DOM element object or a jQuery
|
||||||
|
object, then that object will be used as the rendered message UI. Otherwise,
|
||||||
|
if this is set to `null`, then Etherpad will render a default UI for the
|
||||||
|
message using the other context properties.
|
||||||
* `sticky` (boolean): Whether the gritter notification should fade out on its
|
* `sticky` (boolean): Whether the gritter notification should fade out on its
|
||||||
own or just sit there until manually closed.
|
own or just sit there until manually closed.
|
||||||
* `timestamp`: When the chat message was sent (milliseconds since epoch),
|
* `timestamp`: When the chat message was sent (milliseconds since epoch),
|
||||||
|
|
|
@ -132,6 +132,7 @@ exports.chat = (() => {
|
||||||
author: msg.userId,
|
author: msg.userId,
|
||||||
text: padutils.escapeHtmlWithClickableLinks(msg.text, '_blank'),
|
text: padutils.escapeHtmlWithClickableLinks(msg.text, '_blank'),
|
||||||
message: msg,
|
message: msg,
|
||||||
|
rendered: null,
|
||||||
sticky: false,
|
sticky: false,
|
||||||
timestamp: msg.time,
|
timestamp: msg.time,
|
||||||
timeStr: (() => {
|
timeStr: (() => {
|
||||||
|
@ -164,7 +165,7 @@ exports.chat = (() => {
|
||||||
|
|
||||||
await hooks.aCallAll('chatNewMessage', ctx);
|
await hooks.aCallAll('chatNewMessage', ctx);
|
||||||
const cls = authorClass(ctx.author);
|
const cls = authorClass(ctx.author);
|
||||||
const chatMsg = $('<p>')
|
const chatMsg = ctx.rendered != null ? $(ctx.rendered) : $('<p>')
|
||||||
.attr('data-authorId', ctx.author)
|
.attr('data-authorId', ctx.author)
|
||||||
.addClass(cls)
|
.addClass(cls)
|
||||||
.append($('<b>').text(`${ctx.authorName}:`))
|
.append($('<b>').text(`${ctx.authorName}:`))
|
||||||
|
|
|
@ -79,5 +79,18 @@ describe('chat hooks', function () {
|
||||||
helper.sendChatMessage(`${msg}{enter}`),
|
helper.sendChatMessage(`${msg}{enter}`),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('`rendered` overrides default rendering', async function () {
|
||||||
|
let rendered;
|
||||||
|
await Promise.all([
|
||||||
|
checkHook('chatNewMessage', (context) => {
|
||||||
|
expect(context.rendered == null).to.be.ok();
|
||||||
|
rendered = context.rendered = helper.padChrome$.document.createElement('p');
|
||||||
|
rendered.append('message rendering overridden');
|
||||||
|
}),
|
||||||
|
helper.sendChatMessage(`${this.test.title}{enter}`),
|
||||||
|
]);
|
||||||
|
expect(helper.chatTextParagraphs().last()[0]).to.be(rendered);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue