diff --git a/CHANGELOG.md b/CHANGELOG.md
index e846b96420..5ce6513dac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,29 @@
+#### v3.1.3 (2023-05-15)
+
+##### Chores
+
+* incrementing version number - v3.1.2 (40fa3489)
+* update changelog for v3.1.2 (5b398782)
+* incrementing version number - v3.1.1 (40250733)
+* incrementing version number - v3.1.0 (0cb386bd)
+* incrementing version number - v3.0.1 (26f6ea49)
+* incrementing version number - v3.0.0 (224e08cd)
+
+##### Continuous Integration
+
+* use GitHub Actions expression instead of handlebars template (#11599) (412a1ecf)
+* tag with branch name if not default branch (cd7fdfce)
+
+##### Bug Fixes
+
+* #11601, dont trigger edit if chat input has text (d55cd464)
+* #11600, prevent helmet crash on startup (8eed5a84)
+* #11594 (85d104c3)
+
+##### Other Changes
+
+* use csrf_token in ws handshake (#11573) (51096ad2)
+
#### v3.1.2 (2023-05-12)
##### Chores
diff --git a/install/package.json b/install/package.json
index fac61cf2da..ca0c847cf2 100644
--- a/install/package.json
+++ b/install/package.json
@@ -95,7 +95,7 @@
"nodebb-plugin-dbsearch": "6.0.1",
"nodebb-plugin-emoji": "5.0.10",
"nodebb-plugin-emoji-android": "4.0.0",
- "nodebb-plugin-markdown": "12.0.3",
+ "nodebb-plugin-markdown": "12.0.4",
"nodebb-plugin-mentions": "4.1.1",
"nodebb-plugin-ntfy": "1.0.15",
"nodebb-plugin-spam-be-gone": "2.0.7",
diff --git a/public/src/client/chats.js b/public/src/client/chats.js
index ecb724b3c9..e21181cdc0 100644
--- a/public/src/client/chats.js
+++ b/public/src/client/chats.js
@@ -55,7 +55,7 @@ define('forum/chats', [
Chats.initialised = true;
messages.scrollToBottom($('.expanded-chat ul.chat-content'));
-
+ messages.wrapImagesInLinks($('.expanded-chat ul.chat-content'));
search.init();
};
@@ -69,6 +69,7 @@ define('forum/chats', [
Chats.addScrollHandler(ajaxify.data.roomId, ajaxify.data.uid, $('.chat-content'));
Chats.addScrollBottomHandler($('.chat-content'));
Chats.addCharactersLeftHandler($('[component="chat/main-wrapper"]'));
+ Chats.addTextareaResizeHandler($('[component="chat/main-wrapper"]'));
Chats.addIPHandler($('[component="chat/main-wrapper"]'));
Chats.createAutoComplete(ajaxify.data.roomId, $('[component="chat/input"]'));
Chats.addUploadHandler({
@@ -169,10 +170,8 @@ define('forum/chats', [
messages.parseMessage(data, function (html) {
const currentScrollTop = el.scrollTop();
const previousHeight = el[0].scrollHeight;
- html = $(html);
el.prepend(html);
- html.find('.timeago').timeago();
- html.find('img:not(.not-responsive)').addClass('img-fluid');
+ messages.onMessagesAddedToDom(html);
el.scrollTop((el[0].scrollHeight - previousHeight) + currentScrollTop);
loading = false;
});
@@ -195,6 +194,19 @@ define('forum/chats', [
});
};
+ Chats.addTextareaResizeHandler = function (parent) {
+ // https://stackoverflow.com/questions/454202/creating-a-textarea-with-auto-resize
+ const textarea = parent.find('[component="chat/input"]');
+ textarea.on('input', function () {
+ const isAtBottom = messages.isAtBottom(parent.find('.chat-content'));
+ textarea.css({ height: 0 });
+ textarea.css({ height: textarea.prop('scrollHeight') + 'px' });
+ if (isAtBottom) {
+ messages.scrollToBottom(parent.find('.chat-content'));
+ }
+ });
+ };
+
Chats.addActionHandlers = function (element, roomId) {
element.on('click', '[data-action]', function () {
const messageId = $(this).parents('[data-mid]').attr('data-mid');
diff --git a/public/src/client/chats/messages.js b/public/src/client/chats/messages.js
index b17a8f772b..f5699709a2 100644
--- a/public/src/client/chats/messages.js
+++ b/public/src/client/chats/messages.js
@@ -3,8 +3,11 @@
define('forum/chats/messages', [
'components', 'translator', 'benchpress', 'hooks',
- 'bootbox', 'alerts', 'messages', 'api',
-], function (components, translator, Benchpress, hooks, bootbox, alerts, messagesModule, api) {
+ 'bootbox', 'alerts', 'messages', 'api', 'forum/topic/images',
+], function (
+ components, translator, Benchpress, hooks,
+ bootbox, alerts, messagesModule, api, images
+) {
const messages = {};
messages.sendMessage = async function (roomId, inputEl) {
@@ -25,6 +28,7 @@ define('forum/chats/messages', [
}).catch((err) => {
inputEl.val(message).trigger('input');
messages.updateRemainingLength(inputEl.parent());
+ messages.updateTextAreaHeight(chatContent);
if (err.message === '[[error:email-not-confirmed-chat]]') {
return messagesModule.showEmailConfirmWarning(err.message);
}
@@ -49,18 +53,9 @@ define('forum/chats/messages', [
};
messages.updateTextAreaHeight = function (chatContentEl) {
- // https://stackoverflow.com/questions/454202/creating-a-textarea-with-auto-resize
const textarea = chatContentEl.find('[component="chat/input"]');
const scrollHeight = textarea.prop('scrollHeight');
textarea.css({ height: scrollHeight + 'px' });
- textarea.on('input', function () {
- const isAtBottom = messages.isAtBottom(chatContentEl.find('.chat-content'));
- textarea.css({ height: 0 });
- textarea.css({ height: textarea.prop('scrollHeight') + 'px' });
- if (isAtBottom) {
- messages.scrollToBottom(chatContentEl.find('.chat-content'));
- }
- });
};
function autoresizeTextArea(textarea) {
@@ -89,8 +84,7 @@ define('forum/chats/messages', [
const newMessage = $(html);
const isAtBottom = messages.isAtBottom(chatContentEl);
newMessage.appendTo(chatContentEl);
- newMessage.find('.timeago').timeago();
- newMessage.find('img:not(.not-responsive)').addClass('img-fluid');
+ messages.onMessagesAddedToDom(newMessage);
if (isAtBottom) {
messages.scrollToBottom(chatContentEl);
}
@@ -100,10 +94,15 @@ define('forum/chats/messages', [
});
}
+ messages.onMessagesAddedToDom = function (messageEls) {
+ messageEls.find('.timeago').timeago();
+ messageEls.find('img:not(.not-responsive)').addClass('img-fluid');
+ messages.wrapImagesInLinks(messageEls.first().parent());
+ };
messages.parseMessage = function (data, callback) {
function done(html) {
- translator.translate(html, callback);
+ translator.translate(html, translated => callback($(translated)));
}
const tplData = {
messages: data,
@@ -134,6 +133,12 @@ define('forum/chats/messages', [
}
};
+ messages.wrapImagesInLinks = function (containerEl) {
+ containerEl.find('[component="chat/message/body"] img:not(.emoji)').each(function () {
+ images.wrapImageInLink($(this));
+ });
+ };
+
messages.toggleScrollUpAlert = function (containerEl) {
const isAtBottom = messages.isAtBottom(containerEl, 300);
containerEl.parent()
@@ -225,7 +230,7 @@ define('forum/chats/messages', [
const body = components.get('chat/message', message.messageId);
if (body.length) {
body.replaceWith(html);
- components.get('chat/message', message.messageId).find('.timeago').timeago();
+ messages.onMessagesAddedToDom(html);
}
});
});
@@ -234,13 +239,15 @@ define('forum/chats/messages', [
function onChatMessageDeleted(messageId) {
components.get('chat/message', messageId)
.toggleClass('deleted', true)
- .find('[component="chat/message/body"]').translateHtml('[[modules:chat.message-deleted]]');
+ .find('[component="chat/message/body"]')
+ .translateHtml('[[modules:chat.message-deleted]]');
}
function onChatMessageRestored(message) {
components.get('chat/message', message.messageId)
.toggleClass('deleted', false)
- .find('[component="chat/message/body"]').html(message.content);
+ .find('[component="chat/message/body"]')
+ .html(message.content);
}
messages.delete = function (messageId, roomId) {
diff --git a/public/src/client/post-queue.js b/public/src/client/post-queue.js
index e2617b273e..d7cfb9f230 100644
--- a/public/src/client/post-queue.js
+++ b/public/src/client/post-queue.js
@@ -113,7 +113,6 @@ define('forum/post-queue', [
if (subselector) {
const action = subselector.getAttribute('data-action');
const uid = subselector.closest('[data-uid]').getAttribute('data-uid');
-
switch (action) {
case 'editCategory': {
const categoryEl = e.target.closest('[data-id]').querySelector('.topic-category');
diff --git a/public/src/client/topic.js b/public/src/client/topic.js
index 7143759506..a0b9aba183 100644
--- a/public/src/client/topic.js
+++ b/public/src/client/topic.js
@@ -234,7 +234,7 @@ define('forum/topic', [
let codeBlocks = $('[component="topic"] [component="post/content"] code:not([data-button-added])');
codeBlocks = codeBlocks.filter((i, el) => $(el).text().includes('\n'));
const container = $('
');
- const buttonDiv = $('');
+ const buttonDiv = $('');
codeBlocks.parent().wrap(container).parent().append(buttonDiv);
codeBlocks.parent().parent().find('[component="copy/code/btn"]').translateAttr('title', '[[topic:copy-code]]');
codeBlocks.attr('data-button-added', 1);
diff --git a/public/src/client/topic/events.js b/public/src/client/topic/events.js
index 9856095401..7b78bb4b58 100644
--- a/public/src/client/topic/events.js
+++ b/public/src/client/topic/events.js
@@ -9,9 +9,8 @@ define('forum/topic/events', [
'forum/topic/images',
'components',
'translator',
- 'benchpress',
'hooks',
-], function (postTools, threadTools, posts, images, components, translator, Benchpress, hooks) {
+], function (postTools, threadTools, posts, images, components, translator, hooks) {
const Events = {};
const events = {
diff --git a/public/src/client/topic/images.js b/public/src/client/topic/images.js
index a04b22a9e9..8778053821 100644
--- a/public/src/client/topic/images.js
+++ b/public/src/client/topic/images.js
@@ -4,30 +4,32 @@
define('forum/topic/images', [], function () {
const Images = {};
+ const suffixRegex = /-resized(\.[\w]+)?$/;
+
Images.wrapImagesInLinks = function (posts) {
posts.find('[component="post/content"] img:not(.emoji)').each(function () {
- const $this = $(this);
- let src = $this.attr('src') || '';
- const alt = $this.attr('alt') || '';
- const suffixRegex = /-resized(\.[\w]+)?$/;
+ Images.wrapImageInLink($(this));
+ });
+ };
- if (src === 'about:blank') {
- return;
- }
+ Images.wrapImageInLink = function (imageEl) {
+ let src = imageEl.attr('src') || '';
+ if (src === 'about:blank') {
+ return;
+ }
+ if (!imageEl.parent().is('a')) {
if (utils.isRelativeUrl(src) && suffixRegex.test(src)) {
src = src.replace(suffixRegex, '$1');
}
+ const alt = imageEl.attr('alt') || '';
const srcExt = src.split('.').slice(1).pop();
const altFilename = alt.split('/').pop();
const altExt = altFilename.split('.').slice(1).pop();
-
- if (!$this.parent().is('a')) {
- $this.wrap('');
- }
- });
+ imageEl.wrap('');
+ }
};
return Images;
diff --git a/public/src/modules/chat.js b/public/src/modules/chat.js
index c7158b4e02..40f745043a 100644
--- a/public/src/modules/chat.js
+++ b/public/src/modules/chat.js
@@ -246,6 +246,7 @@ define('chat', [
chatModal.css('position', 'fixed');
chatModal.appendTo($('body'));
chatModal.find('.timeago').timeago();
+ ChatsMessages.wrapImagesInLinks(chatModal.find('[component="chat/messages"] .chat-content'));
module.center(chatModal);
app.loadJQueryUI(function () {
@@ -331,6 +332,7 @@ define('chat', [
Chats.addScrollBottomHandler(chatModal.find('.chat-content'));
Chats.addCharactersLeftHandler(chatModal);
+ Chats.addTextareaResizeHandler(chatModal);
Chats.addIPHandler(chatModal);
Chats.addUploadHandler({
diff --git a/src/views/emails/partials/header.tpl b/src/views/emails/partials/header.tpl
index a467339215..be45efadaf 100644
--- a/src/views/emails/partials/header.tpl
+++ b/src/views/emails/partials/header.tpl
@@ -8,7 +8,7 @@
-
+
-
+
+ /* https://github.com/NodeBB/NodeBB/issues/11572 */
+ img[src*="nodebb-plugin-emoji"] {
+ width: 23px;
+ height: auto;
+ vertical-align: top;
+ }
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
- {{{ if logo.src }}}
-
- {{{ else }}}
-
- {{{ end }}}
- |
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+ {{{ if logo.src }}}
+
+ {{{ else }}}
+
+ {{{ end }}}
+ |
+
+
+
\ No newline at end of file
diff --git a/src/views/post-queue.tpl b/src/views/post-queue.tpl
index e5e51d7d75..c6691f6c98 100644
--- a/src/views/post-queue.tpl
+++ b/src/views/post-queue.tpl
@@ -45,7 +45,7 @@
{{{ end }}}
{{{ each posts }}}
-
+
{{{if !posts.data.tid}}}
@@ -94,7 +94,7 @@
[[post-queue:content]]
-
{posts.data.content}
+
{posts.data.content}