Styling: quotes should start on newlines

And when nested, have no spaces between them.
This commit is contained in:
JC Brand 2020-12-09 14:19:31 +01:00
parent 240fab99f4
commit 58586ab2e4
2 changed files with 28 additions and 5 deletions

View File

@ -269,13 +269,21 @@ describe("An incoming chat Message", function () {
'This is <span class="styling-directive">`</span><code>also _quoted_</code><span class="styling-directive">`</span></blockquote>\n'+
'This is not quoted');
msg_text = `> > This is doubly quoted text`;
msg_text = `> > This is NOT doubly quoted text`;
msg = mock.createChatMessage(_converse, contact_jid, msg_text)
await _converse.handleMessageStanza(msg);
await new Promise(resolve => view.model.messages.once('rendered', resolve));
msg_el = Array.from(view.el.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> &gt; This is NOT doubly quoted text</blockquote>");
msg_text = `>> This is doubly quoted text`;
msg = mock.createChatMessage(_converse, contact_jid, msg_text)
await _converse.handleMessageStanza(msg);
await new Promise(resolve => view.model.messages.once('rendered', resolve));
msg_el = Array.from(view.el.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>");
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)
@ -320,7 +328,7 @@ describe("An incoming chat Message", function () {
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>');
'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>');
msg_text = '> What do you think of it?\n :poop:';
msg = mock.createChatMessage(_converse, contact_jid, msg_text)
@ -339,6 +347,14 @@ describe("An incoming chat Message", function () {
expect(msg_el.innerText).toBe(msg_text);
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';
msg = mock.createChatMessage(_converse, contact_jid, msg_text)
await _converse.handleMessageStanza(msg);
await new Promise(resolve => view.model.messages.once('rendered', resolve));
msg_el = Array.from(view.el.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');
done();
}));
});

View File

@ -34,7 +34,6 @@ const styling_templates = {
/**
* Checks whether a given character "d" at index "i" of "text" is a valid opening or closing directive.
* It's valid if it's not part of a word.
* @param { String } d - The potential directive
* @param { String } text - The text in which the directive appears
* @param { Number } i - The directive index
@ -48,6 +47,14 @@ function isValidDirective (d, text, i, opening) {
if (i > 1 && regex.test(text.slice(i-1))) {
return false;
}
const is_quote = isQuoteDirective(d);
if (is_quote && i > 0 && text[i-1] !== '\n') {
// Quote directives must be on newlines
return false;
} else if (!is_quote && d === text[i+1]) {
// Immediately followed by another directive of the same type
return false;
}
} else {
const regex = RegExp(dont_escape.includes(d) ? `^${d}(\\p{L}|\\p{N})` : `^\\${d}(\\p{L}|\\p{N})`, 'u');
if (i < text.length-1 && regex.test(text.slice(i))) {
@ -68,7 +75,7 @@ function getDirective (text, i, opening=true) {
let d;
if ((/(^```\s*\n|^```\s*$)/).test(text.slice(i)) && (i === 0 || text[i-1] === '\n' || text[i-1] === '>')) {
d = text.slice(i, i+3);
} else if (styling_directives.includes(text.slice(i, i+1)) && text[i] !== text[i+1]) {
} else if (styling_directives.includes(text.slice(i, i+1))) {
d = text.slice(i, i+1);
if (!isValidDirective(d, text, i, opening)) return null;
} else {