Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
converse.js
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
converse.js
Commits
acd9a186
Commit
acd9a186
authored
Jul 20, 2018
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update with new message markup
parent
6a462f6c
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
386 additions
and
428 deletions
+386
-428
css/converse.css
css/converse.css
+17
-29
dist/converse.js
dist/converse.js
+91
-91
mockup/chatroom.html
mockup/chatroom.html
+7
-3
sass/_chatbox.scss
sass/_chatbox.scss
+1
-31
sass/_messages.scss
sass/_messages.scss
+16
-2
spec/chatbox.js
spec/chatbox.js
+14
-14
spec/chatroom.js
spec/chatroom.js
+8
-8
spec/http-file-upload.js
spec/http-file-upload.js
+3
-3
spec/messages.js
spec/messages.js
+170
-177
spec/spoilers.js
spec/spoilers.js
+8
-8
src/converse-chatview.js
src/converse-chatview.js
+5
-7
src/converse-message-view.js
src/converse-message-view.js
+14
-19
src/templates/action.html
src/templates/action.html
+0
-6
src/templates/file_progress.html
src/templates/file_progress.html
+3
-3
src/templates/message.html
src/templates/message.html
+21
-10
src/templates/spoiler_message.html
src/templates/spoiler_message.html
+0
-14
src/utils/core.js
src/utils/core.js
+8
-3
No files found.
css/converse.css
View file @
acd9a186
...
...
@@ -7381,7 +7381,7 @@ body.reset {
background-color
:
#3AA569
;
box-shadow
:
1px
3px
5px
3px
rgba
(
0
,
0
,
0
,
0.4
);
z-index
:
1
;
overflow-y
:
scroll
;
overflow-y
:
hidden
;
width
:
100%
;
}
@media
screen
and
(
max-height
:
450px
)
{
#conversejs
.chatbox
.box-flyout
{
...
...
@@ -7648,18 +7648,6 @@ body.reset {
#conversejs
.converse-overlayed
.chatbox
.box-flyout
{
min-width
:
250px
!important
;
width
:
250px
;
}
#conversejs
.converse-embedded
.chatbox
.chat-body
.chat-message
,
#conversejs
.converse-overlayed
.chatbox
.chat-body
.chat-message
{
line-height
:
20px
;
}
#conversejs
.converse-embedded
.chatbox
.chat-body
.chat-message
.chat-msg-author
,
#conversejs
.converse-overlayed
.chatbox
.chat-body
.chat-message
.chat-msg-author
{
line-height
:
20px
;
}
#conversejs
.converse-embedded
.chatbox
.chat-body
.chat-message
.chat-msg-content
,
#conversejs
.converse-overlayed
.chatbox
.chat-body
.chat-message
.chat-msg-content
{
line-height
:
20px
;
}
#conversejs
.converse-embedded
.chatbox
.chat-body
.chat-message
.chat-msg-content
.emojione
,
#conversejs
.converse-overlayed
.chatbox
.chat-body
.chat-message
.chat-msg-content
.emojione
{
margin-bottom
:
-5px
;
}
#conversejs
.converse-embedded
.chatbox
form
.sendXMPPMessage
.chat-toolbar
li
.toolbar-menu
,
#conversejs
.converse-overlayed
.chatbox
form
.sendXMPPMessage
.chat-toolbar
li
.toolbar-menu
{
min-width
:
235px
;
}
...
...
@@ -7746,16 +7734,6 @@ body.reset {
background-color
:
#3AA569
;
border-top-left-radius
:
4px
;
border-top-right-radius
:
4px
;
}
#conversejs
.converse-fullscreen
.chatbox
.chat-body
.chat-message
{
line-height
:
16px
;
font-size
:
12px
;
}
#conversejs
.converse-fullscreen
.chatbox
.chat-body
.chat-message
.chat-msg-author
{
line-height
:
16px
;
}
#conversejs
.converse-fullscreen
.chatbox
.chat-body
.chat-message
.chat-msg-content
{
line-height
:
16px
;
}
#conversejs
.converse-fullscreen
.chatbox
.chat-body
.chat-message
.chat-msg-content
.emojione
{
height
:
16px
;
margin-bottom
:
-4px
;
}
#conversejs
.converse-fullscreen
.chatbox
.chat-content
{
border-top-left-radius
:
4px
;
border-top-right-radius
:
4px
;
}
...
...
@@ -8884,6 +8862,8 @@ body.reset {
align-items
:
stretch
;
margin-left
:
0.5rem
;
width
:
100%
;
}
#conversejs
.message.chat-msg
.chat-msg__content--action
{
margin-left
:
0
;
}
#conversejs
.message.chat-msg
.chat-msg__body
{
display
:
flex
;
flex-direction
:
row
;
...
...
@@ -8893,8 +8873,9 @@ body.reset {
display
:
flex
;
flex-direction
:
column
;
width
:
100%
;
}
#conversejs
.message.chat-msg
.chat-msg-edited
{
cursor
:
pointer
;
}
#conversejs
.message.chat-msg
.chat-msg__edit-modal
{
cursor
:
pointer
;
padding-right
:
0.5em
;
}
#conversejs
.message.chat-msg.headline
.chat-msg__body
{
margin-left
:
0
;
}
#conversejs
.message.chat-msg
.chat-msg__text
{
...
...
@@ -8906,11 +8887,12 @@ body.reset {
word-break
:
break-all
;
}
#conversejs
.message.chat-msg
.chat-msg__text
.emojione
{
margin-bottom
:
-6px
;
}
#conversejs
.message.chat-msg
.chat-msg-media
{
margin-top
:
0.25rem
;
}
#conversejs
.message.chat-msg
.chat-msg-media
a
{
#conversejs
.message.chat-msg
.chat-msg__media
{
margin-top
:
0.25rem
;
word-break
:
break-all
;
}
#conversejs
.message.chat-msg
.chat-msg__media
a
{
word-wrap
:
break-word
;
}
#conversejs
.message.chat-msg
.chat-msg
-
media
audio
{
#conversejs
.message.chat-msg
.chat-msg
__
media
audio
{
width
:
100%
;
}
#conversejs
.message.chat-msg
.chat-msg__actions
.chat-msg__action
{
height
:
14px
;
...
...
@@ -8934,6 +8916,7 @@ body.reset {
padding-bottom
:
0.25rem
;
display
:
block
;
}
#conversejs
.message.chat-msg
.chat-msg__heading
.chat-msg__author
{
white-space
:
nowrap
;
font-family
:
"Century Gothic"
,
futura
,
"URW Gothic L"
,
Verdana
,
sans-serif
;
font-size
:
115%
;
}
#conversejs
.message.chat-msg
.chat-msg__heading
.chat-msg__author
.badge
{
...
...
@@ -8943,6 +8926,7 @@ body.reset {
padding-left
:
0.25em
;
color
:
#8c8c8c
;
}
#conversejs
.message.chat-msg.chat-msg--action
.chat-msg__content
{
flex-wrap
:
wrap
;
flex-direction
:
row
;
justify-content
:
flex-start
;
}
#conversejs
.message.chat-msg.chat-msg--action
.chat-msg__text
{
...
...
@@ -8951,6 +8935,10 @@ body.reset {
margin-top
:
0
;
padding-bottom
:
0
;
width
:
auto
;
}
#conversejs
.message.chat-msg.chat-msg--action
.chat-msg__author
{
font-size
:
14px
;
}
#conversejs
.message.chat-msg.chat-msg--action
.chat-msg__time
{
margin-left
:
0
;
}
#conversejs
.message.chat-msg.chat-msg--followup
.chat-msg__heading
,
#conversejs
.message.chat-msg.chat-msg--followup
.chat-msg__avatar
{
display
:
none
;
}
...
...
dist/converse.js
View file @
acd9a186
...
...
@@ -69333,11 +69333,11 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
// Copyright (c) 2012-2018, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2)
(function (root, factory) {
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! converse-core */ "./src/converse-core.js"), __webpack_require__(/*! bootstrap */ "./node_modules/bootstrap.native/dist/bootstrap-native-v4.js"), __webpack_require__(/*! emojione */ "./node_modules/emojione/lib/js/emojione.js"), __webpack_require__(/*! xss */ "./node_modules/xss/dist/xss.js"), __webpack_require__(/*! templates/
action.html */ "./src/templates/action.html"), __webpack_require__(/*! templates/
chatbox.html */ "./src/templates/chatbox.html"), __webpack_require__(/*! templates/chatbox_head.html */ "./src/templates/chatbox_head.html"), __webpack_require__(/*! templates/chatbox_message_form.html */ "./src/templates/chatbox_message_form.html"), __webpack_require__(/*! templates/emojis.html */ "./src/templates/emojis.html"), __webpack_require__(/*! templates/error_message.html */ "./src/templates/error_message.html"), __webpack_require__(/*! templates/help_message.html */ "./src/templates/help_message.html"), __webpack_require__(/*! templates/info.html */ "./src/templates/info.html"), __webpack_require__(/*! templates/new_day.html */ "./src/templates/new_day.html"), __webpack_require__(/*! templates/user_details_modal.html */ "./src/templates/user_details_modal.html"), __webpack_require__(/*! templates/toolbar_fileupload.html */ "./src/templates/toolbar_fileupload.html"), __webpack_require__(/*! templates/spinner.html */ "./src/templates/spinner.html"), __webpack_require__(/*! templates/spoiler_button.html */ "./src/templates/spoiler_button.html"), __webpack_require__(/*! templates/status_message.html */ "./src/templates/status_message.html"), __webpack_require__(/*! templates/toolbar.html */ "./src/templates/toolbar.html"), __webpack_require__(/*! converse-modal */ "./src/converse-modal.js"), __webpack_require__(/*! converse-chatboxes */ "./src/converse-chatboxes.js"), __webpack_require__(/*! converse-message-view */ "./src/converse-message-view.js")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! converse-core */ "./src/converse-core.js"), __webpack_require__(/*! bootstrap */ "./node_modules/bootstrap.native/dist/bootstrap-native-v4.js"), __webpack_require__(/*! emojione */ "./node_modules/emojione/lib/js/emojione.js"), __webpack_require__(/*! xss */ "./node_modules/xss/dist/xss.js"), __webpack_require__(/*! templates/chatbox.html */ "./src/templates/chatbox.html"), __webpack_require__(/*! templates/chatbox_head.html */ "./src/templates/chatbox_head.html"), __webpack_require__(/*! templates/chatbox_message_form.html */ "./src/templates/chatbox_message_form.html"), __webpack_require__(/*! templates/emojis.html */ "./src/templates/emojis.html"), __webpack_require__(/*! templates/error_message.html */ "./src/templates/error_message.html"), __webpack_require__(/*! templates/help_message.html */ "./src/templates/help_message.html"), __webpack_require__(/*! templates/info.html */ "./src/templates/info.html"), __webpack_require__(/*! templates/new_day.html */ "./src/templates/new_day.html"), __webpack_require__(/*! templates/user_details_modal.html */ "./src/templates/user_details_modal.html"), __webpack_require__(/*! templates/toolbar_fileupload.html */ "./src/templates/toolbar_fileupload.html"), __webpack_require__(/*! templates/spinner.html */ "./src/templates/spinner.html"), __webpack_require__(/*! templates/spoiler_button.html */ "./src/templates/spoiler_button.html"), __webpack_require__(/*! templates/status_message.html */ "./src/templates/status_message.html"), __webpack_require__(/*! templates/toolbar.html */ "./src/templates/toolbar.html"), __webpack_require__(/*! converse-modal */ "./src/converse-modal.js"), __webpack_require__(/*! converse-chatboxes */ "./src/converse-chatboxes.js"), __webpack_require__(/*! converse-message-view */ "./src/converse-message-view.js")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
})(void 0, function (converse, bootstrap, emojione, xss, tpl_
action, tpl_
chatbox, tpl_chatbox_head, tpl_chatbox_message_form, tpl_emojis, tpl_error_message, tpl_help_message, tpl_info, tpl_new_day, tpl_user_details_modal, tpl_toolbar_fileupload, tpl_spinner, tpl_spoiler_button, tpl_status_message, tpl_toolbar) {
})(void 0, function (converse, bootstrap, emojione, xss, tpl_chatbox, tpl_chatbox_head, tpl_chatbox_message_form, tpl_emojis, tpl_error_message, tpl_help_message, tpl_info, tpl_new_day, tpl_user_details_modal, tpl_toolbar_fileupload, tpl_spinner, tpl_spoiler_button, tpl_status_message, tpl_toolbar) {
"use strict";
const _converse$env = converse.env,
...
...
@@ -70055,18 +70055,18 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
date = moment(el.getAttribute('data-isodate')),
next_el = el.nextElementSibling;
if (!u.hasClass('chat-
action', el) && !u.hasClass('chat
-action', previous_el) && previous_el.getAttribute('data-from') === from && date.isBefore(moment(previous_el.getAttribute('data-isodate')).add(10, 'minutes'))) {
u.addClass('chat-msg-followup', el);
if (!u.hasClass('chat-
msg--action', el) && !u.hasClass('chat-msg-
-action', previous_el) && previous_el.getAttribute('data-from') === from && date.isBefore(moment(previous_el.getAttribute('data-isodate')).add(10, 'minutes'))) {
u.addClass('chat-msg-
-
followup', el);
}
if (!next_el) {
return;
}
if (!u.hasClass('chat-action', 'el') && next_el.getAttribute('data-from') === from && moment(next_el.getAttribute('data-isodate')).isBefore(date.add(10, 'minutes'))) {
u.addClass('chat-msg-followup', next_el);
if (!u.hasClass('chat-
msg--
action', 'el') && next_el.getAttribute('data-from') === from && moment(next_el.getAttribute('data-isodate')).isBefore(date.add(10, 'minutes'))) {
u.addClass('chat-msg-
-
followup', next_el);
} else {
u.removeClass('chat-msg-followup', next_el);
u.removeClass('chat-msg-
-
followup', next_el);
}
},
...
...
@@ -74581,11 +74581,11 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
// Copyright (c) 2013-2018, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2)
(function (root, factory) {
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! converse-core */ "./src/converse-core.js"), __webpack_require__(/*! xss */ "./node_modules/xss/dist/xss.js"), __webpack_require__(/*! emojione */ "./node_modules/emojione/lib/js/emojione.js"), __webpack_require__(/*! filesize */ "./node_modules/filesize/lib/filesize.js"), __webpack_require__(/*! templates/
action.html */ "./src/templates/action.html"), __webpack_require__(/*! templates/csn.html */ "./src/templates/csn.html"), __webpack_require__(/*! templates/file_progress.html */ "./src/templates/file_progress.html"), __webpack_require__(/*! templates/info.html */ "./src/templates/info.html"), __webpack_require__(/*! templates/message.html */ "./src/templates/message.html"), __webpack_require__(/*! templates/message_versions_modal.html */ "./src/templates/message_versions_modal.html"), __webpack_require__(/*! templates/spoiler_message.html */ "./src/templates/spoiler_message
.html")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! converse-core */ "./src/converse-core.js"), __webpack_require__(/*! xss */ "./node_modules/xss/dist/xss.js"), __webpack_require__(/*! emojione */ "./node_modules/emojione/lib/js/emojione.js"), __webpack_require__(/*! filesize */ "./node_modules/filesize/lib/filesize.js"), __webpack_require__(/*! templates/
csn.html */ "./src/templates/csn.html"), __webpack_require__(/*! templates/file_progress.html */ "./src/templates/file_progress.html"), __webpack_require__(/*! templates/info.html */ "./src/templates/info.html"), __webpack_require__(/*! templates/message.html */ "./src/templates/message.html"), __webpack_require__(/*! templates/message_versions_modal.html */ "./src/templates/message_versions_modal
.html")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
})(void 0, function (converse, xss, emojione, filesize, tpl_
action, tpl_csn, tpl_file_progress, tpl_info, tpl_message, tpl_message_versions_modal, tpl_spoiler_message
) {
})(void 0, function (converse, xss, emojione, filesize, tpl_
csn, tpl_file_progress, tpl_info, tpl_message, tpl_message_versions_modal
) {
"use strict";
const _converse$env = converse.env,
...
...
@@ -74654,7 +74654,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
},
render() {
const is_followup = u.hasClass('chat-msg-followup', this.el);
const is_followup = u.hasClass('chat-msg-
-
followup', this.el);
let msg;
if (this.model.isOnlyChatStateNotification()) {
...
...
@@ -74668,7 +74668,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
}
if (is_followup) {
u.addClass('chat-msg-followup', this.el);
u.addClass('chat-msg-
-
followup', this.el);
}
return this.el;
...
...
@@ -74693,21 +74693,13 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
},
renderChatMessage() {
let template,
text = this.model.get('message');
if (this.isMeCommand()) {
template = tpl_action;
text = this.model.get('message').replace(/^\/me/, '');
} else {
template = this.model.get('is_spoiler') ? tpl_spoiler_message : tpl_message;
}
const moment_time = moment(this.model.get('time')),
const is_me_message = this.isMeCommand(),
moment_time = moment(this.model.get('time')),
role = this.model.vcard.get('role'),
roles = role ? role.split(',') : [];
const msg = u.stringToElement(t
emplat
e(_.extend(this.model.toJSON(), {
const msg = u.stringToElement(t
pl_messag
e(_.extend(this.model.toJSON(), {
'__': __,
'is_me_message': is_me_message,
'roles': roles,
'pretty_time': moment_time.format(_converse.time_format),
'time': moment_time.format(),
...
...
@@ -74715,13 +74707,19 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
'label_show': __('Show more'),
'username': this.model.getDisplayName()
})));
var
url = this.model.get('oob_url');
const
url = this.model.get('oob_url');
if (url) {
msg.querySelector('.chat-msg
-
media').innerHTML = _.flow(_.partial(u.renderFileURL, _converse), _.partial(u.renderMovieURL, _converse), _.partial(u.renderAudioURL, _converse), _.partial(u.renderImageURL, _converse))(url);
msg.querySelector('.chat-msg
__
media').innerHTML = _.flow(_.partial(u.renderFileURL, _converse), _.partial(u.renderMovieURL, _converse), _.partial(u.renderAudioURL, _converse), _.partial(u.renderImageURL, _converse))(url);
}
const msg_content = msg.querySelector('.chat-msg-text');
let text = this.model.get('message');
if (is_me_message) {
text = text.replace(/^\/me/, '');
}
const msg_content = msg.querySelector('.chat-msg__text');
if (text !== url) {
text = xss.filterXSS(text, {
...
...
@@ -83939,30 +83937,6 @@ if (!String.prototype.trim) {
/***/ }),
/***/ "./src/templates/action.html":
/*!***********************************!*\
!*** ./src/templates/action.html ***!
\***********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
var _ = {escape:__webpack_require__(/*! ./node_modules/lodash/escape.js */ "./node_modules/lodash/escape.js")};
module.exports = function(o) {
var __t, __p = '', __e = _.escape;
__p += '<!-- src/templates/action.html -->\n<div class="message chat-msg chat-action ' +
__e(o.extra_classes) +
'" data-isodate="' +
__e(o.time) +
'" data-from="' +
__e(o.from) +
'">\n <span class="chat-msg-heading">\n <span class="chat-msg-author">**' +
__e(o.username) +
'</span>\n </span>\n <p class="chat-msg-text"><!-- message gets added here via renderMessage --></p>\n</div>\n';
return __p
};
/***/ }),
/***/ "./src/templates/add_chatroom_modal.html":
/*!***********************************************!*\
!*** ./src/templates/add_chatroom_modal.html ***!
...
...
@@ -85230,7 +85204,7 @@ __p += '<!-- src/templates/file_progress.html -->\n<div class="message chat-msg"
__e(o.time) +
'" data-msgid="' +
__e(o.msgid) +
'">\n <canvas class="avatar
" height="36" width="36"></canvas>\n <div class="chat-msg-content">\n <span class="chat-msg-
text">Uploading file: <strong>' +
'">\n <canvas class="avatar
chat-msg__avatar" height="36" width="36"></canvas>\n <div class="chat-msg__content">\n <span class="chat-msg__
text">Uploading file: <strong>' +
__e(o.file.name) +
'</strong>, ' +
__e(o.filesize) +
...
...
@@ -85699,7 +85673,11 @@ var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') }
__p += '<!-- src/templates/message.html -->\n<div class="message chat-msg ' +
__e(o.type) +
' ' +
' ';
if (o.is_me_message) { ;
__p += ' chat-msg--action ';
} ;
__p += ' ' +
__e(o.extra_classes) +
'" data-isodate="' +
__e(o.time) +
...
...
@@ -85708,10 +85686,26 @@ __e(o.msgid) +
'" data-from="' +
__e(o.from) +
'">\n ';
if (o.type !== 'headline') { ;
__p += '\n <canvas class="avatar" height="36" width="36"></canvas>\n ';
if (o.type !== 'headline' && !o.is_me_message) { ;
__p += '\n <canvas class="avatar chat-msg__avatar" height="36" width="36"></canvas>\n ';
} ;
__p += '\n <div class="chat-msg__content ';
if (o.is_me_message) { ;
__p += 'chat-msg__content--action';
} ;
__p += '\n <div class="chat-msg-content">\n <span class="chat-msg-heading">\n <span class="chat-msg-author">' +
__p += '">\n <span class="chat-msg__heading">\n ';
if (o.is_me_message) { ;
__p += '<time timestamp="' +
__e(o.isodate) +
'" class="chat-msg__time">' +
__e(o.pretty_time) +
'</time>';
} ;
__p += '\n <span class="chat-msg__author">';
if (o.is_me_message) { ;
__p += '**';
}; ;
__p +=
__e(o.username) +
'\n ';
o.roles.forEach(function (role) { ;
...
...
@@ -85719,17 +85713,49 @@ __p += ' <span class="badge badge-secondary">' +
__e(role) +
'</span> ';
}); ;
__p += '\n </span>\n <time timestamp="' +
__p += '\n </span>\n ';
if (!o.is_me_message) { ;
__p += '<time timestamp="' +
__e(o.isodate) +
'" class="chat-msg
-
time">' +
'" class="chat-msg
__
time">' +
__e(o.pretty_time) +
'</time>\n </span>\n ';
'</time>';
} ;
__p += '\n </span>\n ';
if (!o.is_me_message) { ;
__p += '<div class="chat-msg__body">';
} ;
__p += ' \n ';
if (o.edited) { ;
__p += ' <i title="' +
__e(o.__('This message has been edited')) +
'" class="fa fa-edit chat-msg-edited"></i> ';
} ;
__p += '\n <span class="chat-msg-text"></span>\n <div class="chat-msg-media"></div>\n </div>\n</div>\n';
__p += '\n ';
if (!o.is_me_message) { ;
__p += '<div class="chat-msg__message">';
} ;
__p += ' \n ';
if (o.is_spoiler) { ;
__p += '\n <div class="chat-msg__spoiler-hint">\n <span class="spoiler-hint">' +
__e(o.spoiler_hint) +
'</span>\n <a class="badge badge-info spoiler-toggle" data-toggle-state="closed" href="#"><i class="fa fa-eye"></i>' +
__e(o.label_show) +
'</a>\n </div>\n ';
} ;
__p += '\n <div class="chat-msg__text';
if (o.is_spoiler) { ;
__p += ' spoiler collapsed';
} ;
__p += '"><!-- message gets added here via renderMessage --></div>\n <div class="chat-msg__media"></div>\n ';
if (!o.is_me_message) { ;
__p += '</div>';
} ;
__p += '\n ';
if (!o.is_me_message) { ;
__p += '</div>';
} ;
__p += ' \n </div>\n</div>\n';
return __p
};
...
...
@@ -86751,36 +86777,6 @@ return __p
/***/ }),
/***/ "./src/templates/spoiler_message.html":
/*!********************************************!*\
!*** ./src/templates/spoiler_message.html ***!
\********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
var _ = {escape:__webpack_require__(/*! ./node_modules/lodash/escape.js */ "./node_modules/lodash/escape.js")};
module.exports = function(o) {
var __t, __p = '', __e = _.escape;
__p += '<!-- src/templates/spoiler_message.html -->\n<div class="message chat-msg ' +
__e(o.extra_classes) +
'" data-isodate="' +
__e(o.time) +
'" data-msgid="' +
__e(o.msgid) +
'">\n <canvas class="avatar" height="36" width="36"></canvas>\n <div class="chat-msg-content">\n <span class="chat-msg-heading">\n <span class="chat-msg-author">' +
__e(o.username) +
'</span>\n <span class="chat-msg-time">' +
__e(o.pretty_time) +
'</span>\n </span>\n <div>\n <span class="spoiler-hint">' +
__e(o.spoiler_hint) +
'</span>\n <a class="badge badge-info spoiler-toggle" data-toggle-state="closed" href="#"><i class="fa fa-eye"></i>' +
__e(o.label_show) +
'</a>\n </div>\n <div class="chat-msg-text spoiler collapsed"><!-- message gets added here via renderMessage --></div>\n </div>\n</div>\n';
return __p
};
/***/ }),
/***/ "./src/templates/status_message.html":
/*!*******************************************!*\
!*** ./src/templates/status_message.html ***!
...
...
@@ -87275,6 +87271,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
return string.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
};
u.escapeURL = function (url) {
return encodeURI(decodeURI(url)).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
};
u.addHyperlinks = function (text) {
return URI.withinString(text, function (url) {
var uri = new URI(url);
...
...
@@ -87284,8 +87284,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
url = 'http://' + url;
}
url =
encodeURI(decodeURI(url)).replace(/[!'()]/g, escape).replace(/\*/g, "%2A"
);
return `<a target="_blank" rel="noopener" href="${u
.escapeHTML(url)
}">${u.escapeHTML(uri.readable())}</a>`;
url =
u.escapeHTML(u.escapeURL(url)
);
return `<a target="_blank" rel="noopener" href="${u
rl
}">${u.escapeHTML(uri.readable())}</a>`;
});
};
mockup/chatroom.html
View file @
acd9a186
...
...
@@ -45,8 +45,11 @@
Romeo Montague has entered the room
</div>
<div
class=
"message chat-msg chat-msg--action"
data-isodate=
"2018-04-36T18:07:38+02:00"
>
<div
class=
"chat-msg__content"
>
<span
class=
"chat-msg__heading"
><span
class=
"chat-msg__author"
>
**Romeo Montague
</span></span>
<div
class=
"chat-msg__content chat-msg__content--action"
>
<span
class=
"chat-msg__heading"
>
<time
timestamp=
"2018-12-29"
class=
"chat-msg__time"
>
15:29
</time>
<span
class=
"chat-msg__author"
>
**Romeo Montague
</span>
</span>
<span
class=
"chat-msg__text"
>
looks around
</span>
</div>
</div>
...
...
@@ -177,7 +180,7 @@
</div>
<div
class=
"chat-msg__body"
>
<div
class=
"chat-msg__message"
>
<div
class=
"chat-msg
-
media"
>
<div
class=
"chat-msg
__
media"
>
<a
href=
"https://images.unsplash.com/photo-1496660067708-010ebdd7ce72?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=ea3514e6e00d8ce25c24d992b97929d9&dpr=1&auto=format&fit=crop&w=1000&q=80&cs=tinysrgb"
target=
"_blank"
rel=
"noopener"
>
<img
class=
"chat-image img-thumbnail"
src=
"https://images.unsplash.com/photo-1496660067708-010ebdd7ce72?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=ea3514e6e00d8ce25c24d992b97929d9&dpr=1&auto=format&fit=crop&w=1000&q=80&cs=tinysrgb"
>
...
...
@@ -227,6 +230,7 @@
<span
class=
"chat-msg__time"
>
19:49
</span>
</div>
<div
class=
"chat-msg__body"
>
<i
title=
"This message has been edited"
class=
"fa fa-edit chat-msg__edit-modal"
></i>
<div
class=
"chat-msg__message"
>
<span
class=
"chat-msg__text"
>
I mean, sir, in delay We waste our lights in vain, like lamps by day.
</span>
</div>
...
...
sass/_chatbox.scss
View file @
acd9a186
...
...
@@ -124,7 +124,7 @@
background-color
:
$chat-head-color
;
box-shadow
:
1px
3px
5px
3px
rgba
(
0
,
0
,
0
,
0
.4
);
z-index
:
1
;
overflow-y
:
scroll
;
overflow-y
:
hidden
;
width
:
100%
;
@media
screen
and
(
max-height
:
$mobile-landscape-height
)
{
...
...
@@ -464,21 +464,6 @@
min-width
:
$overlayed-chat-width
!
important
;
width
:
$overlayed-chat-width
;
}
.chat-body
{
.chat-message
{
line-height
:
$line-height-large
;
.chat-msg-author
{
line-height
:
$line-height-large
;
}
.chat-msg-content
{
line-height
:
$line-height-large
;
.emojione
{
margin-bottom
:
-5px
;
}
}
}
}
}
.chatbox
{
form
.sendXMPPMessage
{
...
...
@@ -597,21 +582,6 @@
background-color
:
$chat-head-color
;
border-top-left-radius
:
$chatbox-border-radius
;
border-top-right-radius
:
$chatbox-border-radius
;
.chat-message
{
line-height
:
$line-height
;
font-size
:
$font-size-small
;
.chat-msg-author
{
line-height
:
$line-height
;
}
.chat-msg-content
{
line-height
:
$line-height
;
.emojione
{
height
:
$line-height
;
margin-bottom
:
-
$line-height
/
4
;
}
}
}
}
.chat-content
{
border-top-left-radius
:
$chatbox-border-radius
;
...
...
sass/_messages.scss
View file @
acd9a186
...
...
@@ -104,6 +104,7 @@
whitespace
:
nowrap
;
}
}
.chat-msg__content
{
display
:
flex
;
flex-direction
:
column
;
...
...
@@ -112,6 +113,9 @@
margin-left
:
0
.5rem
;
width
:
100%
;
}
.chat-msg__content--action
{
margin-left
:
0
;
}
.chat-msg__body
{
display
:
flex
;
...
...
@@ -126,8 +130,9 @@
width
:
100%
;
}
.chat-msg
-edited
{
.chat-msg
__edit-modal
{
cursor
:
pointer
;
padding-right
:
0
.5em
;
}
&
.headline
{
.chat-msg__body
{
...
...
@@ -148,8 +153,9 @@
}
}
.chat-msg
-
media
{
.chat-msg
__
media
{
margin-top
:
0
.25rem
;
word-break
:
break-all
;
a
{
word-wrap
:
break-word
;
}
...
...
@@ -188,6 +194,7 @@
display
:
block
;
.chat-msg__author
{
white-space
:
nowrap
;
font-family
:
$heading-font
;
font-size
:
115%
;
.badge
{
...
...
@@ -202,6 +209,7 @@
}
&
.chat-msg--action
{
.chat-msg__content
{
flex-wrap
:
wrap
;
flex-direction
:
row
;
justify-content
:
flex-start
;
}
...
...
@@ -213,6 +221,12 @@
padding-bottom
:
0
;
width
:
auto
;
}
.chat-msg__author
{
font-size
:
$message-font-size
;
}
.chat-msg__time
{
margin-left
:
0
;
}
}
&
.chat-msg--followup
{
...
...
spec/chatbox.js
View file @
acd9a186
...
...
@@ -76,33 +76,33 @@
test_utils
.
waitUntil
(
function
()
{
return
u
.
isVisible
(
view
.
el
);
}).
then
(
function
()
{
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-action
'
).
length
).
toBe
(
1
);
expect
(
_
.
includes
(
view
.
el
.
querySelector
(
'
.chat-msg
-
author
'
).
textContent
,
'
**Max Frankfurter
'
)).
toBeTruthy
();
expect
(
$
(
view
.
el
).
find
(
'
.chat-msg
-
text
'
).
text
()).
toBe
(
'
is tired
'
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-
msg--
action
'
).
length
).
toBe
(
1
);
expect
(
_
.
includes
(
view
.
el
.
querySelector
(
'
.chat-msg
__
author
'
).
textContent
,
'
**Max Frankfurter
'
)).
toBeTruthy
();
expect
(
$
(
view
.
el
).
find
(
'
.chat-msg
__
text
'
).
text
()).
toBe
(
'
is tired
'
);
message
=
'
/me is as well
'
;
test_utils
.
sendMessage
(
view
,
message
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-action
'
).
length
).
toBe
(
2
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-
msg--
action
'
).
length
).
toBe
(
2
);
return
test_utils
.
waitUntil
(()
=>
$
(
view
.
el
).
find
(
'
.chat-msg
-author:last
'
).
text
()
===
'
**Max Mustermann
'
);
return
test_utils
.
waitUntil
(()
=>
$
(
view
.
el
).
find
(
'
.chat-msg
__author:last
'
).
text
().
trim
()
===
'
**Max Mustermann
'
);
}).
then
(
function
()
{
expect
(
$
(
view
.
el
).
find
(
'
.chat-msg
-
text:last
'
).
text
()).
toBe
(
'
is as well
'
);
expect
(
$
(
view
.
el
).
find
(
'
.chat-msg:last
'
).
hasClass
(
'
chat-msg-followup
'
)).
toBe
(
false
);
expect
(
$
(
view
.
el
).
find
(
'
.chat-msg
__
text:last
'
).
text
()).
toBe
(
'
is as well
'
);
expect
(
$
(
view
.
el
).
find
(
'
.chat-msg:last
'
).
hasClass
(
'
chat-msg-
-
followup
'
)).
toBe
(
false
);
// Check that /me messages after a normal message don't
// get the 'chat-msg-followup' class.
// get the 'chat-msg-
-
followup' class.
message
=
'
This a normal message
'
;
test_utils
.
sendMessage
(
view
,
message
);
let
message_el
=
view
.
el
.
querySelector
(
'
.message:last-child
'
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
message_el
)).
toBeFalsy
();
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
message_el
)).
toBeFalsy
();
message
=
'
/me wrote a 3rd person message
'
;
test_utils
.
sendMessage
(
view
,
message
);
message_el
=
view
.
el
.
querySelector
(
'
.message:last-child
'
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-action
'
).
length
).
toBe
(
3
);
expect
(
$
(
view
.
el
).
find
(
'
.chat-msg
-
text:last
'
).
text
()).
toBe
(
'
wrote a 3rd person message
'
);
expect
(
$
(
view
.
el
).
find
(
'
.chat-msg
-
author:last
'
).
is
(
'
:visible
'
)).
toBeTruthy
();
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
message_el
)).
toBeFalsy
();
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-
msg--
action
'
).
length
).
toBe
(
3
);
expect
(
$
(
view
.
el
).
find
(
'
.chat-msg
__
text:last
'
).
text
()).
toBe
(
'
wrote a 3rd person message
'
);
expect
(
$
(
view
.
el
).
find
(
'
.chat-msg
__
author:last
'
).
is
(
'
:visible
'
)).
toBeTruthy
();
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
message_el
)).
toBeFalsy
();
done
();
});
});
...
...
@@ -1627,7 +1627,7 @@
return
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
length
;
},
1000
).
then
(
function
()
{
expect
(
view
.
model
.
sendMessage
).
toHaveBeenCalled
();
var
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
-
text
'
);
var
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
__
text
'
);
expect
(
msg
.
html
()).
toEqual
(
'
<a target="_blank" rel="noopener" href="https://www.openstreetmap.org/?mlat=37.786971&
'
+
'
mlon=-122.399677#map=18/37.786971/-122.399677">https://www.openstreetmap.org/?mlat=37.7869
'
+
...
...
spec/chatroom.js
View file @
acd9a186
...
...
@@ -867,8 +867,8 @@
'
type
'
:
'
groupchat
'
}).
c
(
'
body
'
).
t
(
message
).
tree
();
view
.
model
.
onMessage
(
msg
);
expect
(
_
.
includes
(
$
(
view
.
el
).
find
(
'
.chat-msg
-
author
'
).
text
(),
'
**Dyon van de Wege
'
)).
toBeTruthy
();
expect
(
$
(
view
.
el
).
find
(
'
.chat-msg
-
text
'
).
text
()).
toBe
(
'
is tired
'
);
expect
(
_
.
includes
(
$
(
view
.
el
).
find
(
'
.chat-msg
__
author
'
).
text
(),
'
**Dyon van de Wege
'
)).
toBeTruthy
();
expect
(
$
(
view
.
el
).
find
(
'
.chat-msg
__
text
'
).
text
()).
toBe
(
'
is tired
'
);
message
=
'
/me is as well
'
;
msg
=
$msg
({
...
...
@@ -878,8 +878,8 @@
type
:
'
groupchat
'
}).
c
(
'
body
'
).
t
(
message
).
tree
();
view
.
model
.
onMessage
(
msg
);
expect
(
_
.
includes
(
$
(
view
.
el
).
find
(
'
.chat-msg
-
author:last
'
).
text
(),
'
**Max Mustermann
'
)).
toBeTruthy
();
expect
(
$
(
view
.
el
).
find
(
'
.chat-msg
-
text:last
'
).
text
()).
toBe
(
'
is as well
'
);
expect
(
_
.
includes
(
$
(
view
.
el
).
find
(
'
.chat-msg
__
author:last
'
).
text
(),
'
**Max Mustermann
'
)).
toBeTruthy
();
expect
(
$
(
view
.
el
).
find
(
'
.chat-msg
__
text:last
'
).
text
()).
toBe
(
'
is as well
'
);
done
();
});
}));
...
...
@@ -1545,7 +1545,7 @@
view
.
model
.
onMessage
(
message
.
nodeTree
);
var
$chat_content
=
$
(
view
.
el
).
find
(
'
.chat-content
'
);
expect
(
$chat_content
.
find
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
$chat_content
.
find
(
'
.chat-msg
-
text
'
).
text
()).
toBe
(
text
);
expect
(
$chat_content
.
find
(
'
.chat-msg
__
text
'
).
text
()).
toBe
(
text
);
expect
(
_converse
.
emit
).
toHaveBeenCalledWith
(
'
message
'
,
jasmine
.
any
(
Object
));
done
();
});
...
...
@@ -1583,7 +1583,7 @@
}).
c
(
'
body
'
).
t
(
text
);
view
.
model
.
onMessage
(
message
.
nodeTree
);
expect
(
$chat_content
.
find
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
$chat_content
.
find
(
'
.chat-msg
-
text
'
).
last
().
text
()).
toBe
(
text
);
expect
(
$chat_content
.
find
(
'
.chat-msg
__
text
'
).
last
().
text
()).
toBe
(
text
);
// We don't emit an event if it's our own message
expect
(
_converse
.
emit
.
calls
.
count
(),
1
);
done
();
...
...
@@ -1624,7 +1624,7 @@
// Now check that the message appears inside the chatbox in the DOM
var
$chat_content
=
$
(
view
.
el
).
find
(
'
.chat-content
'
);
var
msg_txt
=
$chat_content
.
find
(
'
.chat-msg:last
'
).
find
(
'
.chat-msg
-
text
'
).
text
();
var
msg_txt
=
$chat_content
.
find
(
'
.chat-msg:last
'
).
find
(
'
.chat-msg
__
text
'
).
text
();
expect
(
msg_txt
).
toEqual
(
message
);
expect
(
view
.
content
.
scrollTop
).
toBe
(
0
);
done
();
...
...
@@ -3475,7 +3475,7 @@
var
messages
=
view
.
el
.
querySelectorAll
(
'
.message
'
);
expect
(
messages
.
length
).
toBe
(
8
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg
-
text
'
).
textContent
).
toBe
(
'
hello world
'
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg
__
text
'
).
textContent
).
toBe
(
'
hello world
'
);
// Test that the composing notifications get removed
// via timeout.
...
...
spec/http-file-upload.js
View file @
acd9a186
...
...
@@ -364,7 +364,7 @@
},
1000
);
}).
then
(
function
()
{
// Check that the image renders
expect
(
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg
-
media
'
).
innerHTML
.
trim
()).
toEqual
(
expect
(
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg
__
media
'
).
innerHTML
.
trim
()).
toEqual
(
'
<!-- src/templates/image.html -->
\n
'
+
'
<a href="http://localhost:8000/logo/conversejs-filled.svg" target="_blank" rel="noopener">
'
+
'
<img class="chat-image img-thumbnail" src="http://localhost:8000/logo/conversejs-filled.svg">
'
+
...
...
@@ -472,7 +472,7 @@
},
1000
);
}).
then
(
function
()
{
// Check that the image renders
expect
(
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg
-
media
'
).
innerHTML
.
trim
()).
toEqual
(
expect
(
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg
__
media
'
).
innerHTML
.
trim
()).
toEqual
(
'
<!-- src/templates/image.html -->
\n
'
+
'
<a href="http://localhost:8000/logo/conversejs-filled.svg" target="_blank" rel="noopener">
'
+
'
<img class="chat-image img-thumbnail" src="http://localhost:8000/logo/conversejs-filled.svg"></a>
'
)
...
...
@@ -683,7 +683,7 @@
expect
(
view
.
el
.
querySelector
(
'
.chat-content progress
'
).
getAttribute
(
'
value
'
)).
toBe
(
'
0.5
'
);
message
.
set
(
'
progress
'
,
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-content progress
'
).
getAttribute
(
'
value
'
)).
toBe
(
'
1
'
);
expect
(
view
.
el
.
querySelector
(
'
.chat-content .chat-msg
-
text
'
).
textContent
).
toBe
(
'
Uploading file: my-juliet.jpg, 22.91 KB
'
);
expect
(
view
.
el
.
querySelector
(
'
.chat-content .chat-msg
__
text
'
).
textContent
).
toBe
(
'
Uploading file: my-juliet.jpg, 22.91 KB
'
);
done
();
});
var
sent_stanza
;
...
...
spec/messages.js
View file @
acd9a186
...
...
@@ -45,7 +45,7 @@
keyCode
:
13
// Enter
});
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg
-
text
'
).
textContent
)
expect
(
view
.
el
.
querySelector
(
'
.chat-msg
__
text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
const
first_msg
=
view
.
model
.
messages
.
findWhere
({
'
message
'
:
'
But soft, what light through yonder airlock breaks?
'
});
...
...
@@ -152,11 +152,11 @@
expect
(
textarea
.
value
).
toBe
(
''
);
const
messages
=
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
);
expect
(
messages
.
length
).
toBe
(
3
);
expect
(
messages
[
0
].
querySelector
(
'
.chat-msg
-
text
'
).
textContent
)
expect
(
messages
[
0
].
querySelector
(
'
.chat-msg
__
text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder window breaks?
'
);
expect
(
messages
[
1
].
querySelector
(
'
.chat-msg
-
text
'
).
textContent
)
expect
(
messages
[
1
].
querySelector
(
'
.chat-msg
__
text
'
).
textContent
)
.
toBe
(
'
It is the east, and Juliet is the sun.
'
);
expect
(
messages
[
2
].
querySelector
(
'
.chat-msg
-
text
'
).
textContent
)
expect
(
messages
[
2
].
querySelector
(
'
.chat-msg
__
text
'
).
textContent
)
.
toBe
(
'
Arise, fair sun, and kill the envious moon
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBeFalsy
();
...
...
@@ -209,11 +209,11 @@
expect
(
msg_obj
.
get
(
'
is_delayed
'
)).
toEqual
(
false
);
// Now check that the message appears inside the chatbox in the DOM
const
chat_content
=
chatboxview
.
el
.
querySelector
(
'
.chat-content
'
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg .chat-msg
-
text
'
).
textContent
).
toEqual
(
message
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg
-
time
'
).
textContent
.
match
(
/^
[
0-9
][
0-9
]
:
[
0-9
][
0-9
]
/
)).
toBeTruthy
();
expect
(
chat_content
.
querySelector
(
'
.chat-msg .chat-msg
__
text
'
).
textContent
).
toEqual
(
message
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg
__
time
'
).
textContent
.
match
(
/^
[
0-9
][
0-9
]
:
[
0-9
][
0-9
]
/
)).
toBeTruthy
();
return
test_utils
.
waitUntil
(()
=>
chatbox
.
vcard
.
get
(
'
fullname
'
)
===
mock
.
cur_names
[
0
])
.
then
(
function
()
{
expect
(
chat_content
.
querySelector
(
'
span.chat-msg
-
author
'
).
textContent
.
trim
()).
toBe
(
'
Max Frankfurter
'
);
expect
(
chat_content
.
querySelector
(
'
span.chat-msg
__
author
'
).
textContent
.
trim
()).
toBe
(
'
Max Frankfurter
'
);
done
();
});
});
...
...
@@ -240,7 +240,7 @@
var
chatboxview
=
_converse
.
chatboxviews
.
get
(
sender_jid
);
expect
(
chatboxview
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
chatboxview
.
el
.
querySelector
(
'
.chat-msg
-
text
'
).
textContent
)
expect
(
chatboxview
.
el
.
querySelector
(
'
.chat-msg
__
text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
_converse
.
chatboxes
.
onMessage
(
$msg
({
...
...
@@ -251,11 +251,11 @@
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder chimney breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
test_utils
.
waitUntil
(()
=>
chatboxview
.
el
.
querySelector
(
'
.chat-msg
-
text
'
).
textContent
===
test_utils
.
waitUntil
(()
=>
chatboxview
.
el
.
querySelector
(
'
.chat-msg
__
text
'
).
textContent
===
'
But soft, what light through yonder chimney breaks?
'
).
then
(()
=>
{
expect
(
chatboxview
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
chatboxview
.
el
.
querySelectorAll
(
'
.chat-msg
-
content .fa-edit
'
).
length
).
toBe
(
1
);
expect
(
chatboxview
.
el
.
querySelectorAll
(
'
.chat-msg
__
content .fa-edit
'
).
length
).
toBe
(
1
);
_converse
.
chatboxes
.
onMessage
(
$msg
({
'
from
'
:
sender_jid
,
...
...
@@ -265,12 +265,12 @@
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder window breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
return
test_utils
.
waitUntil
(()
=>
chatboxview
.
el
.
querySelector
(
'
.chat-msg
-
text
'
).
textContent
===
return
test_utils
.
waitUntil
(()
=>
chatboxview
.
el
.
querySelector
(
'
.chat-msg
__
text
'
).
textContent
===
'
But soft, what light through yonder window breaks?
'
);
}).
then
(()
=>
{
expect
(
chatboxview
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
chatboxview
.
el
.
querySelectorAll
(
'
.chat-msg
-
content .fa-edit
'
).
length
).
toBe
(
1
);
chatboxview
.
el
.
querySelector
(
'
.chat-msg
-
content .fa-edit
'
).
click
();
expect
(
chatboxview
.
el
.
querySelectorAll
(
'
.chat-msg
__
content .fa-edit
'
).
length
).
toBe
(
1
);
chatboxview
.
el
.
querySelector
(
'
.chat-msg
__
content .fa-edit
'
).
click
();
const
modal
=
chatboxview
.
model
.
messages
.
at
(
0
).
message_versions_modal
;
return
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
);
}).
then
(()
=>
{
...
...
@@ -324,7 +324,7 @@
expect
(
chatbox
).
toBeDefined
();
expect
(
chatboxview
).
toBeDefined
();
var
author_el
=
chatboxview
.
el
.
querySelector
(
'
.chat-msg
-
author
'
);
var
author_el
=
chatboxview
.
el
.
querySelector
(
'
.chat-msg
__
author
'
);
expect
(
chatbox
.
get
(
'
fullname
'
)
===
sender_jid
);
expect
(
_
.
includes
(
author_el
.
textContent
.
trim
(),
'
max.frankfurter@localhost
'
)).
toBeTruthy
();
...
...
@@ -333,7 +333,7 @@
expect
(
_converse
.
api
.
vcard
.
get
).
toHaveBeenCalled
();
return
test_utils
.
waitUntil
(()
=>
chatbox
.
vcard
.
get
(
'
fullname
'
)
===
mock
.
cur_names
[
0
])
}).
then
(
function
()
{
var
author_el
=
chatboxview
.
el
.
querySelector
(
'
.chat-msg
-
author
'
);
var
author_el
=
chatboxview
.
el
.
querySelector
(
'
.chat-msg
__
author
'
);
expect
(
_
.
includes
(
author_el
.
textContent
.
trim
(),
'
Max Frankfurter
'
)).
toBeTruthy
();
done
();
});
...
...
@@ -389,9 +389,9 @@
expect
(
msg_obj
.
get
(
'
is_delayed
'
)).
toEqual
(
false
);
// Now check that the message appears inside the chatbox in the DOM
var
chat_content
=
chatboxview
.
el
.
querySelector
(
'
.chat-content
'
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg .chat-msg
-
text
'
).
textContent
).
toEqual
(
message
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg
-
time
'
).
textContent
.
match
(
/^
[
0-9
][
0-9
]
:
[
0-9
][
0-9
]
/
)).
toBeTruthy
();
expect
(
chat_content
.
querySelector
(
'
span.chat-msg
-
author
'
).
textContent
.
trim
()).
toBe
(
'
max.frankfurter@localhost
'
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg .chat-msg
__
text
'
).
textContent
).
toEqual
(
message
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg
__
time
'
).
textContent
.
match
(
/^
[
0-9
][
0-9
]
:
[
0-9
][
0-9
]
/
)).
toBeTruthy
();
expect
(
chat_content
.
querySelector
(
'
span.chat-msg
__
author
'
).
textContent
.
trim
()).
toBe
(
'
max.frankfurter@localhost
'
);
done
();
}));
});
...
...
@@ -436,7 +436,7 @@
});
view
.
model
.
sendMessage
(
message
);
var
$chat_content
=
$
(
view
.
el
).
find
(
'
.chat-content
'
);
var
msg_txt
=
$chat_content
.
find
(
'
.chat-msg:last
'
).
find
(
'
.chat-msg
-
text
'
).
text
();
var
msg_txt
=
$chat_content
.
find
(
'
.chat-msg:last
'
).
find
(
'
.chat-msg
__
text
'
).
text
();
expect
(
msg_txt
).
toEqual
(
msg_text
);
// We send another message, for which an error will
...
...
@@ -451,7 +451,7 @@
'
message
'
:
msg_text
});
view
.
model
.
sendMessage
(
message
);
msg_txt
=
$chat_content
.
find
(
'
.chat-msg:last
'
).
find
(
'
.chat-msg
-
text
'
).
text
();
msg_txt
=
$chat_content
.
find
(
'
.chat-msg:last
'
).
find
(
'
.chat-msg
__
text
'
).
text
();
expect
(
msg_txt
).
toEqual
(
msg_text
);
/* <message xmlns="jabber:client"
...
...
@@ -571,7 +571,7 @@
// Now check that the message appears inside the chatbox in the DOM
var
$chat_content
=
$
(
chatboxview
.
el
).
find
(
'
.chat-content
'
);
var
msg_txt
=
$chat_content
.
find
(
'
.chat-msg:last
'
).
find
(
'
.chat-msg
-
text
'
).
text
();
var
msg_txt
=
$chat_content
.
find
(
'
.chat-msg:last
'
).
find
(
'
.chat-msg
__
text
'
).
text
();
expect
(
msg_txt
).
toEqual
(
message
);
return
test_utils
.
waitUntil
(
function
()
{
return
u
.
isVisible
(
chatboxview
.
el
.
querySelector
(
'
.new-msgs-indicator
'
));
...
...
@@ -634,7 +634,7 @@
expect
(
_converse
.
chatboxes
.
getChatBox
).
toHaveBeenCalled
();
var
chatboxview
=
_converse
.
chatboxviews
.
get
(
sender_jid
);
var
$chat_content
=
$
(
chatboxview
.
el
).
find
(
'
.chat-content:last
'
);
var
msg_txt
=
$chat_content
.
find
(
'
.chat-msg
'
).
find
(
'
.chat-msg
-
text
'
).
text
();
var
msg_txt
=
$chat_content
.
find
(
'
.chat-msg
'
).
find
(
'
.chat-msg
__
text
'
).
text
();
expect
(
msg_txt
).
toEqual
(
message
);
done
();
});
...
...
@@ -781,10 +781,10 @@
expect
(
$time
.
text
()).
toEqual
(
'
Sunday Dec 31st 2017
'
)
$day
=
$chat_content
.
find
(
'
.date-separator:first
'
);
expect
(
$day
[
0
].
nextElementSibling
.
querySelector
(
'
.chat-msg
-
text
'
).
textContent
).
toBe
(
'
Older message
'
);
expect
(
$day
[
0
].
nextElementSibling
.
querySelector
(
'
.chat-msg
__
text
'
).
textContent
).
toBe
(
'
Older message
'
);
var
$el
=
$chat_content
.
find
(
'
.chat-msg:first
'
).
find
(
'
.chat-msg
-
text
'
)
expect
(
$el
.
hasClass
(
'
chat-msg-followup
'
)).
toBe
(
false
);
var
$el
=
$chat_content
.
find
(
'
.chat-msg:first
'
).
find
(
'
.chat-msg
__
text
'
)
expect
(
$el
.
hasClass
(
'
chat-msg-
-
followup
'
)).
toBe
(
false
);
expect
(
$el
.
text
()).
toEqual
(
'
Older message
'
);
$time
=
$chat_content
.
find
(
'
time.separator-text:eq(1)
'
);
...
...
@@ -792,35 +792,35 @@
$day
=
$chat_content
.
find
(
'
.date-separator:eq(1)
'
);
expect
(
$day
.
data
(
'
isodate
'
)).
toEqual
(
moment
(
'
2018-01-01T00:00:00
'
).
format
());
expect
(
$day
[
0
].
nextElementSibling
.
querySelector
(
'
.chat-msg
-
text
'
).
textContent
).
toBe
(
'
Inbetween message
'
);
expect
(
$day
[
0
].
nextElementSibling
.
querySelector
(
'
.chat-msg
__
text
'
).
textContent
).
toBe
(
'
Inbetween message
'
);
$el
=
$chat_content
.
find
(
'
.chat-msg:eq(1)
'
);
expect
(
$el
.
find
(
'
.chat-msg
-
text
'
).
text
()).
toEqual
(
'
Inbetween message
'
);
expect
(
$el
[
0
].
nextElementSibling
.
querySelector
(
'
.chat-msg
-
text
'
).
textContent
).
toEqual
(
'
another inbetween message
'
);
expect
(
$el
.
find
(
'
.chat-msg
__
text
'
).
text
()).
toEqual
(
'
Inbetween message
'
);
expect
(
$el
[
0
].
nextElementSibling
.
querySelector
(
'
.chat-msg
__
text
'
).
textContent
).
toEqual
(
'
another inbetween message
'
);
$el
=
$chat_content
.
find
(
'
.chat-msg:eq(2)
'
);
expect
(
$el
.
find
(
'
.chat-msg
-
text
'
).
text
()).
toEqual
(
'
another inbetween message
'
);
expect
(
$el
.
hasClass
(
'
chat-msg-followup
'
)).
toBe
(
true
);
expect
(
$el
.
find
(
'
.chat-msg
__
text
'
).
text
()).
toEqual
(
'
another inbetween message
'
);
expect
(
$el
.
hasClass
(
'
chat-msg-
-
followup
'
)).
toBe
(
true
);
$time
=
$chat_content
.
find
(
'
time.separator-text:nth(2)
'
);
expect
(
$time
.
text
()).
toEqual
(
"
Tuesday Jan 2nd 2018
"
);
$day
=
$chat_content
.
find
(
'
.date-separator:nth(2)
'
);
expect
(
$day
.
data
(
'
isodate
'
)).
toEqual
(
moment
(
'
2018-01-02T00:00:00
'
).
format
());
expect
(
$day
[
0
].
nextElementSibling
.
querySelector
(
'
.chat-msg
-
text
'
).
textContent
).
toBe
(
'
An earlier message on the next day
'
);
expect
(
$day
[
0
].
nextElementSibling
.
querySelector
(
'
.chat-msg
__
text
'
).
textContent
).
toBe
(
'
An earlier message on the next day
'
);
$el
=
$chat_content
.
find
(
'
.chat-msg:eq(3)
'
);
expect
(
$el
.
find
(
'
.chat-msg
-
text
'
).
text
()).
toEqual
(
'
An earlier message on the next day
'
);
expect
(
$el
.
hasClass
(
'
chat-msg-followup
'
)).
toBe
(
false
);
expect
(
$el
.
find
(
'
.chat-msg
__
text
'
).
text
()).
toEqual
(
'
An earlier message on the next day
'
);
expect
(
$el
.
hasClass
(
'
chat-msg-
-
followup
'
)).
toBe
(
false
);
$el
=
$chat_content
.
find
(
'
.chat-msg:eq(4)
'
);
expect
(
$el
.
find
(
'
.chat-msg
-
text
'
).
text
()).
toEqual
(
'
message
'
);
expect
(
$el
[
0
].
nextElementSibling
.
querySelector
(
'
.chat-msg
-
text
'
).
textContent
).
toEqual
(
'
newer message from the next day
'
);
expect
(
$el
.
hasClass
(
'
chat-msg-followup
'
)).
toBe
(
false
);
expect
(
$el
.
find
(
'
.chat-msg
__
text
'
).
text
()).
toEqual
(
'
message
'
);
expect
(
$el
[
0
].
nextElementSibling
.
querySelector
(
'
.chat-msg
__
text
'
).
textContent
).
toEqual
(
'
newer message from the next day
'
);
expect
(
$el
.
hasClass
(
'
chat-msg-
-
followup
'
)).
toBe
(
false
);
$day
=
$chat_content
.
find
(
'
.date-separator:last
'
);
expect
(
$day
.
data
(
'
isodate
'
)).
toEqual
(
moment
().
startOf
(
'
day
'
).
format
());
expect
(
$day
[
0
].
nextElementSibling
.
querySelector
(
'
.chat-msg
-
text
'
).
textContent
).
toBe
(
'
latest message
'
);
expect
(
$el
.
hasClass
(
'
chat-msg-followup
'
)).
toBe
(
false
);
expect
(
$day
[
0
].
nextElementSibling
.
querySelector
(
'
.chat-msg
__
text
'
).
textContent
).
toBe
(
'
latest message
'
);
expect
(
$el
.
hasClass
(
'
chat-msg-
-
followup
'
)).
toBe
(
false
);
done
();
});
}));
...
...
@@ -839,7 +839,7 @@
sinon
.
spy
(
_converse
,
'
log
'
);
sinon
.
spy
(
_converse
.
chatboxes
,
'
getChatBox
'
);
sinon
.
spy
(
u
,
'
isHeadlineMessage
'
);
var
msg
=
$msg
({
const
msg
=
$msg
({
from
:
'
localhost
'
,
to
:
_converse
.
bare_jid
,
type
:
'
chat
'
,
...
...
@@ -902,12 +902,12 @@
expect
(
msg_obj
.
get
(
'
sender
'
)).
toEqual
(
'
them
'
);
expect
(
msg_obj
.
get
(
'
is_delayed
'
)).
toEqual
(
false
);
// Now check that the message appears inside the chatbox in the DOM
var
chat_content
=
chatboxview
.
el
.
querySelector
(
'
.chat-content
'
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg .chat-msg
-
text
'
).
textContent
).
toEqual
(
msgtext
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg
-
time
'
).
textContent
.
match
(
/^
[
0-9
][
0-9
]
:
[
0-9
][
0-9
]
/
)).
toBeTruthy
();
const
chat_content
=
chatboxview
.
el
.
querySelector
(
'
.chat-content
'
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg .chat-msg
__
text
'
).
textContent
).
toEqual
(
msgtext
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg
__
time
'
).
textContent
.
match
(
/^
[
0-9
][
0-9
]
:
[
0-9
][
0-9
]
/
)).
toBeTruthy
();
return
test_utils
.
waitUntil
(()
=>
chatbox
.
vcard
.
get
(
'
fullname
'
)
===
'
Candice van der Knijff
'
)
.
then
(
function
()
{
expect
(
chat_content
.
querySelector
(
'
span.chat-msg
-
author
'
).
textContent
.
trim
()).
toBe
(
'
Candice van der Knijff
'
);
expect
(
chat_content
.
querySelector
(
'
span.chat-msg
__
author
'
).
textContent
.
trim
()).
toBe
(
'
Candice van der Knijff
'
);
done
();
});
}));
...
...
@@ -917,16 +917,15 @@
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
var
contact
,
sent_stanza
,
IQ_id
,
stanza
;
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
'
localhost
'
,
[],
[
'
vcard-temp
'
]).
then
(
function
()
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
test_utils
.
openControlBox
();
// Send a message from a different resource
spyOn
(
_converse
,
'
log
'
);
var
msgtext
=
'
This is a sent carbon message
'
;
var
recipient_jid
=
mock
.
cur_names
[
5
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
var
msg
=
$msg
({
const
msgtext
=
'
This is a sent carbon message
'
;
const
recipient_jid
=
mock
.
cur_names
[
5
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
const
msg
=
$msg
({
'
from
'
:
_converse
.
bare_jid
,
'
id
'
:
(
new
Date
()).
getTime
(),
'
to
'
:
_converse
.
connection
.
jid
,
...
...
@@ -943,20 +942,19 @@
_converse
.
chatboxes
.
onMessage
(
msg
);
// Check that the chatbox and its view now exist
var
chatbox
=
_converse
.
chatboxes
.
get
(
recipient_jid
);
var
chatboxview
=
_converse
.
chatboxviews
.
get
(
recipient_jid
);
const
chatbox
=
_converse
.
chatboxes
.
get
(
recipient_jid
);
const
chatboxview
=
_converse
.
chatboxviews
.
get
(
recipient_jid
);
expect
(
chatbox
).
toBeDefined
();
expect
(
chatboxview
).
toBeDefined
();
// Check that the message was received and check the message parameters
expect
(
chatbox
.
messages
.
length
).
toEqual
(
1
);
var
msg_obj
=
chatbox
.
messages
.
models
[
0
];
const
msg_obj
=
chatbox
.
messages
.
models
[
0
];
expect
(
msg_obj
.
get
(
'
message
'
)).
toEqual
(
msgtext
);
expect
(
msg_obj
.
get
(
'
fullname
'
)).
toEqual
(
_converse
.
xmppstatus
.
get
(
'
fullname
'
));
expect
(
msg_obj
.
get
(
'
sender
'
)).
toEqual
(
'
me
'
);
expect
(
msg_obj
.
get
(
'
is_delayed
'
)).
toEqual
(
false
);
// Now check that the message appears inside the chatbox in the DOM
var
$chat_content
=
$
(
chatboxview
.
el
).
find
(
'
.chat-content
'
);
var
msg_txt
=
$chat_content
.
find
(
'
.chat-msg
'
).
find
(
'
.chat-msg-text
'
).
text
();
const
msg_txt
=
chatboxview
.
el
.
querySelector
(
'
.chat-content .chat-msg .chat-msg__text
'
).
textContent
;
expect
(
msg_txt
).
toEqual
(
msgtext
);
done
();
});
...
...
@@ -1014,6 +1012,9 @@
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
if
(
_converse
.
view_mode
===
'
fullscreen
'
)
{
return
done
();
}
test_utils
.
createContacts
(
_converse
,
'
current
'
);
test_utils
.
openControlBox
();
test_utils
.
waitUntil
(
function
()
{
...
...
@@ -1089,7 +1090,6 @@
var
message
=
'
This is a day old message
'
;
var
chatbox
=
_converse
.
chatboxes
.
get
(
contact_jid
);
var
chatboxview
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
var
$chat_content
=
$
(
chatboxview
.
el
).
find
(
'
.chat-content
'
);
var
msg_obj
;
var
msg_txt
;
var
sender_txt
;
...
...
@@ -1113,16 +1113,17 @@
return
test_utils
.
waitUntil
(()
=>
chatbox
.
vcard
.
get
(
'
fullname
'
)
===
'
Candice van der Knijff
'
)
.
then
(
function
()
{
var
chat_content
=
chatboxview
.
el
.
querySelector
(
'
.chat-content
'
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg .chat-msg
-
text
'
).
textContent
).
toEqual
(
message
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg
-
time
'
).
textContent
.
match
(
/^
[
0-9
][
0-9
]
:
[
0-9
][
0-9
]
/
)).
toBeTruthy
();
expect
(
chat_content
.
querySelector
(
'
span.chat-msg
-
author
'
).
textContent
.
trim
()).
toBe
(
'
Candice van der Knijff
'
);
const
chat_content
=
chatboxview
.
el
.
querySelector
(
'
.chat-content
'
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg .chat-msg
__
text
'
).
textContent
).
toEqual
(
message
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg
__
time
'
).
textContent
.
match
(
/^
[
0-9
][
0-9
]
:
[
0-9
][
0-9
]
/
)).
toBeTruthy
();
expect
(
chat_content
.
querySelector
(
'
span.chat-msg
__
author
'
).
textContent
.
trim
()).
toBe
(
'
Candice van der Knijff
'
);
var
$day
=
$chat_content
.
find
(
'
.date-separator
'
);
expect
(
$day
.
length
).
toEqual
(
1
);
expect
(
$day
.
attr
(
'
class
'
)).
toEqual
(
'
message date-separator
'
);
expect
(
$day
.
data
(
'
isodate
'
)).
toEqual
(
moment
(
one_day_ago
.
startOf
(
'
day
'
)).
format
());
expect
(
chat_content
.
querySelectorAll
(
'
.date-separator
'
).
length
).
toEqual
(
1
);
const
day
=
chat_content
.
querySelector
(
'
.date-separator
'
);
expect
(
day
.
getAttribute
(
'
class
'
)).
toEqual
(
'
message date-separator
'
);
expect
(
day
.
getAttribute
(
'
data-
isodate
'
)).
toEqual
(
moment
(
one_day_ago
.
startOf
(
'
day
'
)).
format
());
const
$chat_content
=
$
(
chat_content
);
var
$time
=
$chat_content
.
find
(
'
time.separator-text
'
);
expect
(
$time
.
text
()).
toEqual
(
moment
(
one_day_ago
.
startOf
(
'
day
'
)).
format
(
"
dddd MMM Do YYYY
"
));
...
...
@@ -1141,7 +1142,7 @@
expect
(
$chat_content
[
0
].
querySelectorAll
(
'
time.separator-text
'
).
length
).
toEqual
(
2
);
// There are now two time elements
var
message_date
=
new
Date
();
$day
=
$chat_content
.
find
(
'
.date-separator:last
'
);
const
$day
=
$chat_content
.
find
(
'
.date-separator:last
'
);
expect
(
$day
.
length
).
toEqual
(
1
);
expect
(
$day
.
attr
(
'
class
'
)).
toEqual
(
'
message date-separator
'
);
expect
(
$day
.
data
(
'
isodate
'
)).
toEqual
(
moment
(
message_date
).
startOf
(
'
day
'
).
format
());
...
...
@@ -1156,12 +1157,12 @@
expect
(
msg_obj
.
get
(
'
fullname
'
)).
toEqual
(
contact_name
);
expect
(
msg_obj
.
get
(
'
sender
'
)).
toEqual
(
'
them
'
);
expect
(
msg_obj
.
get
(
'
is_delayed
'
)).
toEqual
(
false
);
msg_txt
=
$chat_content
.
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
-
text
'
).
text
();
msg_txt
=
$chat_content
.
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
__
text
'
).
text
();
expect
(
msg_txt
).
toEqual
(
message
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg:last-child .chat-msg
-
text
'
).
textContent
).
toEqual
(
message
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg:last-child .chat-msg
-
time
'
).
textContent
.
match
(
/^
[
0-9
][
0-9
]
:
[
0-9
][
0-9
]
/
)).
toBeTruthy
();
expect
(
chat_content
.
querySelector
(
'
.chat-msg:last-child .chat-msg
-
author
'
).
textContent
.
trim
()).
toBe
(
'
Candice van der Knijff
'
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg:last-child .chat-msg
__
text
'
).
textContent
).
toEqual
(
message
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg:last-child .chat-msg
__
time
'
).
textContent
.
match
(
/^
[
0-9
][
0-9
]
:
[
0-9
][
0-9
]
/
)).
toBeTruthy
();
expect
(
chat_content
.
querySelector
(
'
.chat-msg:last-child .chat-msg
__
author
'
).
textContent
.
trim
()).
toBe
(
'
Candice van der Knijff
'
);
done
();
});
});
...
...
@@ -1186,7 +1187,7 @@
expect
(
view
.
model
.
sendMessage
).
toHaveBeenCalled
();
expect
(
view
.
model
.
messages
.
length
,
2
);
expect
(
_converse
.
emit
.
calls
.
mostRecent
().
args
,
[
'
messageSend
'
,
message
]);
expect
(
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
-
text
'
).
text
()).
toEqual
(
message
);
expect
(
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
__
text
'
).
text
()).
toEqual
(
message
);
done
();
}));
...
...
@@ -1205,7 +1206,7 @@
spyOn
(
view
.
model
,
'
sendMessage
'
).
and
.
callThrough
();
test_utils
.
sendMessage
(
view
,
message
);
expect
(
view
.
model
.
sendMessage
).
toHaveBeenCalled
();
var
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
-
text
'
);
var
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
__
text
'
);
expect
(
msg
.
text
()).
toEqual
(
message
);
expect
(
msg
.
html
()).
toEqual
(
'
<p>This message contains <em>some</em> <b>markup</b></p>
'
);
done
();
...
...
@@ -1226,7 +1227,7 @@
spyOn
(
view
.
model
,
'
sendMessage
'
).
and
.
callThrough
();
test_utils
.
sendMessage
(
view
,
message
);
expect
(
view
.
model
.
sendMessage
).
toHaveBeenCalled
();
var
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
-
text
'
);
var
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
__
text
'
);
expect
(
msg
.
text
()).
toEqual
(
message
);
expect
(
msg
.
html
()).
toEqual
(
'
This message contains a hyperlink: <a target="_blank" rel="noopener" href="http://www.opkode.com">www.opkode.com</a>
'
);
done
();
...
...
@@ -1248,14 +1249,14 @@
message
=
"
http://www.opkode.com/'onmouseover='alert(1)'whatever
"
;
test_utils
.
sendMessage
(
view
,
message
);
expect
(
view
.
model
.
sendMessage
).
toHaveBeenCalled
();
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
-
text
'
);
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
__
text
'
);
expect
(
msg
.
text
()).
toEqual
(
message
);
expect
(
msg
.
html
()).
toEqual
(
'
<a target="_blank" rel="noopener" href="http://www.opkode.com/%27onmouseover=%27alert%281%29%27whatever">http://www.opkode.com/
\'
onmouseover=
\'
alert(1)
\'
whatever</a>
'
);
message
=
'
http://www.opkode.com/"onmouseover="alert(1)"whatever
'
;
test_utils
.
sendMessage
(
view
,
message
);
expect
(
view
.
model
.
sendMessage
).
toHaveBeenCalled
();
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
-
text
'
);
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
__
text
'
);
expect
(
msg
.
text
()).
toEqual
(
message
);
expect
(
msg
.
html
()).
toEqual
(
'
<a target="_blank" rel="noopener" href="http://www.opkode.com/%22onmouseover=%22alert%281%29%22whatever">http://www.opkode.com/"onmouseover="alert(1)"whatever</a>
'
);
...
...
@@ -1263,7 +1264,7 @@
test_utils
.
sendMessage
(
view
,
message
);
expect
(
view
.
model
.
sendMessage
).
toHaveBeenCalled
();
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
-
text
'
);
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
__
text
'
);
expect
(
msg
.
text
()).
toEqual
(
message
);
expect
(
msg
.
html
()).
toEqual
(
'
<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Ender%27s_Game">
'
+
message
+
'
</a>
'
);
...
...
@@ -1271,7 +1272,7 @@
test_utils
.
sendMessage
(
view
,
message
);
expect
(
view
.
model
.
sendMessage
).
toHaveBeenCalled
();
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
-
text
'
);
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg
__
text
'
);
expect
(
msg
.
text
()).
toEqual
(
message
);
expect
(
msg
.
html
()).
toEqual
(
'
<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Ender%27s_Game">
'
+
message
+
'
</a>
'
);
done
();
...
...
@@ -1292,7 +1293,7 @@
const
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
const
chat_content
=
view
.
el
.
querySelector
(
'
.chat-content
'
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg
-
text
'
).
innerHTML
).
toBe
(
'
Hey<br>Have you heard the news?
'
);
expect
(
chat_content
.
querySelector
(
'
.chat-msg
__
text
'
).
innerHTML
).
toBe
(
'
Hey<br>Have you heard the news?
'
);
stanza
=
Strophe
.
xmlHtmlNode
(
"
<message from='
"
+
contact_jid
+
"
'
"
+
...
...
@@ -1301,7 +1302,7 @@
"
<body>Hey
\n\n\n
Have you heard the news?</body>
"
+
"
</message>
"
).
firstChild
;
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
expect
(
chat_content
.
querySelector
(
'
.message:last-child .chat-msg
-
text
'
).
innerHTML
).
toBe
(
'
Hey<br><br>Have you heard the news?
'
);
expect
(
chat_content
.
querySelector
(
'
.message:last-child .chat-msg
__
text
'
).
innerHTML
).
toBe
(
'
Hey<br><br>Have you heard the news?
'
);
stanza
=
Strophe
.
xmlHtmlNode
(
"
<message from='
"
+
contact_jid
+
"
'
"
+
...
...
@@ -1310,7 +1311,7 @@
"
<body>Hey
\n
Have you heard
\n
the news?</body>
"
+
"
</message>
"
).
firstChild
;
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
expect
(
chat_content
.
querySelector
(
'
.message:last-child .chat-msg
-
text
'
).
innerHTML
).
toBe
(
'
Hey<br>Have you heard<br>the news?
'
);
expect
(
chat_content
.
querySelector
(
'
.message:last-child .chat-msg
__
text
'
).
innerHTML
).
toBe
(
'
Hey<br>Have you heard<br>the news?
'
);
done
();
}));
...
...
@@ -1319,18 +1320,18 @@
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
var
base_url
=
document
.
URL
.
split
(
window
.
location
.
pathname
)[
0
];
var
message
=
base_url
+
"
/logo/conversejs-filled.svg
"
;
var
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
createContacts
(
_converse
,
'
current
'
,
1
);
const
base_url
=
document
.
URL
.
split
(
window
.
location
.
pathname
)[
0
];
let
message
=
base_url
+
"
/logo/conversejs-filled.svg
"
;
const
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
var
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
const
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
spyOn
(
view
.
model
,
'
sendMessage
'
).
and
.
callThrough
();
test_utils
.
sendMessage
(
view
,
message
);
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-content .chat-image
'
).
length
,
1000
).
then
(()
=>
{
expect
(
view
.
model
.
sendMessage
).
toHaveBeenCalled
();
var
msg
=
$
(
view
.
el
).
find
(
'
.chat-content .chat-msg
'
).
last
().
find
(
'
.chat-msg-
text
'
);
const
msg
=
$
(
view
.
el
).
find
(
'
.chat-content .chat-msg
'
).
last
().
find
(
'
.chat-msg__
text
'
);
expect
(
msg
.
html
().
trim
()).
toEqual
(
'
<!-- src/templates/image.html -->
\n
'
+
'
<a href="
'
+
base_url
+
'
/logo/conversejs-filled.svg" target="_blank" rel="noopener"><img class="chat-image img-thumbnail"
'
+
...
...
@@ -1340,7 +1341,7 @@
return
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-content .chat-image
'
).
length
===
2
,
1000
);
}).
then
(()
=>
{
expect
(
view
.
model
.
sendMessage
).
toHaveBeenCalled
();
var
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg-
text
'
);
const
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg__
text
'
);
expect
(
msg
.
html
().
trim
()).
toEqual
(
'
<!-- src/templates/image.html -->
\n
'
+
'
<a href="
'
+
base_url
+
'
/logo/conversejs-filled.svg?param1=val1&param2=val2" target="_blank" rel="noopener"><img
'
+
...
...
@@ -1352,7 +1353,7 @@
return
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-content .chat-image
'
).
length
===
4
,
1000
);
}).
then
(
function
()
{
expect
(
view
.
model
.
sendMessage
).
toHaveBeenCalled
();
var
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg-
text
'
);
const
msg
=
$
(
view
.
el
).
find
(
'
.chat-content
'
).
find
(
'
.chat-msg
'
).
last
().
find
(
'
.chat-msg__
text
'
);
expect
(
msg
[
0
].
textContent
.
trim
()).
toEqual
(
'
hello world
'
);
expect
(
msg
[
0
].
querySelectorAll
(
'
img
'
).
length
).
toEqual
(
2
);
done
();
...
...
@@ -1377,10 +1378,10 @@
expect
(
chatbox
.
messages
.
models
.
length
,
1
);
var
msg_object
=
chatbox
.
messages
.
models
[
0
];
var
msg_author
=
view
.
el
.
querySelector
(
'
.chat-content .chat-msg:last-child .chat-msg
-
author
'
);
var
msg_author
=
view
.
el
.
querySelector
(
'
.chat-content .chat-msg:last-child .chat-msg
__
author
'
);
expect
(
msg_author
.
textContent
.
trim
()).
toBe
(
'
Max Mustermann
'
);
var
msg_time
=
view
.
el
.
querySelector
(
'
.chat-content .chat-msg:last-child .chat-msg
-
time
'
);
var
msg_time
=
view
.
el
.
querySelector
(
'
.chat-content .chat-msg:last-child .chat-msg
__
time
'
);
var
time
=
moment
(
msg_object
.
get
(
'
time
'
)).
format
(
_converse
.
time_format
);
expect
(
msg_time
.
textContent
).
toBe
(
time
);
done
();
...
...
@@ -1394,7 +1395,7 @@
test_utils
.
createContacts
(
_converse
,
'
current
'
);
test_utils
.
openControlBox
();
test_utils
.
waitUntil
(()
=>
$
(
_converse
.
rosterview
.
el
).
find
(
'
.roster-group
'
).
length
,
300
)
test_utils
.
waitUntil
(()
=>
_converse
.
rosterview
.
el
.
querySelectorAll
(
'
.roster-group
'
).
length
,
300
)
.
then
(
function
()
{
const
base_time
=
new
Date
();
const
ONE_MINUTE_LATER
=
60000
;
...
...
@@ -1468,19 +1469,19 @@
var
chat_content
=
view
.
el
.
querySelector
(
'
.chat-content
'
);
expect
(
chat_content
.
querySelectorAll
(
'
.message
'
).
length
).
toBe
(
6
);
expect
(
chat_content
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
5
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(2)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(2) .chat-msg
-
text
'
).
textContent
).
toBe
(
"
A message
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(3)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(3) .chat-msg
-
text
'
).
textContent
).
toBe
(
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(2)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(2) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
A message
"
);
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(3)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(3) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
Another message 3 minutes later
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(4)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(4) .chat-msg
-
text
'
).
textContent
).
toBe
(
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(4)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(4) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
Another message 14 minutes since we started
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(5)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(5) .chat-msg
-
text
'
).
textContent
).
toBe
(
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(5)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(5) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
Another message 1 minute and 1 second since the previous one
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(6)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(6) .chat-msg
-
text
'
).
textContent
).
toBe
(
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(6)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(6) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
Another message within 10 minutes, but from a different person
"
);
// Let's add a delayed, inbetween message
...
...
@@ -1499,21 +1500,21 @@
expect
(
chat_content
.
querySelectorAll
(
'
.message
'
).
length
).
toBe
(
7
);
expect
(
chat_content
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
6
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(2)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(2) .chat-msg
-
text
'
).
textContent
).
toBe
(
"
A message
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(3)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(3) .chat-msg
-
text
'
).
textContent
).
toBe
(
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(2)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(2) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
A message
"
);
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(3)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(3) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
Another message 3 minutes later
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(4)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(4) .chat-msg
-
text
'
).
textContent
).
toBe
(
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(4)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(4) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
A delayed message, sent 5 minutes since we started
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(5)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(5) .chat-msg
-
text
'
).
textContent
).
toBe
(
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(5)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(5) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
Another message 14 minutes since we started
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(6)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(6) .chat-msg
-
text
'
).
textContent
).
toBe
(
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(6)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(6) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
Another message 1 minute and 1 second since the previous one
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(7)
'
))).
toBe
(
false
);
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(7)
'
))).
toBe
(
false
);
_converse
.
chatboxes
.
onMessage
(
$msg
({
'
id
'
:
'
aeb213
'
,
'
to
'
:
_converse
.
bare_jid
})
.
c
(
'
forwarded
'
,
{
'
xmlns
'
:
'
urn:xmpp:forward:0
'
})
...
...
@@ -1527,25 +1528,25 @@
.
tree
());
expect
(
chat_content
.
querySelectorAll
(
'
.message
'
).
length
).
toBe
(
8
);
expect
(
chat_content
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
7
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(2)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(2) .chat-msg
-
text
'
).
textContent
).
toBe
(
"
A message
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(3)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(3) .chat-msg
-
text
'
).
textContent
).
toBe
(
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(2)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(2) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
A message
"
);
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(3)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(3) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
Another message 3 minutes later
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(4)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(4) .chat-msg
-
text
'
).
textContent
).
toBe
(
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(4)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(4) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
A carbon message 4 minutes later
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(5)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(5) .chat-msg
-
text
'
).
textContent
).
toBe
(
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(5)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(5) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
A delayed message, sent 5 minutes since we started
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(6)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(6) .chat-msg
-
text
'
).
textContent
).
toBe
(
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(6)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(6) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
Another message 14 minutes since we started
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(7)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(7) .chat-msg
-
text
'
).
textContent
).
toBe
(
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(7)
'
))).
toBe
(
true
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(7) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
Another message 1 minute and 1 second since the previous one
"
);
expect
(
u
.
hasClass
(
'
chat-msg-followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(8)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(8) .chat-msg
-
text
'
).
textContent
).
toBe
(
expect
(
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
chat_content
.
querySelector
(
'
.message:nth-child(8)
'
))).
toBe
(
false
);
expect
(
chat_content
.
querySelector
(
'
.message:nth-child(8) .chat-msg
__
text
'
).
textContent
).
toBe
(
"
Another message within 10 minutes, but from a different person
"
);
jasmine
.
clock
().
uninstall
();
...
...
@@ -1561,13 +1562,13 @@
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
var
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
createContacts
(
_converse
,
'
current
'
,
1
);
const
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
var
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
const
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
spyOn
(
view
.
model
,
'
sendMessage
'
).
and
.
callThrough
();
var
stanza
=
Strophe
.
xmlHtmlNode
(
const
stanza
=
Strophe
.
xmlHtmlNode
(
"
<message from='
"
+
contact_jid
+
"
'
"
+
"
type='chat'
"
+
"
to='dummy@localhost/resource'>
"
+
...
...
@@ -1576,19 +1577,17 @@
"
</message>
"
).
firstChild
;
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
test_utils
.
waitUntil
(
function
()
{
return
view
.
el
.
querySelectorAll
(
'
.chat-content .chat-msg audio
'
).
length
;
},
1000
).
then
(
function
()
{
var
msg
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg-text
'
);
expect
(
msg
.
outerHTML
).
toEqual
(
'
<span class="chat-msg-text">Have you heard this funny audio?</span>
'
);
var
media
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg-media
'
);
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-content .chat-msg audio
'
).
length
,
1000
).
then
(
function
()
{
let
msg
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__text
'
);
expect
(
msg
.
outerHTML
).
toEqual
(
'
<div class="chat-msg__text">Have you heard this funny audio?</div>
'
);
let
media
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__media
'
);
expect
(
media
.
innerHTML
.
replace
(
/
(\r\n
|
\n
|
\r)
/gm
,
""
)).
toEqual
(
'
<!-- src/templates/audio.html -->
'
+
'
<audio controls=""><source src="http://localhost/audio.mp3" type="audio/mpeg"></audio>
'
+
'
<a target="_blank" rel="noopener" href="http://localhost/audio.mp3">Download audio file</a>
'
);
// If the <url> and <body> contents is the same, don't duplicate.
var
stanza
=
Strophe
.
xmlHtmlNode
(
const
stanza
=
Strophe
.
xmlHtmlNode
(
"
<message from='
"
+
contact_jid
+
"
'
"
+
"
type='chat'
"
+
"
to='dummy@localhost/resource'>
"
+
...
...
@@ -1597,9 +1596,9 @@
"
</message>
"
).
firstChild
;
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
msg
=
view
.
el
.
querySelector
(
'
.chat-msg:last-child .chat-msg
-
text
'
);
expect
(
msg
.
innerHTML
).
toEqual
(
'
'
);
media
=
view
.
el
.
querySelector
(
'
.chat-msg:last-child .chat-msg
-
media
'
);
msg
=
view
.
el
.
querySelector
(
'
.chat-msg:last-child .chat-msg
__
text
'
);
expect
(
msg
.
innerHTML
).
toEqual
(
'
<!-- message gets added here via renderMessage -->
'
);
// Emtpy
media
=
view
.
el
.
querySelector
(
'
.chat-msg:last-child .chat-msg
__
media
'
);
expect
(
media
.
innerHTML
.
replace
(
/
(\r\n
|
\n
|
\r)
/gm
,
""
)).
toEqual
(
'
<!-- src/templates/audio.html -->
'
+
'
<audio controls=""><source src="http://localhost/audio.mp3" type="audio/mpeg"></audio>
'
+
...
...
@@ -1614,12 +1613,12 @@
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
var
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
const
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
var
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
const
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
spyOn
(
view
.
model
,
'
sendMessage
'
).
and
.
callThrough
();
var
stanza
=
Strophe
.
xmlHtmlNode
(
const
stanza
=
Strophe
.
xmlHtmlNode
(
"
<message from='
"
+
contact_jid
+
"
'
"
+
"
type='chat'
"
+
"
to='dummy@localhost/resource'>
"
+
...
...
@@ -1628,19 +1627,17 @@
"
</message>
"
).
firstChild
;
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
test_utils
.
waitUntil
(
function
()
{
return
view
.
el
.
querySelectorAll
(
'
.chat-content .chat-msg video
'
).
length
;
},
2000
).
then
(
function
()
{
var
msg
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg-text
'
);
expect
(
msg
.
outerHTML
).
toEqual
(
'
<span class="chat-msg-text">Have you seen this funny video?</span>
'
);
var
media
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg-media
'
);
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-content .chat-msg video
'
).
length
,
2000
).
then
(
function
()
{
let
msg
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__text
'
);
expect
(
msg
.
outerHTML
).
toEqual
(
'
<div class="chat-msg__text">Have you seen this funny video?</div>
'
);
let
media
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__media
'
);
expect
(
media
.
innerHTML
.
replace
(
/
(\r\n
|
\n
|
\r)
/gm
,
""
)).
toEqual
(
'
<!-- src/templates/video.html -->
'
+
'
<video controls=""><source src="http://localhost/video.mp4" type="video/mp4"></video>
'
+
'
<a target="_blank" rel="noopener" href="http://localhost/video.mp4">Download video file</a>
'
);
// If the <url> and <body> contents is the same, don't duplicate.
var
stanza
=
Strophe
.
xmlHtmlNode
(
const
stanza
=
Strophe
.
xmlHtmlNode
(
"
<message from='
"
+
contact_jid
+
"
'
"
+
"
type='chat'
"
+
"
to='dummy@localhost/resource'>
"
+
...
...
@@ -1649,9 +1646,9 @@
"
</message>
"
).
firstChild
;
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
msg
=
view
.
el
.
querySelector
(
'
.chat-msg:last-child .chat-msg
-
text
'
);
expect
(
msg
.
innerHTML
).
toEqual
(
'
'
);
media
=
view
.
el
.
querySelector
(
'
.chat-msg:last-child .chat-msg
-
media
'
);
msg
=
view
.
el
.
querySelector
(
'
.chat-msg:last-child .chat-msg
__
text
'
);
expect
(
msg
.
innerHTML
).
toEqual
(
'
<!-- message gets added here via renderMessage -->
'
);
// Emtpy
media
=
view
.
el
.
querySelector
(
'
.chat-msg:last-child .chat-msg
__
media
'
);
expect
(
media
.
innerHTML
.
replace
(
/
(\r\n
|
\n
|
\r)
/gm
,
""
)).
toEqual
(
'
<!-- src/templates/video.html -->
'
+
'
<video controls=""><source src="http://localhost/video.mp4" type="video/mp4"></video>
'
+
...
...
@@ -1665,13 +1662,13 @@
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
var
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
createContacts
(
_converse
,
'
current
'
,
1
);
const
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
var
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
const
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
spyOn
(
view
.
model
,
'
sendMessage
'
).
and
.
callThrough
();
var
stanza
=
Strophe
.
xmlHtmlNode
(
const
stanza
=
Strophe
.
xmlHtmlNode
(
"
<message from='
"
+
contact_jid
+
"
'
"
+
"
type='chat'
"
+
"
to='dummy@localhost/resource'>
"
+
...
...
@@ -1680,12 +1677,10 @@
"
</message>
"
).
firstChild
;
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
test_utils
.
waitUntil
(
function
()
{
return
view
.
el
.
querySelectorAll
(
'
.chat-content .chat-msg a
'
).
length
;
},
1000
).
then
(
function
()
{
var
msg
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg-text
'
);
expect
(
msg
.
outerHTML
).
toEqual
(
'
<span class="chat-msg-text">Have you downloaded this funny file?</span>
'
);
var
media
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg-media
'
);
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-content .chat-msg a
'
).
length
,
1000
).
then
(
function
()
{
const
msg
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__text
'
);
expect
(
msg
.
outerHTML
).
toEqual
(
'
<div class="chat-msg__text">Have you downloaded this funny file?</div>
'
);
const
media
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__media
'
);
expect
(
media
.
innerHTML
.
replace
(
/
(\r\n
|
\n
|
\r)
/gm
,
""
)).
toEqual
(
'
<!-- src/templates/file.html -->
'
+
'
<a target="_blank" rel="noopener" href="http://localhost/funny.pdf">Download "funny.pdf"</a>
'
);
...
...
@@ -1699,14 +1694,14 @@
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
var
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
const
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
var
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
const
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
spyOn
(
view
.
model
,
'
sendMessage
'
).
and
.
callThrough
();
var
base_url
=
document
.
URL
.
split
(
window
.
location
.
pathname
)[
0
];
var
url
=
base_url
+
"
/logo/conversejs-filled.svg
"
;
const
base_url
=
document
.
URL
.
split
(
window
.
location
.
pathname
)[
0
];
const
url
=
base_url
+
"
/logo/conversejs-filled.svg
"
;
var
stanza
=
Strophe
.
xmlHtmlNode
(
const
stanza
=
Strophe
.
xmlHtmlNode
(
"
<message from='
"
+
contact_jid
+
"
'
"
+
"
type='chat'
"
+
"
to='dummy@localhost/resource'>
"
+
...
...
@@ -1715,12 +1710,10 @@
"
</message>
"
).
firstChild
;
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
test_utils
.
waitUntil
(
function
()
{
return
view
.
el
.
querySelectorAll
(
'
.chat-content .chat-msg img
'
).
length
;
},
2000
).
then
(
function
()
{
var
msg
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg-text
'
);
expect
(
msg
.
outerHTML
).
toEqual
(
'
<span class="chat-msg-text">Have you seen this funny image?</span>
'
);
var
media
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg-media
'
);
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-content .chat-msg img
'
).
length
,
2000
).
then
(
function
()
{
const
msg
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__text
'
);
expect
(
msg
.
outerHTML
).
toEqual
(
'
<div class="chat-msg__text">Have you seen this funny image?</div>
'
);
const
media
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__media
'
);
expect
(
media
.
innerHTML
.
replace
(
/
(\r\n
|
\n
|
\r)
/gm
,
""
)).
toEqual
(
'
<!-- src/templates/image.html -->
'
+
'
<a href="http://localhost:8000/logo/conversejs-filled.svg" target="_blank" rel="noopener">
'
+
...
...
@@ -1768,7 +1761,7 @@
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder airlock breaks?
'
).
tree
());
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg
-
text
'
).
textContent
)
expect
(
view
.
el
.
querySelector
(
'
.chat-msg
__
text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
view
.
model
.
onMessage
(
$msg
({
...
...
@@ -1779,11 +1772,11 @@
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder chimney breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
return
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg
-
text
'
).
textContent
===
return
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg
__
text
'
).
textContent
===
'
But soft, what light through yonder chimney breaks?
'
);
}).
then
(()
=>
{
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
-
content .fa-edit
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
__
content .fa-edit
'
).
length
).
toBe
(
1
);
view
.
model
.
onMessage
(
$msg
({
'
from
'
:
'
lounge@localhost/newguy
'
,
...
...
@@ -1793,12 +1786,12 @@
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder window breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
return
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg
-
text
'
).
textContent
===
return
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg
__
text
'
).
textContent
===
'
But soft, what light through yonder window breaks?
'
);
}).
then
(()
=>
{
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
-
content .fa-edit
'
).
length
).
toBe
(
1
);
view
.
el
.
querySelector
(
'
.chat-msg
-
content .fa-edit
'
).
click
();
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
__
content .fa-edit
'
).
length
).
toBe
(
1
);
view
.
el
.
querySelector
(
'
.chat-msg
__
content .fa-edit
'
).
click
();
const
modal
=
view
.
model
.
messages
.
at
(
0
).
message_versions_modal
;
return
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
);
}).
then
(()
=>
{
...
...
@@ -1838,7 +1831,7 @@
keyCode
:
13
// Enter
});
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg
-
text
'
).
textContent
)
expect
(
view
.
el
.
querySelector
(
'
.chat-msg
__
text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
const
first_msg
=
view
.
model
.
messages
.
findWhere
({
'
message
'
:
'
But soft, what light through yonder airlock breaks?
'
});
...
...
spec/spoilers.js
View file @
acd9a186
...
...
@@ -40,9 +40,9 @@
return
test_utils
.
waitUntil
(()
=>
view
.
model
.
vcard
.
get
(
'
fullname
'
)
===
'
Max Frankfurter
'
)
.
then
(
function
()
{
expect
(
view
.
el
.
querySelector
(
'
.chat-msg
-author
'
).
textContent
).
toBe
(
'
Max Frankfurter
'
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg
__author
'
).
textContent
.
trim
()
).
toBe
(
'
Max Frankfurter
'
);
var
message_content
=
view
.
el
.
querySelector
(
'
.chat-msg
-
text
'
);
var
message_content
=
view
.
el
.
querySelector
(
'
.chat-msg
__
text
'
);
expect
(
message_content
.
textContent
).
toBe
(
spoiler
);
var
spoiler_hint_el
=
view
.
el
.
querySelector
(
'
.spoiler-hint
'
);
...
...
@@ -79,9 +79,9 @@
var
view
=
_converse
.
chatboxviews
.
get
(
sender_jid
);
return
test_utils
.
waitUntil
(()
=>
view
.
model
.
vcard
.
get
(
'
fullname
'
)
===
'
Max Frankfurter
'
)
.
then
(
function
()
{
expect
(
_
.
includes
(
view
.
el
.
querySelector
(
'
.chat-msg
-
author
'
).
textContent
,
'
Max Frankfurter
'
)).
toBeTruthy
();
expect
(
_
.
includes
(
view
.
el
.
querySelector
(
'
.chat-msg
__
author
'
).
textContent
,
'
Max Frankfurter
'
)).
toBeTruthy
();
var
message_content
=
view
.
el
.
querySelector
(
'
.chat-msg
-
text
'
);
var
message_content
=
view
.
el
.
querySelector
(
'
.chat-msg
__
text
'
);
expect
(
message_content
.
textContent
).
toBe
(
spoiler
);
var
spoiler_hint_el
=
view
.
el
.
querySelector
(
'
.spoiler-hint
'
);
...
...
@@ -148,9 +148,9 @@
expect
(
body_el
.
textContent
).
toBe
(
'
This is the spoiler
'
);
/* Test the HTML spoiler message */
expect
(
view
.
el
.
querySelector
(
'
.chat-msg
-author
'
).
textContent
).
toBe
(
'
Max Mustermann
'
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg
__author
'
).
textContent
.
trim
()
).
toBe
(
'
Max Mustermann
'
);
var
spoiler_msg_el
=
view
.
el
.
querySelector
(
'
.chat-msg
-
text.spoiler
'
);
var
spoiler_msg_el
=
view
.
el
.
querySelector
(
'
.chat-msg
__
text.spoiler
'
);
expect
(
spoiler_msg_el
.
textContent
).
toBe
(
'
This is the spoiler
'
);
expect
(
_
.
includes
(
spoiler_msg_el
.
classList
,
'
collapsed
'
)).
toBeTruthy
();
...
...
@@ -227,9 +227,9 @@
expect
(
body_el
.
textContent
).
toBe
(
'
This is the spoiler
'
);
/* Test the HTML spoiler message */
expect
(
view
.
el
.
querySelector
(
'
.chat-msg
-author
'
).
textContent
).
toBe
(
'
Max Mustermann
'
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg
__author
'
).
textContent
.
trim
()
).
toBe
(
'
Max Mustermann
'
);
var
spoiler_msg_el
=
view
.
el
.
querySelector
(
'
.chat-msg
-
text.spoiler
'
);
var
spoiler_msg_el
=
view
.
el
.
querySelector
(
'
.chat-msg
__
text.spoiler
'
);
expect
(
spoiler_msg_el
.
textContent
).
toBe
(
'
This is the spoiler
'
);
expect
(
_
.
includes
(
spoiler_msg_el
.
classList
,
'
collapsed
'
)).
toBeTruthy
();
...
...
src/converse-chatview.js
View file @
acd9a186
...
...
@@ -9,7 +9,6 @@
"
bootstrap
"
,
"
emojione
"
,
"
xss
"
,
"
templates/action.html
"
,
"
templates/chatbox.html
"
,
"
templates/chatbox_head.html
"
,
"
templates/chatbox_message_form.html
"
,
...
...
@@ -33,7 +32,6 @@
bootstrap
,
emojione
,
xss
,
tpl_action
,
tpl_chatbox
,
tpl_chatbox_head
,
tpl_chatbox_message_form
,
...
...
@@ -747,19 +745,19 @@
date
=
moment
(
el
.
getAttribute
(
'
data-isodate
'
)),
next_el
=
el
.
nextElementSibling
;
if
(
!
u
.
hasClass
(
'
chat-
action
'
,
el
)
&&
!
u
.
hasClass
(
'
chat
-action
'
,
previous_el
)
&&
if
(
!
u
.
hasClass
(
'
chat-
msg--action
'
,
el
)
&&
!
u
.
hasClass
(
'
chat-msg-
-action
'
,
previous_el
)
&&
previous_el
.
getAttribute
(
'
data-from
'
)
===
from
&&
date
.
isBefore
(
moment
(
previous_el
.
getAttribute
(
'
data-isodate
'
)).
add
(
10
,
'
minutes
'
)))
{
u
.
addClass
(
'
chat-msg-followup
'
,
el
);
u
.
addClass
(
'
chat-msg-
-
followup
'
,
el
);
}
if
(
!
next_el
)
{
return
;
}
if
(
!
u
.
hasClass
(
'
chat-action
'
,
'
el
'
)
&&
if
(
!
u
.
hasClass
(
'
chat-
msg--
action
'
,
'
el
'
)
&&
next_el
.
getAttribute
(
'
data-from
'
)
===
from
&&
moment
(
next_el
.
getAttribute
(
'
data-isodate
'
)).
isBefore
(
date
.
add
(
10
,
'
minutes
'
)))
{
u
.
addClass
(
'
chat-msg-followup
'
,
next_el
);
u
.
addClass
(
'
chat-msg-
-
followup
'
,
next_el
);
}
else
{
u
.
removeClass
(
'
chat-msg-followup
'
,
next_el
);
u
.
removeClass
(
'
chat-msg-
-
followup
'
,
next_el
);
}
},
...
...
src/converse-message-view.js
View file @
acd9a186
...
...
@@ -10,26 +10,22 @@
"
xss
"
,
"
emojione
"
,
"
filesize
"
,
"
templates/action.html
"
,
"
templates/csn.html
"
,
"
templates/file_progress.html
"
,
"
templates/info.html
"
,
"
templates/message.html
"
,
"
templates/message_versions_modal.html
"
,
"
templates/spoiler_message.html
"
],
factory
);
}(
this
,
function
(
converse
,
xss
,
emojione
,
filesize
,
tpl_action
,
tpl_csn
,
tpl_file_progress
,
tpl_info
,
tpl_message
,
tpl_message_versions_modal
,
tpl_spoiler_message
tpl_message_versions_modal
)
{
"
use strict
"
;
const
{
Backbone
,
_
,
moment
}
=
converse
.
env
;
...
...
@@ -101,7 +97,7 @@
},
render
()
{
const
is_followup
=
u
.
hasClass
(
'
chat-msg-followup
'
,
this
.
el
);
const
is_followup
=
u
.
hasClass
(
'
chat-msg-
-
followup
'
,
this
.
el
);
let
msg
;
if
(
this
.
model
.
isOnlyChatStateNotification
())
{
this
.
renderChatStateNotification
()
...
...
@@ -113,7 +109,7 @@
this
.
renderChatMessage
();
}
if
(
is_followup
)
{
u
.
addClass
(
'
chat-msg-followup
'
,
this
.
el
);
u
.
addClass
(
'
chat-msg-
-
followup
'
,
this
.
el
);
}
return
this
.
el
;
},
...
...
@@ -135,21 +131,16 @@
},
renderChatMessage
()
{
let
template
,
text
=
this
.
model
.
get
(
'
message
'
);
if
(
this
.
isMeCommand
())
{
template
=
tpl_action
;
text
=
this
.
model
.
get
(
'
message
'
).
replace
(
/^
\/
me/
,
''
);
}
else
{
template
=
this
.
model
.
get
(
'
is_spoiler
'
)
?
tpl_spoiler_message
:
tpl_message
;
}
const
moment_time
=
moment
(
this
.
model
.
get
(
'
time
'
)),
const
is_me_message
=
this
.
isMeCommand
(),
moment_time
=
moment
(
this
.
model
.
get
(
'
time
'
)),
role
=
this
.
model
.
vcard
.
get
(
'
role
'
),
roles
=
role
?
role
.
split
(
'
,
'
)
:
[];
const
msg
=
u
.
stringToElement
(
t
emplat
e
(
const
msg
=
u
.
stringToElement
(
t
pl_messag
e
(
_
.
extend
(
this
.
model
.
toJSON
(),
{
'
__
'
:
__
,
'
is_me_message
'
:
is_me_message
,
'
roles
'
:
roles
,
'
pretty_time
'
:
moment_time
.
format
(
_converse
.
time_format
),
'
time
'
:
moment_time
.
format
(),
...
...
@@ -159,16 +150,20 @@
})
));
var
url
=
this
.
model
.
get
(
'
oob_url
'
);
const
url
=
this
.
model
.
get
(
'
oob_url
'
);
if
(
url
)
{
msg
.
querySelector
(
'
.chat-msg
-
media
'
).
innerHTML
=
_
.
flow
(
msg
.
querySelector
(
'
.chat-msg
__
media
'
).
innerHTML
=
_
.
flow
(
_
.
partial
(
u
.
renderFileURL
,
_converse
),
_
.
partial
(
u
.
renderMovieURL
,
_converse
),
_
.
partial
(
u
.
renderAudioURL
,
_converse
),
_
.
partial
(
u
.
renderImageURL
,
_converse
))(
url
);
}
const
msg_content
=
msg
.
querySelector
(
'
.chat-msg-text
'
);
let
text
=
this
.
model
.
get
(
'
message
'
);
if
(
is_me_message
)
{
text
=
text
.
replace
(
/^
\/
me/
,
''
);
}
const
msg_content
=
msg
.
querySelector
(
'
.chat-msg__text
'
);
if
(
text
!==
url
)
{
text
=
xss
.
filterXSS
(
text
,
{
'
whiteList
'
:
{}});
msg_content
.
innerHTML
=
_
.
flow
(
...
...
src/templates/action.html
deleted
100644 → 0
View file @
6a462f6c
<div
class=
"message chat-msg chat-action {{{o.extra_classes}}}"
data-isodate=
"{{{o.time}}}"
data-from=
"{{{o.from}}}"
>
<span
class=
"chat-msg-heading"
>
<span
class=
"chat-msg-author"
>
**{{{o.username}}}
</span>
</span>
<p
class=
"chat-msg-text"
>
<!-- message gets added here via renderMessage -->
</p>
</div>
src/templates/file_progress.html
View file @
acd9a186
<div
class=
"message chat-msg"
data-isodate=
"{{{o.time}}}"
data-msgid=
"{{{o.msgid}}}"
>
<canvas
class=
"avatar"
height=
"36"
width=
"36"
></canvas>
<div
class=
"chat-msg
-
content"
>
<span
class=
"chat-msg
-
text"
>
Uploading file:
<strong>
{{{o.file.name}}}
</strong>
, {{{o.filesize}}}
</span>
<canvas
class=
"avatar
chat-msg__avatar
"
height=
"36"
width=
"36"
></canvas>
<div
class=
"chat-msg
__
content"
>
<span
class=
"chat-msg
__
text"
>
Uploading file:
<strong>
{{{o.file.name}}}
</strong>
, {{{o.filesize}}}
</span>
<progress
value=
"{{{o.progress}}}"
/>
</div>
</div>
src/templates/message.html
View file @
acd9a186
<div
class=
"message chat-msg {{{o.type}}} {{{o.extra_classes}}}"
data-isodate=
"{{{o.time}}}"
data-msgid=
"{{{o.msgid}}}"
data-from=
"{{{o.from}}}"
>
{[ if (o.type !== 'headline') { ]}
<canvas
class=
"avatar"
height=
"36"
width=
"36"
></canvas>
<div
class=
"message chat-msg {{{o.type}}} {
[ if (o.is_me_message) { ]} chat-msg--action {[ } ]} {
{{o.extra_classes}}}"
data-isodate=
"{{{o.time}}}"
data-msgid=
"{{{o.msgid}}}"
data-from=
"{{{o.from}}}"
>
{[ if (o.type !== 'headline'
&&
!o.is_me_message
) { ]}
<canvas
class=
"avatar
chat-msg__avatar
"
height=
"36"
width=
"36"
></canvas>
{[ } ]}
<div
class=
"chat-msg-content"
>
<span
class=
"chat-msg-heading"
>
<span
class=
"chat-msg-author"
>
{{{o.username}}}
<div
class=
"chat-msg__content {[ if (o.is_me_message) { ]}chat-msg__content--action{[ } ]}"
>
<span
class=
"chat-msg__heading"
>
{[ if (o.is_me_message) { ]}
<time
timestamp=
"{{{o.isodate}}}"
class=
"chat-msg__time"
>
{{{o.pretty_time}}}
</time>
{[ } ]}
<span
class=
"chat-msg__author"
>
{[ if (o.is_me_message) { ]}**{[ }; ]}{{{o.username}}}
{[o.roles.forEach(function (role) { ]}
<span
class=
"badge badge-secondary"
>
{{{role}}}
</span>
{[ }); ]}
</span>
<time
timestamp=
"{{{o.isodate}}}"
class=
"chat-msg-time"
>
{{{o.pretty_time}}}
</time>
{[ if (!o.is_me_message) { ]}
<time
timestamp=
"{{{o.isodate}}}"
class=
"chat-msg__time"
>
{{{o.pretty_time}}}
</time>
{[ } ]}
</span>
{[ if (o.edited) { ]}
<i
title=
"{{{o.__('This message has been edited')}}}"
class=
"fa fa-edit chat-msg-edited"
></i>
{[ } ]}
<span
class=
"chat-msg-text"
></span>
<div
class=
"chat-msg-media"
></div>
{[ if (!o.is_me_message) { ]}
<div
class=
"chat-msg__body"
>
{[ } ]}
{[ if (o.edited) { ]}
<i
title=
"{{{o.__('This message has been edited')}}}"
class=
"fa fa-edit chat-msg-edited"
></i>
{[ } ]}
{[ if (!o.is_me_message) { ]}
<div
class=
"chat-msg__message"
>
{[ } ]}
{[ if (o.is_spoiler) { ]}
<div
class=
"chat-msg__spoiler-hint"
>
<span
class=
"spoiler-hint"
>
{{{o.spoiler_hint}}}
</span>
<a
class=
"badge badge-info spoiler-toggle"
data-toggle-state=
"closed"
href=
"#"
><i
class=
"fa fa-eye"
></i>
{{{o.label_show}}}
</a>
</div>
{[ } ]}
<div
class=
"chat-msg__text{[ if (o.is_spoiler) { ]} spoiler collapsed{[ } ]}"
>
<!-- message gets added here via renderMessage -->
</div>
<div
class=
"chat-msg__media"
></div>
{[ if (!o.is_me_message) { ]}
</div>
{[ } ]}
{[ if (!o.is_me_message) { ]}
</div>
{[ } ]}
</div>
</div>
src/templates/spoiler_message.html
deleted
100644 → 0
View file @
6a462f6c
<div
class=
"message chat-msg {{{o.extra_classes}}}"
data-isodate=
"{{{o.time}}}"
data-msgid=
"{{{o.msgid}}}"
>
<canvas
class=
"avatar"
height=
"36"
width=
"36"
></canvas>
<div
class=
"chat-msg-content"
>
<span
class=
"chat-msg-heading"
>
<span
class=
"chat-msg-author"
>
{{{o.username}}}
</span>
<span
class=
"chat-msg-time"
>
{{{o.pretty_time}}}
</span>
</span>
<div>
<span
class=
"spoiler-hint"
>
{{{o.spoiler_hint}}}
</span>
<a
class=
"badge badge-info spoiler-toggle"
data-toggle-state=
"closed"
href=
"#"
><i
class=
"fa fa-eye"
></i>
{{{o.label_show}}}
</a>
</div>
<div
class=
"chat-msg-text spoiler collapsed"
>
<!-- message gets added here via renderMessage -->
</div>
</div>
</div>
src/utils/core.js
View file @
acd9a186
...
...
@@ -210,6 +210,10 @@
.
replace
(
/"/g
,
"
"
"
);
};
u
.
escapeURL
=
function
(
url
)
{
return
encodeURI
(
decodeURI
(
url
)).
replace
(
/
[
!'()
]
/g
,
escape
).
replace
(
/
\*
/g
,
"
%2A
"
);
};
u
.
addHyperlinks
=
function
(
text
)
{
return
URI
.
withinString
(
text
,
function
(
url
)
{
var
uri
=
new
URI
(
url
);
...
...
@@ -217,8 +221,8 @@
if
(
!
url
.
startsWith
(
'
http://
'
)
&&
!
url
.
startsWith
(
'
https://
'
))
{
url
=
'
http://
'
+
url
;
}
url
=
encodeURI
(
decodeURI
(
url
)).
replace
(
/
[
!'()
]
/g
,
escape
).
replace
(
/
\*
/g
,
"
%2A
"
);
return
`<a target="_blank" rel="noopener" href="
${
u
.
escapeHTML
(
url
)
}
">
${
u
.
escapeHTML
(
uri
.
readable
())}
</a>`
;
url
=
u
.
escapeHTML
(
u
.
escapeURL
(
url
)
);
return
`<a target="_blank" rel="noopener" href="
${
u
rl
}
">
${
u
.
escapeHTML
(
uri
.
readable
())}
</a>`
;
});
};
...
...
@@ -255,7 +259,8 @@
};
u
.
renderFileURL
=
function
(
_converse
,
url
)
{
const
uri
=
new
URI
(
url
),
{
__
}
=
_converse
,
const
uri
=
new
URI
(
url
),
{
__
}
=
_converse
,
filename
=
uri
.
filename
();
if
(
!
_
.
includes
([
"
https
"
,
"
http
"
],
uri
.
protocol
())
||
filename
.
endsWith
(
'
mp3
'
)
||
filename
.
endsWith
(
'
mp4
'
)
||
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment