Upgrade to Webpack 3

Had to make various other changes due to incompatibilities.

- Use the new `lit` package instead of `lit-html` or `lit-element`
- Drop `haunted` since it breaks the rules by specifying `type: module`
  but then doesn't import with file extensions
- Use Sass Dart instead of node-sass (fixes #2445)
- Upgrade Karma
This commit is contained in:
Shaun Wu 2021-04-14 16:56:59 -04:00 committed by JC Brand
parent fe29a86af9
commit 9ea8653ef7
154 changed files with 1740 additions and 2676 deletions

View File

@ -10,8 +10,8 @@
"jasmine": true,
"es6": true
},
"plugins": ["lodash"],
"extends": ["eslint:recommended", "plugin:lodash/canonical"],
"plugins": [],
"extends": ["eslint:recommended"],
"globals": {
"Uint8Array": true,
"Promise": true,
@ -21,20 +21,6 @@
"window": true
},
"rules": {
"lodash/prefer-lodash-chain": "off",
"lodash/prefer-lodash-method": "off",
"lodash/import-scope": "off",
"lodash/prefer-constant": "off",
"lodash/prefer-get": "off",
"lodash/prefer-includes": "off",
"lodash/prefer-invoke-map": "off",
"lodash/prefer-is-nil": "off",
"lodash/prefer-lodash-typecheck": "off",
"lodash/prefer-noop": "off",
"lodash/prefer-startswith": "off",
"lodash/preferred-alias": "off",
"lodash/matches-prop-shorthand": "off",
"lodash/prop-shorthand": "off",
"accessor-pairs": "error",
"array-bracket-spacing": "off",
"array-callback-return": "error",

View File

@ -16,7 +16,7 @@ OXIPNG ?= oxipng
PAPER =
RJS ?= ./node_modules/.bin/r.js
NPX ?= ./node_modules/.bin/npx
SASS ?= ./node_modules/.bin/node-sass
SASS ?= ./node_modules/.bin/sass
SED ?= sed
SPHINXBUILD ?= ./bin/sphinx-build
SPHINXOPTS =
@ -144,7 +144,7 @@ dist/converse.css:: node_modules
npm run dev
dist/website.css:: node_modules src
$(SASS) --source-map true --include-path $(BOOTSTRAP) src/shared/styles/website.scss $@
$(SASS) --load-path=$(BOOTSTRAP) src/shared/styles/website.scss $@
dist/website.min.css:: node_modules dist/website.css
$(CLEANCSS) dist/website.css > $@

3504
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -65,7 +65,7 @@
"devDependencies": {
"@babel/cli": "^7.10.3",
"@babel/core": "^7.10.5",
"@babel/plugin-proposal-class-properties": "^7.12.1",
"@babel/plugin-proposal-class-properties": "^7.13.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8",
"@babel/plugin-proposal-optional-chaining": "^7.12.1",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
@ -74,7 +74,7 @@
"@fortawesome/fontawesome-free": "5.14.0",
"autoprefixer": "^9.8.6",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.1.0",
"babel-loader": "^8.2.2",
"babel-plugin-lodash": "^3.3.4",
"bootstrap": "^4.6.0",
"bootstrap.native": "^2.0.27",
@ -82,33 +82,29 @@
"clean-css-cli": "^4.3.0",
"copy-webpack-plugin": "^6.3.2",
"css-loader": "^3.5.3",
"dayjs": "1.8.30",
"dayjs": "1.10.4",
"eslint": "^7.3.0",
"eslint-plugin-lodash": "^7.1.0",
"exports-loader": "^0.7.0",
"fast-text-encoding": "^1.0.3",
"favico.js-slevomat": "^0.3.11",
"file-loader": "^6.0.0",
"haunted": "^4.7.0",
"html-webpack-plugin": "^4.3.0",
"http-server": "^0.12.3",
"imports-loader": "^0.8.0",
"install": "^0.13.0",
"jasmine": "^3.5.0",
"jed": "1.1.1",
"jsdoc": "^3.6.4",
"karma": "^5.1.0",
"jsdoc": "^3.6.6",
"karma": "^6.3.2",
"karma-chrome-launcher": "^3.1.0",
"karma-cli": "^2.0.0",
"karma-jasmine": "^3.1.1",
"karma-jasmine-html-reporter": "^1.5.4",
"karma-webpack": "^4.0.2",
"karma-webpack": "^5.0.0",
"lerna": "^3.22.1",
"lit-element": "^2.4.0",
"lit-html": "^1.2.1",
"mini-css-extract-plugin": "^0.9.0",
"lit": "^2.0.0-rc.1",
"mini-css-extract-plugin": "^1.5.1",
"minimist": "^1.2.3",
"node-sass": "^4.14.1",
"npm": "^6.14.9",
"po-loader": "^0.5.0",
"po2json": "^1.0.0-beta",
@ -116,11 +112,12 @@
"postcss-loader": "^3.0.0",
"prettierx": "^0.12.1",
"run-headless-chromium": "^0.1.1",
"sass-loader": "^8.0.2",
"sass": "^1.32.12",
"sass-loader": "^11.0.1",
"sinon": "^9.2.4",
"style-loader": "^0.23.1",
"urijs": "^1.19.6",
"webpack": "^4.43.0",
"webpack": "^5.36.1",
"webpack-cli": "^4.5.0",
"webpack-dev-server": "^3.11.2",
"webpack-merge": "^5.7.3",

View File

@ -355,7 +355,7 @@ describe("Emojis", function () {
await new Promise(resolve => _converse.on('chatBoxViewInitialized', resolve));
const view = _converse.api.chatviews.get(contact_jid);
await new Promise(resolve => view.model.messages.once('rendered', resolve));
await u.waitUntil(() => view.querySelector('.chat-msg__text').innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => view.querySelector('.chat-msg__text').innerHTML.replace(/<!-.*?->/g, '') ===
'<img class="emoji" draggable="false" title=":innocent:" alt="😇" src="https://twemoji.maxcdn.com/v/12.1.6//72x72/1f607.png">');
const last_msg_sel = 'converse-chat-message:last-child .chat-msg__text';
@ -414,7 +414,7 @@ describe("Emojis", function () {
await u.waitUntil(() => u.isVisible(view.querySelector('.emoji-picker__lists')), 1000);
const picker = await u.waitUntil(() => view.querySelector('converse-emoji-picker'), 1000);
const custom_category = picker.querySelector('.pick-category[data-category="custom"]');
expect(custom_category.innerHTML.replace(/<!---->/g, '').trim()).toBe(
expect(custom_category.innerHTML.replace(/<!-.*?->/g, '').trim()).toBe(
'<img class="emoji" draggable="false" title=":xmpp:" alt=":xmpp:" src="/dist/images/custom_emojis/xmpp.png">');
const textarea = view.querySelector('textarea.chat-textarea');
@ -427,7 +427,7 @@ describe("Emojis", function () {
});
await new Promise(resolve => view.model.messages.once('rendered', resolve));
const body = view.querySelector('converse-chat-message-body');
await u.waitUntil(() => body.innerHTML.replace(/<!---->/g, '').trim() ===
await u.waitUntil(() => body.innerHTML.replace(/<!-.*?->/g, '').trim() ===
'Running tests for <img class="emoji" draggable="false" title=":converse:" alt=":converse:" src="/dist/images/custom_emojis/converse.png">');
done();
}));

View File

@ -305,11 +305,11 @@ describe("XEP-0363: HTTP File Upload", function () {
`</message>`);
const img_link_el = await u.waitUntil(() => view.querySelector('converse-chat-message-body .chat-image__link'), 1000);
// Check that the image renders
expect(img_link_el.outerHTML.replace(/<!---->/g, '').trim()).toEqual(
expect(img_link_el.outerHTML.replace(/<!-.*?->/g, '').trim()).toEqual(
`<a class="chat-image__link" target="_blank" rel="noopener" href="${base_url}/logo/conversejs-filled.svg">`+
`<img class="chat-image img-thumbnail" src="${base_url}/logo/conversejs-filled.svg"></a>`);
expect(view.querySelector('.chat-msg .chat-msg__media').innerHTML.replace(/<!---->/g, '').trim()).toEqual(
expect(view.querySelector('.chat-msg .chat-msg__media').innerHTML.replace(/<!-.*?->/g, '').trim()).toEqual(
`<a target="_blank" rel="noopener" href="${base_url}/logo/conversejs-filled.svg">`+
`Download image file "conversejs-filled.svg"</a>`);
XMLHttpRequest.prototype.send = send_backup;
@ -409,11 +409,11 @@ describe("XEP-0363: HTTP File Upload", function () {
`</message>`);
const img_link_el = await u.waitUntil(() => view.querySelector('converse-chat-message-body .chat-image__link'), 1000);
// Check that the image renders
expect(img_link_el.outerHTML.replace(/<!---->/g, '').trim()).toEqual(
expect(img_link_el.outerHTML.replace(/<!-.*?->/g, '').trim()).toEqual(
`<a class="chat-image__link" target="_blank" rel="noopener" href="${base_url}/logo/conversejs-filled.svg">`+
`<img class="chat-image img-thumbnail" src="${base_url}/logo/conversejs-filled.svg"></a>`);
expect(view.querySelector('.chat-msg .chat-msg__media').innerHTML.replace(/<!---->/g, '').trim()).toEqual(
expect(view.querySelector('.chat-msg .chat-msg__media').innerHTML.replace(/<!-.*?->/g, '').trim()).toEqual(
`<a target="_blank" rel="noopener" href="${base_url}/logo/conversejs-filled.svg">`+
`Download image file "conversejs-filled.svg"</a>`);

View File

@ -82,7 +82,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length);
msg_el = view.querySelector('converse-chat-message-body');
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'This <span class="styling-directive">*</span>'+
'<b>message <span class="styling-directive">_</span><i>contains</i><span class="styling-directive">_</span></b>'+
'<span class="styling-directive">*</span>'+
@ -96,7 +96,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 2);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'Here\'s a <span class="styling-directive">~</span><del>strikethrough section</del><span class="styling-directive">~</span>');
// Span directives containing hyperlinks
@ -106,7 +106,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 3);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'<span class="styling-directive">~</span>'+
'<del>Check out this site: <a target="_blank" rel="noopener" href="https://conversejs.org/">https://conversejs.org</a></del>'+
'<span class="styling-directive">~</span>');
@ -119,7 +119,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 4);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'<span class="styling-directive">*</span>'+
'<b><a target="_blank" rel="noopener" href="https://conversejs.org/logo/conversejs-filled.svg">https://conversejs.org/logo/conversejs-filled.svg</a></b>'+
'<span class="styling-directive">*</span>');
@ -131,7 +131,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 5);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'<span class="styling-directive">~</span><del> Hello! <span title=":poop:">💩</span> </del><span class="styling-directive">~</span>');
// Span directives don't cross lines
@ -141,7 +141,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 6);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'This *is not a styling hint \n'+
' * <span class="styling-directive">_</span><i>But this is</i><span class="styling-directive">_</span>!');
@ -151,7 +151,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 7);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'(There are three blocks in this body marked by parens,)\n'+
' (but there is no *formatting)\n'+
' (as spans* may not escape blocks.)\n'+
@ -164,7 +164,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 8);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'_<span class="styling-directive">_</span><i> hello world </i><span class="styling-directive">_</span>');
// Directives which are parts of words aren't matched
@ -174,7 +174,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 9);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'Go to ~https://conversejs.org~now <span class="styling-directive">_</span><i>please</i><span class="styling-directive">_</span>');
msg_text = `Go to _https://converse_js.org_ _please_`;
@ -183,7 +183,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 10);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'Go to <span class="styling-directive">_</span>'+
'<i><a target="_blank" rel="noopener" href="https://converse_js.org/">https://converse_js.org</a></i>'+
'<span class="styling-directive">_</span> <span class="styling-directive">_</span><i>please</i><span class="styling-directive">_</span>');
@ -207,7 +207,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'Here\'s a code block: \n'+
'<div class="styling-directive">```</div><code class="block">Inside the code-block, &lt;code&gt;hello&lt;/code&gt; we don\'t enable *styling hints* like ~these~\n'+
'</code><div class="styling-directive">```</div>'
@ -219,7 +219,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 2);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'<div class="styling-directive">```</div>'+
'<code class="block">ignored\n(println "Hello, world!")\n</code>'+
'<div class="styling-directive">```</div>\n'+
@ -232,7 +232,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 3);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'```ignored\n (println "Hello, world!")\n ```\n\n'+
' This should not show up as monospace, '+
'<span class="styling-directive">*</span><b>preformatted</b><span class="styling-directive">*</span> text ^');
@ -255,7 +255,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 1);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'<blockquote>This is quoted text\nThis is also quoted</blockquote>\nThis is not quoted');
msg_text = `> This is *quoted* text\n>This is \`also _quoted_\`\nThis is not quoted`;
@ -264,7 +264,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 2);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'<blockquote>This is <span class="styling-directive">*</span><b>quoted</b><span class="styling-directive">*</span> text\n'+
'This is <span class="styling-directive">`</span><code>also _quoted_</code><span class="styling-directive">`</span></blockquote>\n'+
'This is not quoted');
@ -275,7 +275,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 3);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') === "<blockquote><blockquote>This is doubly quoted text</blockquote></blockquote>");
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') === "<blockquote><blockquote>This is doubly quoted text</blockquote></blockquote>");
msg_text = `>> This is doubly quoted text`;
msg = mock.createChatMessage(_converse, contact_jid, msg_text)
@ -283,7 +283,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 4);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') === "<blockquote><blockquote>This is doubly quoted text</blockquote></blockquote>");
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') === "<blockquote><blockquote>This is doubly quoted text</blockquote></blockquote>");
msg_text = ">```\n>ignored\n> <span></span> (println \"Hello, world!\")\n>```\n> This should show up as monospace, preformatted text ^";
msg = mock.createChatMessage(_converse, contact_jid, msg_text)
@ -291,7 +291,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 5);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'<blockquote>'+
'<div class="styling-directive">```</div>'+
'<code class="block">ignored\n &lt;span&gt;&lt;/span&gt; (println "Hello, world!")\n'+
@ -305,7 +305,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 6);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'<blockquote>```\n (println "Hello, world!")</blockquote>\n\n'+
'The entire blockquote is a preformatted text block, but this line is plaintext!');
@ -315,7 +315,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 7);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'<blockquote>Also, icons.js is loaded from /dist, instead of dist.</blockquote>\n'+
'<a target="_blank" rel="noopener" href="https://conversejs.org/docs/html/configuration.html#assets-path">https://conversejs.org/docs/html/configuration.html#assets-path</a>');
@ -325,7 +325,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 8);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'<blockquote>Where is it located?</blockquote>\n'+
'<a target="_blank" rel="noopener" '+
'href="https://www.openstreetmap.org/?mlat=37.786971&amp;mlon=-122.399677#map=18/37.786971/-122.399677">https://www.openstreetmap.org/?mlat=37.786971&amp;mlon=-122.399677#map=18/37.786971/-122.399677</a>');
@ -336,7 +336,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 9);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'<blockquote>What do you think of it?</blockquote>\n <span title=":poop:">💩</span>');
msg_text = '> What do you think of it?\n~hello~';
@ -345,7 +345,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 10);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'<blockquote>What do you think of it?</blockquote>\n<span class="styling-directive">~</span><del>hello</del><span class="styling-directive">~</span>');
msg_text = 'hello world > this is not a quote';
@ -354,7 +354,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 11);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') === 'hello world &gt; this is not a quote');
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') === 'hello world &gt; this is not a quote');
msg_text = '> What do you think of it romeo?\n Did you see this romeo?';
msg = $msg({
@ -382,7 +382,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 12);
msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
`<blockquote>What do you think of it <span class="mention">romeo</span>?</blockquote>\n Did you see this <span class="mention">romeo</span>?`);
done();
}));
@ -421,7 +421,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length);
const msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') === '```\ncode```');
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') === '```\ncode```');
done();
}));
});

View File

@ -2,7 +2,6 @@
* @copyright The Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
import './polyfill';
import Storage from '@converse/skeletor/src/storage.js';
import _converse from '@converse/headless/shared/_converse';
import advancedFormat from 'dayjs/plugin/advancedFormat';
@ -36,7 +35,7 @@ import { Strophe, $build, $iq, $msg, $pres } from 'strophe.js/src/strophe';
import { TimeoutError } from '@converse/headless/shared/errors';
import { createStore, replacePromise } from '@converse/headless/shared/utils';
import { getOpenPromise } from '@converse/openpromise';
import { html } from 'lit-element';
import { html } from 'lit';
import { sprintf } from 'sprintf-js';
export { _converse };

View File

@ -31,12 +31,6 @@
"immediate": "~3.0.5"
}
},
"lit-html": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.3.0.tgz",
"integrity": "sha512-0Q1bwmaFH9O14vycPHw8C/IeHMk/uSDldVLIefu/kfbTBGIc44KGH6A8p1bDfxUfHdc8q6Ct7kQklWoHgr4t1Q==",
"dev": true
},
"localforage": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.7.3.tgz",

View File

@ -36,7 +36,7 @@
},
"gitHead": "9641dcdc820e029b05930479c242d2b707bbe8e2",
"devDependencies": {
"@converse/skeletor": "0.0.3",
"@converse/skeletor": "conversejs/skeletor#fe855404babc08cbb1018231eb49a7b7e497539c",
"filesize": "^6.1.0",
"localforage": "^1.9.0",
"localforage-driver-memory": "^1.0.5",

View File

@ -7,7 +7,7 @@ import { ASCII_REPLACE_REGEX, CODEPOINTS_REGEX } from './regexes.js';
import { Model } from '@converse/skeletor/src/model.js';
import { _converse, api, converse } from "../../core.js";
import { getOpenPromise } from '@converse/openpromise';
import { html } from 'lit-html';
import { html } from 'lit';
const u = converse.env.utils;
@ -277,7 +277,7 @@ converse.plugins.add('converse-emoji', {
* Returns an emoji represented by the passed in shortname.
* Scans the passed in text for shortnames and replaces them with
* emoji unicode glyphs or alternatively if it's a custom emoji
* without unicode representation then a lit-html TemplateResult
* without unicode representation then a lit TemplateResult
* which represents image tag markup is returned.
*
* The shortname needs to be defined in `emojis.json`
@ -291,13 +291,13 @@ converse.plugins.add('converse-emoji', {
* unicode codepoints. If so, the returned result will be an array
* with containing one string, because the emojis themselves will
* also be strings. If set to false, emojis will be represented by
* lit-html TemplateResult objects.
* lit TemplateResult objects.
* @param { Boolean } options.add_title_wrapper - Whether unicode
* codepoints should be wrapped with a `<span>` element with a
* title, so that the shortname is shown upon hovering with the
* mouse.
* @returns {Array} An array of at least one string, or otherwise
* strings and lit-html TemplateResult objects.
* strings and lit TemplateResult objects.
*/
shortnamesToEmojis (str, options={unicode_only: false, add_title_wrapper: false}) {
str = convertASCII2Emoji(str);

View File

@ -1,56 +0,0 @@
function CustomEvent ( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
const evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
if ( typeof window.CustomEvent !== "function" ) {
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
}
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
'use strict';
if (typeof start !== 'number') {
start = 0;
}
if (start + search.length > this.length) {
return false;
} else {
return this.indexOf(search, start) !== -1; // eslint-disable-line lodash/prefer-includes
}
};
}
if (!String.prototype.endsWith) {
String.prototype.endsWith = function (searchString, position) {
const subjectString = this.toString();
if (position === undefined || position > subjectString.length) {
position = subjectString.length;
}
position -= searchString.length;
const lastIndex = subjectString.indexOf(searchString, position);
return lastIndex !== -1 && lastIndex === position;
};
}
if (!String.prototype.startsWith) {
String.prototype.startsWith = function (searchString, position) {
position = position || 0;
return this.substr(position, searchString.length) === searchString;
};
}
if (!String.prototype.splitOnce) {
String.prototype.splitOnce = function (delimiter) {
const components = this.split(delimiter);
return [components.shift(), components.join(delimiter)];
};
}
if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
};
}

View File

@ -79,7 +79,7 @@ async function fetchTranslations (_converse) {
return;
}
const { default: data } = await import(/*webpackChunkName: "locales/[request]" */ `../i18n/${locale}/LC_MESSAGES/converse.po`);
await import(/*webpackChunkName: "locales/dayjs/[request]" */ `dayjs/locale/${dayjs_locale}`);
await import(/*webpackChunkName: "locales/dayjs/[request]" */ `dayjs/locale/${dayjs_locale}.js`);
dayjs.locale(getLocale(dayjs_locale, l => dayjs.locale(l)));
jed_instance = new Jed(data);
}

View File

@ -3,7 +3,7 @@ import log from "@converse/headless/log";
import tpl_alert_component from "templates/alert.js";
import { View } from '@converse/skeletor/src/view.js';
import { api, converse } from "@converse/headless/core";
import { render } from 'lit-html';
import { render } from 'lit';
import './styles/_modal.scss';

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { __ } from '../../i18n';
import { modal_header_close_button } from "./buttons.js"

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { modal_header_close_button } from "./buttons.js"

View File

@ -1,5 +1,5 @@
import { __ } from '../../i18n';
import { html } from "lit-html";
import { html } from "lit";
export const modal_close_button = html`<button type="button" class="btn btn-secondary" data-dismiss="modal">${__('Close')}</button>`;

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { modal_header_close_button } from "./buttons.js"

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { __ } from '../../i18n';
import { modal_close_button, modal_header_close_button } from "./buttons.js"

View File

@ -1,6 +1,6 @@
import dayjs from 'dayjs';
import { __ } from '../../i18n';
import { html } from "lit-html";
import { html } from "lit";
import { modal_close_button, modal_header_close_button } from "./buttons.js"

View File

@ -1,7 +1,7 @@
import { __ } from '../../i18n';
import { html } from "lit-html";
import { html } from "lit";
import { modal_close_button, modal_header_close_button } from "./buttons.js"
import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import xss from "xss/dist/xss";

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { __ } from '../../i18n';
import { modal_header_close_button } from "./buttons.js"

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { modal_close_button, modal_header_close_button } from "./buttons.js"
import { renderAvatar } from 'shared/directives/avatar';

View File

@ -2,7 +2,7 @@ import "shared/components/image-picker.js";
import spinner from "templates/spinner.js";
import { __ } from 'i18n';
import { _converse, converse } from "@converse/headless/core";
import { html } from "lit-html";
import { html } from "lit";
import { modal_header_close_button } from "./buttons.js";
const u = converse.env.utils;

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { __ } from '../../i18n';

View File

@ -1,6 +1,6 @@
import avatar from 'shared/templates/avatar.js';
import { __ } from 'i18n';
import { html } from 'lit-html';
import { html } from 'lit';
import { modal_close_button, modal_header_close_button } from './buttons.js'

View File

@ -1,9 +1,9 @@
import xss from "xss/dist/xss";
import { __ } from '../../i18n';
import { api } from "@converse/headless/core";
import { html } from "lit-html";
import { html } from "lit";
import { modal_header_close_button } from "./buttons.js"
import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
const tpl_navigation = (o) => {

View File

@ -2,7 +2,7 @@ import tpl_bookmarks_list from './templates/list.js';
import { ElementView } from '@converse/skeletor/src/element.js';
import { _converse, api, converse } from '@converse/headless/core';
import { initStorage } from '@converse/headless/shared/utils.js';
import { render } from 'lit-html';
import { render } from 'lit';
const { Strophe } = converse.env;
const u = converse.env.utils;

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { __ } from 'i18n';

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { __ } from 'i18n';

View File

@ -1,5 +1,5 @@
import { html } from 'lit-html';
import { repeat } from 'lit-html/directives/repeat.js';
import { html } from 'lit';
import { repeat } from 'lit/directives/repeat.js';
import { _converse, api } from '@converse/headless/core';

View File

@ -2,7 +2,7 @@ import tpl_background_logo from '../../templates/background_logo.js';
import tpl_chats from './templates/chats.js';
import { ElementView } from '@converse/skeletor/src/element.js';
import { api, _converse } from '@converse/headless/core';
import { render } from 'lit-html';
import { render } from 'lit';
class ConverseChats extends ElementView {

View File

@ -3,7 +3,7 @@ import tpl_toolbar from './templates/toolbar.js';
import { ElementView } from '@converse/skeletor/src/element.js';
import { __ } from 'i18n';
import { _converse, api, converse } from "@converse/headless/core";
import { html, render } from 'lit-html';
import { html, render } from 'lit';
import { clearMessages, parseMessageForCommands } from './utils.js';
const { u } = converse.env;

View File

@ -5,7 +5,7 @@ import { ElementView } from '@converse/skeletor/src/element.js';
import { __ } from 'i18n';
import { _converse, api } from "@converse/headless/core";
import { getHeadingDropdownItem, getHeadingStandaloneButton } from 'plugins/chatview/utils.js';
import { render } from 'lit-html';
import { render } from 'lit';
export default class ChatHeading extends ElementView {

View File

@ -1,7 +1,7 @@
import { _converse } from '@converse/headless/core';
import { html } from "lit-html";
import { html } from "lit";
import { renderAvatar } from 'shared/directives/avatar.js';
import { until } from 'lit-html/directives/until.js';
import { until } from 'lit/directives/until.js';
export default (o) => {

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
export default (o) => html`
<div class="flyout box-flyout">

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
export default (o) => html`

View File

@ -1,6 +1,6 @@
import 'shared/chat/toolbar.js';
import { api } from '@converse/headless/core.js';
import { html } from "lit-html";
import { html } from "lit";
export default (o) => {
const message_limit = api.settings.get('message_limit');

View File

@ -53,7 +53,7 @@ describe("A Chat Message", function () {
keyCode: 13 // Enter
});
expect(_converse.connection.send).toHaveBeenCalled();
await u.waitUntil(() => view.querySelector('.chat-msg__text').textContent.replace(/<!---->/g, '') === new_text);
await u.waitUntil(() => view.querySelector('.chat-msg__text').textContent.replace(/<!-.*?->/g, '') === new_text);
const msg = _converse.connection.send.calls.all()[0].args[0];
expect(msg.toLocaleString())
@ -107,7 +107,7 @@ describe("A Chat Message", function () {
keyCode: 13 // Enter
});
await u.waitUntil(() => Array.from(view.querySelectorAll('.chat-msg__text'))
.filter(m => m.textContent.replace(/<!---->/g, '') === new_text).length);
.filter(m => m.textContent.replace(/<!-.*?->/g, '') === new_text).length);
expect(view.querySelectorAll('.chat-msg').length).toBe(2);
textarea.value = 'Arise, fair sun, and kill the envious moon';
@ -345,8 +345,7 @@ describe("A Chat Message", function () {
await u.waitUntil(() => u.isVisible(modal.el), 1000);
const older_msgs = modal.el.querySelectorAll('.older-msg');
expect(older_msgs.length).toBe(2);
expect(older_msgs[0].childNodes[0].nodeName).toBe('TIME');
expect(older_msgs[0].childNodes[2].textContent).toBe('But soft, what light through yonder airlock breaks?');
expect(older_msgs[0].textContent.includes('But soft, what light through yonder airlock breaks?')).toBe(true);
expect(view.model.messages.models.length).toBe(1);
done();
}));

View File

@ -49,7 +49,7 @@ describe("A Groupchat Message", function () {
.c('reference', {'xmlns':'urn:xmpp:reference:0', 'begin':'13', 'end':'19', 'type':'mention', 'uri':'xmpp:romeo@montague.lit'}).nodeTree;
await view.model.handleMessageStanza(msg);
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 3);
await u.waitUntil(() => sizzle('.chat-msg__text:last', view).pop().innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => sizzle('.chat-msg__text:last', view).pop().innerHTML.replace(/<!-.*?->/g, '') ===
'mentions <span class="mention mention--self badge badge-info">romeo</span>');
done();
}));

View File

@ -16,7 +16,7 @@ describe("A Chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-content .chat-image').length, 1000)
expect(view.model.sendMessage).toHaveBeenCalled();
let msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop();
expect(msg.innerHTML.replace(/<!---->/g, '').trim()).toEqual(
expect(msg.innerHTML.replace(/<!-.*?->/g, '').trim()).toEqual(
`<a class="chat-image__link" target="_blank" rel="noopener" href="${base_url}/logo/conversejs-filled.svg">`+
`<img class="chat-image img-thumbnail" src="https://conversejs.org/logo/conversejs-filled.svg">`+
`</a>`);
@ -26,7 +26,7 @@ describe("A Chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-content .chat-image').length === 2, 1000);
expect(view.model.sendMessage).toHaveBeenCalled();
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop();
expect(msg.innerHTML.replace(/<!---->/g, '').trim()).toEqual(
expect(msg.innerHTML.replace(/<!-.*?->/g, '').trim()).toEqual(
`<a class="chat-image__link" target="_blank" rel="noopener" href="${base_url}/logo/conversejs-filled.svg?param1=val1&amp;param2=val2">`+
`<img class="chat-image img-thumbnail" src="${message.replace(/&/g, '&amp;')}">`+
`</a>`);
@ -91,7 +91,7 @@ describe("A Chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-content .chat-image').length, 1000)
expect(view.model.sendMessage).toHaveBeenCalled();
const msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop();
await u.waitUntil(() => msg.innerHTML.replace(/<!---->/g, '').trim() ==
await u.waitUntil(() => msg.innerHTML.replace(/<!-.*?->/g, '').trim() ==
`<a target="_blank" rel="noopener" href="https://conversejs.org/logo/non-existing.svg">https://conversejs.org/logo/non-existing.svg</a>`, 1000);
done();
}));
@ -114,7 +114,7 @@ describe("A Chat Message", function () {
expect(view.model.sendMessage).toHaveBeenCalled();
await u.waitUntil(() => view.querySelector('.chat-content .chat-msg'), 1000);
const msg = view.querySelector('.chat-content .chat-msg .chat-msg__text');
await u.waitUntil(() => msg.innerHTML.replace(/<!---->/g, '').trim() ==
await u.waitUntil(() => msg.innerHTML.replace(/<!-.*?->/g, '').trim() ==
`<a target="_blank" rel="noopener" href="https://pbs.twimg.com/media/string?format=jpg&amp;name=small">https://pbs.twimg.com/media/string?format=jpg&amp;name=small</a>`, 1000);
done();
}));

View File

@ -512,7 +512,7 @@ describe("A Chat Message", function () {
expect(view.model.sendMessage).toHaveBeenCalled();
const msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual('&lt;p&gt;This message contains &lt;em&gt;some&lt;/em&gt; &lt;b&gt;markup&lt;/b&gt;&lt;/p&gt;');
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual('&lt;p&gt;This message contains &lt;em&gt;some&lt;/em&gt; &lt;b&gt;markup&lt;/b&gt;&lt;/p&gt;');
done();
}));
@ -531,7 +531,7 @@ describe("A Chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length);
const msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
await u.waitUntil(() => msg.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg.innerHTML.replace(/<!-.*?->/g, '') ===
'This message contains a hyperlink: <a target="_blank" rel="noopener" href="http://www.opkode.com">www.opkode.com</a>');
done();
}));
@ -549,7 +549,7 @@ describe("A Chat Message", function () {
await mock.sendMessage(view, message);
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length);
let msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
await u.waitUntil(() => msg.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg.innerHTML.replace(/<!-.*?->/g, '') ===
'This message contains a hyperlink with forbidden query params: <a target="_blank" rel="noopener" href="https://www.opkode.com/?id=0">https://www.opkode.com/?id=0</a>');
// Test assigning a string to filter_url_query_params
@ -559,7 +559,7 @@ describe("A Chat Message", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 2);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
await u.waitUntil(() => msg.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg.innerHTML.replace(/<!-.*?->/g, '') ===
'Another message with a hyperlink with forbidden query params: '+
'<a target="_blank" rel="noopener" href="https://www.opkode.com/?id=0&amp;utm_content=1&amp;s=1">https://www.opkode.com/?id=0&amp;utm_content=1&amp;s=1</a>');
done();
@ -577,7 +577,7 @@ describe("A Chat Message", function () {
</message>`);
_converse.connection._dataRecv(mock.createRequest(stanza));
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length);
expect(view.querySelector('.chat-msg__text').innerHTML.replace(/<!---->/g, '')).toBe('Hey\nHave you heard the news?');
expect(view.querySelector('.chat-msg__text').innerHTML.replace(/<!-.*?->/g, '')).toBe('Hey\nHave you heard the news?');
stanza = u.toStanza(`
<message from="${contact_jid}"
type="chat"
@ -586,7 +586,7 @@ describe("A Chat Message", function () {
</message>`);
_converse.connection._dataRecv(mock.createRequest(stanza));
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 2);
const text = view.querySelector('converse-chat-message:last-child .chat-msg__text').innerHTML.replace(/<!---->/g, '');
const text = view.querySelector('converse-chat-message:last-child .chat-msg__text').innerHTML.replace(/<!-.*?->/g, '');
expect(text).toBe('Hey\n\u200B\nHave you heard the news?');
stanza = u.toStanza(`
<message from="${contact_jid}"
@ -596,7 +596,7 @@ describe("A Chat Message", function () {
</message>`);
_converse.connection._dataRecv(mock.createRequest(stanza));
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 3);
expect(view.querySelector('converse-chat-message:last-child .chat-msg__text').innerHTML.replace(/<!---->/g, '')).toBe('Hey\nHave you heard\nthe news?');
expect(view.querySelector('converse-chat-message:last-child .chat-msg__text').innerHTML.replace(/<!-.*?->/g, '')).toBe('Hey\nHave you heard\nthe news?');
stanza = u.toStanza(`
<message from="${contact_jid}"
@ -607,7 +607,7 @@ describe("A Chat Message", function () {
_converse.connection._dataRecv(mock.createRequest(stanza));
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 4);
await u.waitUntil(() => {
const text = view.querySelector('converse-chat-message:last-child .chat-msg__text').innerHTML.replace(/<!---->/g, '');
const text = view.querySelector('converse-chat-message:last-child .chat-msg__text').innerHTML.replace(/<!-.*?->/g, '');
return text === 'Hey\nHave you heard\n\u200B\nthe news?\n<a target="_blank" rel="noopener" href="https://conversejs.org/">https://conversejs.org</a>';
});
done();
@ -1301,7 +1301,7 @@ describe("A Chat Message", function () {
expect(u.hasClass('chat-msg__text', msg)).toBe(true);
expect(msg.textContent).toEqual('Have you heard this funny audio?');
let media = view.querySelector('.chat-msg .chat-msg__media');
expect(media.innerHTML.replace(/<!---->/g, '').replace(/(\r\n|\n|\r)/gm, "").trim()).toEqual(
expect(media.innerHTML.replace(/<!-.*?->/g, '').replace(/(\r\n|\n|\r)/gm, "").trim()).toEqual(
`<audio controls="" src="https://montague.lit/audio.mp3"></audio> `+
`<a target="_blank" rel="noopener" href="https://montague.lit/audio.mp3">Download audio file "audio.mp3"</a>`);
@ -1316,9 +1316,9 @@ describe("A Chat Message", function () {
_converse.connection._dataRecv(mock.createRequest(stanza));
await new Promise(resolve => view.model.messages.once('rendered', resolve));
msg = view.querySelector('.chat-msg:last-child .chat-msg__text');
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual('Have you heard this funny audio?'); // Emtpy
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual('Have you heard this funny audio?'); // Emtpy
media = view.querySelector('.chat-msg:last-child .chat-msg__media');
expect(media.innerHTML.replace(/<!---->/g, '').replace(/(\r\n|\n|\r)/gm, "").trim()).toEqual(
expect(media.innerHTML.replace(/<!-.*?->/g, '').replace(/(\r\n|\n|\r)/gm, "").trim()).toEqual(
`<audio controls="" src="https://montague.lit/audio.mp3"></audio> `+
`<a target="_blank" rel="noopener" href="https://montague.lit/audio.mp3">`+
`Download audio file "audio.mp3"</a>`);
@ -1349,8 +1349,8 @@ describe("A Chat Message", function () {
expect(msg.classList.length).toBe(1);
expect(msg.textContent).toEqual('Have you seen this funny video?');
let media = view.querySelector('.chat-msg .chat-msg__media');
expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
`<!----><video controls="" preload="metadata" style="max-height: 50vh" src="https://montague.lit/video.mp4"></video><!---->`);
expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "").replace(/<!-.*?->/g, '')).toEqual(
`<video controls="" preload="metadata" style="max-height: 50vh" src="https://montague.lit/video.mp4"></video>`);
// If the <url> and <body> contents is the same, don't duplicate.
@ -1364,10 +1364,10 @@ describe("A Chat Message", function () {
_converse.connection._dataRecv(mock.createRequest(stanza));
await new Promise(resolve => view.model.messages.once('rendered', resolve));
msg = view.querySelector('.chat-msg:last-child .chat-msg__text');
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual('Have you seen this funny video?');
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual('Have you seen this funny video?');
media = view.querySelector('.chat-msg:last-child .chat-msg__media');
expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
`<!----><video controls="" preload="metadata" style="max-height: 50vh" src="https://montague.lit/video.mp4"></video><!---->`);
expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "").replace(/<!-.*?->/g, '')).toEqual(
`<video controls="" preload="metadata" style="max-height: 50vh" src="https://montague.lit/video.mp4"></video>`);
done();
}));
@ -1395,8 +1395,8 @@ describe("A Chat Message", function () {
expect(u.hasClass('chat-msg__text', msg)).toBe(true);
expect(msg.textContent).toEqual('Have you downloaded this funny file?');
const media = view.querySelector('.chat-msg .chat-msg__media');
expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
`<!----><a target="_blank" rel="noopener" href="https://montague.lit/funny.pdf"><!---->Download file "funny.pdf"<!----></a><!---->`);
expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "").replace(/<!-.*?->/g, '')).toEqual(
`<a target="_blank" rel="noopener" href="https://montague.lit/funny.pdf">Download file "funny.pdf"</a>`);
done();
}));
@ -1428,7 +1428,7 @@ describe("A Chat Message", function () {
expect(u.hasClass('chat-msg__text', msg)).toBe(true);
expect(msg.textContent).toEqual('Have you seen this funny image?');
const media = view.querySelector('.chat-msg .chat-msg__media');
expect(media.innerHTML.replace(/<!---->/g, '').replace(/(\r\n|\n|\r)/gm, "")).toEqual(
expect(media.innerHTML.replace(/<!-.*?->/g, '').replace(/(\r\n|\n|\r)/gm, "")).toEqual(
`<a target="_blank" rel="noopener" href="${base_url}/logo/conversejs-filled.svg">`+
`Download image file "conversejs-filled.svg"</a>`);
done();

View File

@ -19,44 +19,44 @@ describe("XSS", function () {
await mock.sendMessage(view, message);
let msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual("&lt;img src=x onerror=alert('XSS');&gt;");
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual("&lt;img src=x onerror=alert('XSS');&gt;");
expect(window.alert).not.toHaveBeenCalled();
message = "<img src=x onerror=alert('XSS')//";
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual("&lt;img src=x onerror=alert('XSS')//");
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual("&lt;img src=x onerror=alert('XSS')//");
message = "<img src=x onerror=alert(String.fromCharCode(88,83,83));>";
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual("&lt;img src=x onerror=alert(String.fromCharCode(88,83,83));&gt;");
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual("&lt;img src=x onerror=alert(String.fromCharCode(88,83,83));&gt;");
message = "<img src=x oneonerrorrror=alert(String.fromCharCode(88,83,83));>";
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual("&lt;img src=x oneonerrorrror=alert(String.fromCharCode(88,83,83));&gt;");
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual("&lt;img src=x oneonerrorrror=alert(String.fromCharCode(88,83,83));&gt;");
message = "<img src=x:alert(alt) onerror=eval(src) alt=xss>";
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual("&lt;img src=x:alert(alt) onerror=eval(src) alt=xss&gt;");
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual("&lt;img src=x:alert(alt) onerror=eval(src) alt=xss&gt;");
message = "><img src=x onerror=alert('XSS');>";
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual("&gt;&lt;img src=x onerror=alert('XSS');&gt;");
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual("&gt;&lt;img src=x onerror=alert('XSS');&gt;");
message = "><img src=x onerror=alert(String.fromCharCode(88,83,83));>";
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual("&gt;&lt;img src=x onerror=alert(String.fromCharCode(88,83,83));&gt;");
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual("&gt;&lt;img src=x onerror=alert(String.fromCharCode(88,83,83));&gt;");
expect(window.alert).not.toHaveBeenCalled();
done();
@ -75,43 +75,43 @@ describe("XSS", function () {
await mock.sendMessage(view, message);
let msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual('&lt;svg onload=alert(1)&gt;');
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual('&lt;svg onload=alert(1)&gt;');
message = "<svg/onload=alert('XSS')>";
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual("&lt;svg/onload=alert('XSS')&gt;");
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual("&lt;svg/onload=alert('XSS')&gt;");
message = "<svg onload=alert(1)//";
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual("&lt;svg onload=alert(1)//");
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual("&lt;svg onload=alert(1)//");
message = "<svg/onload=alert(String.fromCharCode(88,83,83))>";
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual("&lt;svg/onload=alert(String.fromCharCode(88,83,83))&gt;");
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual("&lt;svg/onload=alert(String.fromCharCode(88,83,83))&gt;");
message = "<svg id=alert(1) onload=eval(id)>";
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual("&lt;svg id=alert(1) onload=eval(id)&gt;");
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual("&lt;svg id=alert(1) onload=eval(id)&gt;");
message = '"><svg/onload=alert(String.fromCharCode(88,83,83))>';
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual('"&gt;&lt;svg/onload=alert(String.fromCharCode(88,83,83))&gt;');
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual('"&gt;&lt;svg/onload=alert(String.fromCharCode(88,83,83))&gt;');
message = '"><svg/onload=alert(/XSS/)';
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual('"&gt;&lt;svg/onload=alert(/XSS/)');
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual('"&gt;&lt;svg/onload=alert(/XSS/)');
expect(window.alert).not.toHaveBeenCalled();
done();
@ -132,43 +132,43 @@ describe("XSS", function () {
let msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML.replace(/<!---->/g, ''))
expect(msg.innerHTML.replace(/<!-.*?->/g, ''))
.toEqual('http://www.opkode.com/\'onmouseover=\'alert(1)\'whatever');
await u.waitUntil(() => msg.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg.innerHTML.replace(/<!-.*?->/g, '') ===
'<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';
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
await u.waitUntil(() => msg.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg.innerHTML.replace(/<!-.*?->/g, '') ===
'<a target="_blank" rel="noopener" href="http://www.opkode.com/%22onmouseover=%22alert%281%29%22whatever">http://www.opkode.com/"onmouseover="alert(1)"whatever</a>');
message = "https://en.wikipedia.org/wiki/Ender's_Game";
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
await u.waitUntil(() => msg.innerHTML.replace(/<!---->/g, '') === '<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Ender%27s_Game">'+message+'</a>');
await u.waitUntil(() => msg.innerHTML.replace(/<!-.*?->/g, '') === '<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Ender%27s_Game">'+message+'</a>');
message = "<https://bugs.documentfoundation.org/show_bug.cgi?id=123737>";
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
await u.waitUntil(() => msg.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg.innerHTML.replace(/<!-.*?->/g, '') ===
`&lt;<a target="_blank" rel="noopener" href="https://bugs.documentfoundation.org/show_bug.cgi?id=123737">https://bugs.documentfoundation.org/show_bug.cgi?id=123737</a>&gt;`);
message = '<http://www.opkode.com/"onmouseover="alert(1)"whatever>';
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
await u.waitUntil(() => msg.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg.innerHTML.replace(/<!-.*?->/g, '') ===
'&lt;<a target="_blank" rel="noopener" href="http://www.opkode.com/%22onmouseover=%22alert%281%29%22whatever">http://www.opkode.com/"onmouseover="alert(1)"whatever</a>&gt;');
message = `https://www.google.com/maps/place/Kochstraat+6,+2041+CE+Zandvoort/@52.3775999,4.548971,3a,15y,170.85h,88.39t/data=!3m6!1e1!3m4!1sQ7SdHo_bPLPlLlU8GSGWaQ!2e0!7i13312!8i6656!4m5!3m4!1s0x47c5ec1e56f845ad:0x1de0bc4a5771fb08!8m2!3d52.3773668!4d4.5489388!5m1!1e2`
await mock.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(message);
await u.waitUntil(() => msg.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg.innerHTML.replace(/<!-.*?->/g, '') ===
`<a target="_blank" rel="noopener" href="https://www.google.com/maps/place/Kochstraat+6,+2041+CE+Zandvoort/@52.3775999,4.548971,3a,15y,170.85h,88.39t/data=%213m6%211e1%213m4%211sQ7SdHo_bPLPlLlU8GSGWaQ%212e0%217i13312%218i6656%214m5%213m4%211s0x47c5ec1e56f845ad:0x1de0bc4a5771fb08%218m2%213d52.3773668%214d4.5489388%215m1%211e2">https://www.google.com/maps/place/Kochstraat+6,+2041+CE+Zandvoort/@52.3775999,4.548971,3a,15y,170.85h,88.39t/data=!3m6!1e1!3m4!1sQ7SdHo_bPLPlLlU8GSGWaQ!2e0!7i13312!8i6656!4m5!3m4!1s0x47c5ec1e56f845ad:0x1de0bc4a5771fb08!8m2!3d52.3773668!4d4.5489388!5m1!1e2</a>`);
done();
}));
@ -211,19 +211,19 @@ describe("XSS", function () {
function checkNonParsedURL (url) {
const msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(url);
expect(msg.innerHTML.replace(/<!---->/g, '')).toEqual(url);
expect(msg.innerHTML.replace(/<!-.*?->/g, '')).toEqual(url);
}
async function checkParsedURL ({ entered, href }) {
const msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent).toEqual(entered);
await u.waitUntil(() => msg.innerHTML.replace(/<!---->/g, '') === `<a target="_blank" rel="noopener" href="${href}">${entered}</a>`);
await u.waitUntil(() => msg.innerHTML.replace(/<!-.*?->/g, '') === `<a target="_blank" rel="noopener" href="${href}">${entered}</a>`);
}
async function checkParsedXMPPURL ({ entered, href }) {
const msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
expect(msg.textContent.trim()).toEqual(entered);
await u.waitUntil(() => msg.innerHTML.replace(/<!---->/g, '').trim() === `<a target="_blank" rel="noopener" href="${href}">${entered}</a>`);
await u.waitUntil(() => msg.innerHTML.replace(/<!-.*?->/g, '').trim() === `<a target="_blank" rel="noopener" href="${href}">${entered}</a>`);
}
await mock.sendMessage(view, bad_urls[0]);

View File

@ -1,6 +1,6 @@
import { __ } from 'i18n';
import { _converse } from "@converse/headless/core";
import { html } from 'lit-html';
import { html } from 'lit';
export async function getHeadingDropdownItem (promise_or_data) {

View File

@ -1,6 +1,6 @@
import 'plugins/chatview/heading.js';
import 'plugins/chatview/bottom-panel.js';
import { html, render } from 'lit-html';
import { html, render } from 'lit';
import BaseChatView from 'shared/chat/baseview.js';
import tpl_chat from './templates/chat.js';
import { __ } from 'i18n';

View File

@ -1,7 +1,7 @@
import tpl_controlbox from './templates/controlbox.js';
import { ElementView } from '@converse/skeletor/src/element.js';
import { _converse, api, converse } from '@converse/headless/core';
import { render } from 'lit-html';
import { render } from 'lit';
const u = converse.env.utils;

View File

@ -4,7 +4,7 @@ import { ElementView } from "@converse/skeletor/src/element";
import { Model } from '@converse/skeletor/src/model.js';
import { __ } from 'i18n';
import { _converse, api, converse } from "@converse/headless/core";
import { render } from 'lit-html';
import { render } from 'lit';
const u = converse.env.utils;
const { Strophe } = converse.env;

View File

@ -1,4 +1,4 @@
import { html } from 'lit-html';
import { html } from 'lit';
import { _converse, api } from "@converse/headless/core";
export default o => html`

View File

@ -2,7 +2,7 @@ import 'shared/components/brand-heading.js';
import tpl_spinner from 'templates/spinner.js';
import { __ } from 'i18n';
import { _converse, api } from "@converse/headless/core";
import { html } from "lit-html";
import { html } from "lit";
const trust_checkbox = (checked) => {

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { navigateToControlBox } from '../utils.js';
export default (jid) => {

View File

@ -1,6 +1,6 @@
import { __ } from 'i18n';
import { api } from "@converse/headless/core";
import { html } from "lit-html";
import { html } from "lit";
export default (o) => {
const i18n_toggle = api.connection.connected() ? __('Chat Contacts') : __('Toggle chat');

View File

@ -1,4 +1,4 @@
import { html } from 'lit-html';
import { html } from 'lit';
import { onStartDiagonalResize, onStartHorizontalResize, onStartVerticalResize } from '../utils.js';
export default () => html`

View File

@ -5,7 +5,7 @@
*/
import '../chatview/index.js';
import './view.js';
import { HeadlinesPanelMixin, HeadlinesPanel } from './panel.js';
import { HeadlinesPanel } from './panel.js';
import { _converse, converse } from '@converse/headless/core';
import './styles/headlines.scss';
@ -25,7 +25,6 @@ converse.plugins.add('converse-headlines-view', {
dependencies: ['converse-headlines', 'converse-chatview'],
initialize () {
_converse.ControlBoxView && Object.assign(_converse.ControlBoxView.prototype, HeadlinesPanelMixin);
_converse.HeadlinesPanel = HeadlinesPanel;
}
});

View File

@ -1,6 +1,6 @@
import { _converse } from '@converse/headless/core';
import { html } from "lit-html";
import { until } from 'lit-html/directives/until.js';
import { html } from "lit";
import { until } from 'lit/directives/until.js';
export default (o) => {

View File

@ -1,5 +1,5 @@
import '../heading.js';
import { html } from "lit-html";
import { html } from "lit";
export default (o) => html`
<div class="flyout box-flyout">

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import tpl_headline_list from "templates/headline_list.js";

View File

@ -1,7 +1,7 @@
import BaseChatView from 'shared/chat/baseview.js';
import tpl_headlines from './templates/headlines.js';
import { _converse, api } from '@converse/headless/core';
import { render } from 'lit-html';
import { render } from 'lit';
class HeadlinesView extends BaseChatView {

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { __ } from 'i18n';
export default (o) =>

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { __ } from 'i18n';

View File

@ -198,7 +198,7 @@ describe("A Minimized ChatBoxView's Unread Message Count", function () {
_converse.minimize.minimize(view.model);
const unread_count = selectUnreadMsgCount();
expect(u.isVisible(unread_count)).toBeTruthy();
expect(unread_count.innerHTML.replace(/<!---->/g, '')).toBe('1');
expect(unread_count.innerHTML.replace(/<!-.*?->/g, '')).toBe('1');
done();
}));
@ -216,7 +216,7 @@ describe("A Minimized ChatBoxView's Unread Message Count", function () {
await u.waitUntil(() => view.model.messages.length);
const unread_count = selectUnreadMsgCount();
expect(u.isVisible(unread_count)).toBeTruthy();
expect(unread_count.innerHTML.replace(/<!---->/g, '')).toBe('1');
expect(unread_count.innerHTML.replace(/<!-.*?->/g, '')).toBe('1');
done();
}));
@ -233,7 +233,7 @@ describe("A Minimized ChatBoxView's Unread Message Count", function () {
await u.waitUntil(() => view.querySelectorAll('.chat-content .chat-msg').length, 1000);
expect(view.model.sendMessage).toHaveBeenCalled();
const msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop();
await u.waitUntil(() => msg.innerHTML.replace(/\<!----\>/g, '') ===
await u.waitUntil(() => msg.innerHTML.replace(/\<!-.*?-\>/g, '') ===
'<a target="_blank" rel="noopener" href="https://www.openstreetmap.org/?mlat=37.786971&amp;'+
'mlon=-122.399677#map=18/37.786971/-122.399677">https://www.openstreetmap.org/?mlat=37.786971&amp;mlon=-122.399677#map=18/37.786971/-122.399677</a>');
done();

View File

@ -3,10 +3,10 @@ import tpl_chats_panel from './templates/chats-panel.js';
import { ElementView } from '@converse/skeletor/src/element.js';
import { _converse, api } from '@converse/headless/core';
import { initStorage } from '@converse/headless/shared/utils.js';
import { render } from 'lit-html';
import { render } from 'lit';
class MinimizedChats extends ElementView {
export default class MinimizedChats extends ElementView {
async initialize () {
this.model = _converse.chatboxes;

View File

@ -5,7 +5,7 @@ import tpl_muc_bottom_panel from './templates/muc-bottom-panel.js';
import { __ } from 'i18n';
import { _converse, api, converse } from "@converse/headless/core";
import { getAutoCompleteListItem, parseMessageForMUCCommands } from './utils.js';
import { render } from 'lit-html';
import { render } from 'lit';
export default class MUCBottomPanel extends BottomPanel {

View File

@ -5,7 +5,7 @@ import tpl_muc from './templates/muc.js';
import { Model } from '@converse/skeletor/src/model.js';
import { __ } from 'i18n';
import { _converse, api, converse } from '@converse/headless/core';
import { html, render } from "lit-html";
import { html, render } from "lit";
/**
* Mixin which turns a ChatBoxView into a ChatRoomView

View File

@ -1,5 +1,5 @@
import { __ } from 'i18n';
import { html } from "lit-html";
import { html } from "lit";
export default (o, command) => {
const i18n_hide = __('Hide');

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import tpl_command_form from './ad-hoc-command-form.js';
export default (o, command) => html`

View File

@ -1,7 +1,7 @@
import tpl_command from './ad-hoc-command.js';
import { __ } from 'i18n';
import { getAutoCompleteList } from '../utils.js';
import { html } from "lit-html";
import { html } from "lit";
export default (o) => {

View File

@ -1,8 +1,8 @@
import xss from "xss/dist/xss";
import { __ } from 'i18n';
import { html } from "lit-html";
import { html } from "lit";
import { modal_header_close_button } from "modals/templates/buttons.js"
import { unsafeHTML } from "lit-html/directives/unsafe-html.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
const nickname_input = (o) => {

View File

@ -1,6 +1,6 @@
import spinner from "templates/spinner.js";
import { __ } from 'i18n';
import { html } from "lit-html";
import { html } from "lit";
import { modal_header_close_button } from "modals/templates/buttons.js"

View File

@ -1,7 +1,7 @@
import tpl_muc_nickname_form from './muc-nickname-form.js';
import { __ } from 'i18n';
import { api, converse } from "@converse/headless/core";
import { html } from "lit-html";
import { html } from "lit";
const tpl_can_edit = () => html`

View File

@ -3,7 +3,7 @@ import '../sidebar.js';
import 'shared/chat/chat-content.js';
import 'shared/chat/help-messages.js';
import { _converse } from '@converse/headless/core';
import { html } from "lit-html";
import { html } from "lit";
export default (o) => html`
<div class="chat-area">

View File

@ -1,7 +1,7 @@
import tpl_spinner from 'templates/spinner.js';
import { __ } from 'i18n';
import { api, converse } from "@converse/headless/core";
import { html } from "lit-html";
import { html } from "lit";
const { sizzle } = converse.env;
const u = converse.env.utils;

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { __ } from 'i18n';
export default (o) => {

View File

@ -1,5 +1,5 @@
import { __ } from 'i18n';
import { html } from "lit-html";
import { html } from "lit";
const tpl_moved = (o) => {
const i18n_moved = __('The conversation has moved to a new address. Click the link below to enter.');

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
export default (messages) => {

View File

@ -2,8 +2,8 @@ import 'shared/components/dropdown.js';
import 'shared/components/rich-text.js';
import { __ } from 'i18n';
import { _converse } from "@converse/headless/core";
import { html } from "lit-html";
import { until } from 'lit-html/directives/until.js';
import { html } from "lit";
import { until } from 'lit/directives/until.js';
const tpl_standalone_btns = (o) => o.standalone_btns.reverse().map(b => until(b, ''));

View File

@ -1,6 +1,6 @@
import { __ } from 'i18n';
import { html } from "lit-html";
import { repeat } from 'lit-html/directives/repeat.js';
import { html } from "lit";
import { repeat } from 'lit/directives/repeat.js';
import { modal_close_button, modal_header_close_button } from "modals/templates/buttons.js"
import spinner from "templates/spinner.js";

View File

@ -1,6 +1,6 @@
import { __ } from 'i18n';
import { api } from "@converse/headless/core";
import { html } from "lit-html";
import { html } from "lit";
function submitNickname (ev, model) {
ev.preventDefault();

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { __ } from 'i18n';

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { __ } from 'i18n';
import tpl_occupant from "./occupant.js";

View File

@ -5,7 +5,7 @@ import '../disconnected.js';
import '../heading.js';
import '../nickname-form.js';
import '../password-form.js';
import { html } from "lit-html";
import { html } from "lit";
import { getChatRoomBodyTemplate } from '../utils.js';

View File

@ -1,4 +1,4 @@
import { html } from "lit-html";
import { html } from "lit";
import { __ } from 'i18n';

View File

@ -64,10 +64,8 @@ describe("A Groupchat Message", function () {
await u.waitUntil(() => u.isVisible(modal.el), 1000);
const older_msgs = modal.el.querySelectorAll('.older-msg');
expect(older_msgs.length).toBe(2);
expect(older_msgs[0].childNodes[2].textContent).toBe('But soft, what light through yonder airlock breaks?');
expect(older_msgs[0].childNodes[0].nodeName).toBe('TIME');
expect(older_msgs[1].childNodes[0].nodeName).toBe('TIME');
expect(older_msgs[1].childNodes[2].textContent).toBe('But soft, what light through yonder chimney breaks?');
expect(older_msgs[0].textContent.includes('But soft, what light through yonder airlock breaks?')).toBe(true);
expect(older_msgs[1].textContent.includes('But soft, what light through yonder chimney breaks?')).toBe(true);
done();
}));
@ -158,10 +156,8 @@ describe("A Groupchat Message", function () {
await u.waitUntil(() => u.isVisible(modal.el), 1000);
const older_msgs = modal.el.querySelectorAll('.older-msg');
expect(older_msgs.length).toBe(2);
expect(older_msgs[0].childNodes[2].textContent).toBe('But soft, what light through yonder airlock breaks?');
expect(older_msgs[0].childNodes[0].nodeName).toBe('TIME');
expect(older_msgs[1].childNodes[0].nodeName).toBe('TIME');
expect(older_msgs[1].childNodes[2].textContent).toBe('But soft, what light through yonder chimney breaks?');
expect(older_msgs[0].textContent.includes('But soft, what light through yonder airlock breaks?')).toBe(true);
expect(older_msgs[1].textContent.includes('But soft, what light through yonder chimney breaks?')).toBe(true);
done();
}));
@ -211,7 +207,7 @@ describe("A Groupchat Message", function () {
});
expect(_converse.connection.send).toHaveBeenCalled();
await u.waitUntil(() => Array.from(view.querySelectorAll('.chat-msg__text'))
.filter(m => m.textContent.replace(/<!---->/g, '') === new_text).length);
.filter(m => m.textContent.replace(/<!-.*?->/g, '') === new_text).length);
const msg = _converse.connection.send.calls.all()[0].args[0];
expect(msg.toLocaleString())

View File

@ -58,7 +58,7 @@ describe("An incoming groupchat message", function () {
.c('reference', {'xmlns':'urn:xmpp:reference:0', 'begin':'11', 'end':'14', 'type':'mention', 'uri':'xmpp:romeo@montague.lit'}).up()
.c('reference', {'xmlns':'urn:xmpp:reference:0', 'begin':'15', 'end':'23', 'type':'mention', 'uri':'xmpp:mr.robot@montague.lit'}).nodeTree;
await view.model.handleMessageStanza(msg);
await u.waitUntil(() => view.querySelector('.chat-msg__text')?.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => view.querySelector('.chat-msg__text')?.innerHTML.replace(/<!-.*?->/g, '') ===
'hello <span class="mention">z3r0</span> '+
'<span class="mention mention--self badge badge-info">tom</span> '+
'<span class="mention">mr.robot</span>, how are you?');
@ -75,7 +75,7 @@ describe("An incoming groupchat message", function () {
await view.model.handleMessageStanza(msg);
message = await u.waitUntil(() => view.querySelector('.chat-msg__text'));
expect(message.classList.length).toEqual(1);
expect(message.innerHTML.replace(/<!---->/g, '')).toBe(
expect(message.innerHTML.replace(/<!-.*?->/g, '')).toBe(
'hello <span class="mention">z3r0</span> '+
'<span class="mention mention--self badge badge-info">tom</span> '+
'<span class="mention">mr.robot</span>, how are you?');
@ -113,7 +113,7 @@ describe("An incoming groupchat message", function () {
.c('reference', {'xmlns':'urn:xmpp:reference:0', 'begin':'16', 'end':'24', 'type':'mention', 'uri':'xmpp:mr.robot@montague.lit'}).nodeTree;
await view.model.handleMessageStanza(msg);
await u.waitUntil(() => view.querySelector('.chat-msg__text')?.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => view.querySelector('.chat-msg__text')?.innerHTML.replace(/<!-.*?->/g, '') ===
'<blockquote>hello <span class="mention">z3r0</span> <span class="mention mention--self badge badge-info">tom</span> <span class="mention">mr.robot</span>, how are you?</blockquote>');
const message = view.querySelector('.chat-msg__text');
expect(message.classList.length).toEqual(1);
@ -380,7 +380,7 @@ describe("A sent groupchat message", function () {
const last_msg_sel = 'converse-chat-message:last-child .chat-msg__text';
await u.waitUntil(() =>
view.querySelector(last_msg_sel).innerHTML.replace(/<!---->/g, '') ===
view.querySelector(last_msg_sel).innerHTML.replace(/<!-.*?->/g, '') ===
'hello <span class="mention">z3r0</span> <span class="mention">gibson</span> <span class="mention">mr.robot</span>, how are you?'
);
@ -496,7 +496,7 @@ describe("A sent groupchat message", function () {
const bottom_panel = view.querySelector('converse-muc-bottom-panel');
bottom_panel.onKeyDown(enter_event);
const message = await u.waitUntil(() => view.querySelector('.chat-msg__text'));
expect(message.innerHTML.replace(/<!---->/g, '')).toEqual(
expect(message.innerHTML.replace(/<!-.*?->/g, '')).toEqual(
`Welcome <span class="mention">gibson</span> <span title=":poop:">💩</span> `+
`We have a guide on how to do that here: `+
`<a target="_blank" rel="noopener" href="https://conversejs.org/docs/html/index.html">https://conversejs.org/docs/html/index.html</a>`);

View File

@ -25,7 +25,7 @@ describe("A outgoing groupchat Message", function () {
const msg_el = Array.from(view.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text);
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
'This <span class="styling-directive">*</span><b>message mentions <span class="mention mention--self badge badge-info">romeo</span></b><span class="styling-directive">*</span>');
done();
}));

View File

@ -2,7 +2,7 @@ import log from "@converse/headless/log";
import tpl_spinner from 'templates/spinner.js';
import { __ } from 'i18n';
import { _converse, api, converse } from "@converse/headless/core";
import { html } from "lit-html";
import { html } from "lit";
import { parseMessageForCommands } from 'plugins/chatview/utils.js';
import { setAffiliation } from '@converse/headless/plugins/muc/affiliations/utils.js';

View File

@ -3,7 +3,7 @@ import difference from 'lodash-es/difference';
import log from '@converse/headless/log';
import { __ } from 'i18n';
import { _converse, converse, api } from '@converse/headless/core';
import { html } from 'lit-html';
import { html } from 'lit';
import { initStorage } from '@converse/headless/shared/utils.js';
const { Strophe, sizzle, u } = converse.env;

View File

@ -2,13 +2,13 @@
* @copyright The Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
import "modals/chat-status.js";
import "modals/profile.js";
import "../modal.js";
import "@converse/headless/plugins/status";
import "@converse/headless/plugins/vcard";
import XMPPStatusView from './statusview.js';
import { _converse, api, converse } from "@converse/headless/core";
import '../modal.js';
import './statusview.js';
import '@converse/headless/plugins/status';
import '@converse/headless/plugins/vcard';
import 'modals/chat-status.js';
import 'modals/profile.js';
import { api, converse } from '@converse/headless/core';
converse.plugins.add('converse-profile', {
@ -20,7 +20,5 @@ converse.plugins.add('converse-profile', {
'allow_adhoc_commands': true,
'show_client_info': true
});
_converse.XMPPStatusView = XMPPStatusView;
}
});

View File

@ -3,7 +3,7 @@ import tpl_profile from './templates/profile.js';
import { ElementViewWithAvatar } from 'shared/avatar.js';
import { __ } from 'i18n';
import { _converse, api } from '@converse/headless/core';
import { render } from 'lit-html';
import { render } from 'lit';
function getPrettyStatus (stat) {

View File

@ -1,6 +1,6 @@
import { __ } from 'i18n';
import { api } from "@converse/headless/core";
import { html } from "lit-html";
import { html } from "lit";
export default (o) => {

View File

@ -9,7 +9,7 @@ import utils from "@converse/headless/utils/form";
import { ElementView } from "@converse/skeletor/src/element";
import { __ } from 'i18n';
import { _converse, api, converse } from "@converse/headless/core";
import { render } from 'lit-html';
import { render } from 'lit';
// Strophe methods for building stanzas
const { Strophe, sizzle, $iq } = converse.env;

View File

@ -2,7 +2,7 @@ import tpl_registration_form from './registration_form.js';
import tpl_spinner from 'templates/spinner.js';
import { __ } from 'i18n';
import { api } from '@converse/headless/core';
import { html } from 'lit-html';
import { html } from 'lit';
const tpl_form_request = () => {
const default_domain = api.settings.get('registration_domain');

View File

@ -1,6 +1,6 @@
import { __ } from 'i18n';
import { api } from '@converse/headless/core';
import { html } from 'lit-html';
import { html } from 'lit';
export default o => {
const i18n_choose_provider = __('Choose a different provider');

View File

@ -2,7 +2,7 @@ import AddMUCModal from 'plugins/muc-views/modals/add-muc.js';
import MUCListModal from 'plugins/muc-views/modals/muc-list.js';
import { __ } from 'i18n';
import { _converse, api } from "@converse/headless/core";
import { html } from "lit-html";
import { html } from "lit";
const bookmark = (o) => {

View File

@ -5,7 +5,7 @@ import { Model } from '@converse/skeletor/src/model.js';
import { __ } from 'i18n';
import { _converse, api, converse } from "@converse/headless/core";
import { initStorage } from '@converse/headless/shared/utils.js';
import { render } from 'lit-html';
import { render } from 'lit';
const { Strophe } = converse.env;
const u = converse.env.utils;

View File

@ -1,6 +1,6 @@
import 'shared/components/font-awesome.js';
import { api } from '@converse/headless/core';
import { html } from 'lit-html';
import { html } from 'lit';
export default () => {
let extra_classes = api.settings.get('singleton') ? 'converse-singleton' : '';

View File

@ -9,7 +9,7 @@ import { _converse, api, converse } from "@converse/headless/core";
const u = converse.env.utils;
class RosterContact extends CustomElement {
export default class RosterContact extends CustomElement {
static get properties () {
return {

View File

@ -4,7 +4,7 @@ import { ElementView } from '@converse/skeletor/src/element.js';
import { Model } from '@converse/skeletor/src/model.js';
import { _converse, api } from "@converse/headless/core";
import { initStorage } from '@converse/headless/shared/utils.js';
import { render } from 'lit-html';
import { render } from 'lit';
export const RosterFilter = Model.extend({
initialize () {

View File

@ -3,7 +3,7 @@ import tpl_roster from "./templates/roster.js";
import { ElementView } from "@converse/skeletor/src/element";
import { Model } from '@converse/skeletor/src/model.js';
import { _converse, api, converse } from "@converse/headless/core";
import { render } from 'lit-html';
import { render } from 'lit';
const u = converse.env.utils;

View File

@ -1,6 +1,6 @@
import { __ } from 'i18n';
import { _converse, converse } from "@converse/headless/core";
import { html } from "lit-html";
import { html } from "lit";
import { toggleGroup } from '../utils.js';
const { u } = converse.env;

View File

@ -1,6 +1,6 @@
import { __ } from 'i18n';
import { api } from "@converse/headless/core";
import { html } from "lit-html";
import { html } from "lit";
const tpl_pending_contact = o => html`<span class="pending-contact-name" title="JID: ${o.jid}">${o.display_name}</span>`;

Some files were not shown because too many files have changed in this diff Show More