Commit 58586ab2 authored by JC Brand's avatar JC Brand

Styling: quotes should start on newlines

And when nested, have no spaces between them.
parent 240fab99
...@@ -269,13 +269,21 @@ describe("An incoming chat Message", function () { ...@@ -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 <span class="styling-directive">`</span><code>also _quoted_</code><span class="styling-directive">`</span></blockquote>\n'+
'This is not quoted'); '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) msg = mock.createChatMessage(_converse, contact_jid, msg_text)
await _converse.handleMessageStanza(msg); await _converse.handleMessageStanza(msg);
await new Promise(resolve => view.model.messages.once('rendered', resolve)); await new Promise(resolve => view.model.messages.once('rendered', resolve));
msg_el = Array.from(view.el.querySelectorAll('converse-chat-message-body')).pop(); msg_el = Array.from(view.el.querySelectorAll('converse-chat-message-body')).pop();
expect(msg_el.innerText).toBe(msg_text); 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_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) msg = mock.createChatMessage(_converse, contact_jid, msg_text)
...@@ -320,7 +328,7 @@ describe("An incoming chat Message", function () { ...@@ -320,7 +328,7 @@ describe("An incoming chat Message", function () {
await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') === await u.waitUntil(() => msg_el.innerHTML.replace(/<!---->/g, '') ===
'<blockquote> Where is it located?</blockquote>\n'+ '<blockquote> Where is it located?</blockquote>\n'+
'<a target="_blank" rel="noopener" '+ '<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_text = '> What do you think of it?\n :poop:';
msg = mock.createChatMessage(_converse, contact_jid, msg_text) msg = mock.createChatMessage(_converse, contact_jid, msg_text)
...@@ -339,6 +347,14 @@ describe("An incoming chat Message", function () { ...@@ -339,6 +347,14 @@ describe("An incoming chat Message", function () {
expect(msg_el.innerText).toBe(msg_text); 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>'); '<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(); done();
})); }));
}); });
......
...@@ -34,7 +34,6 @@ const styling_templates = { ...@@ -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. * 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 } d - The potential directive
* @param { String } text - The text in which the directive appears * @param { String } text - The text in which the directive appears
* @param { Number } i - The directive index * @param { Number } i - The directive index
...@@ -48,6 +47,14 @@ function isValidDirective (d, text, i, opening) { ...@@ -48,6 +47,14 @@ function isValidDirective (d, text, i, opening) {
if (i > 1 && regex.test(text.slice(i-1))) { if (i > 1 && regex.test(text.slice(i-1))) {
return false; 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 { } else {
const regex = RegExp(dont_escape.includes(d) ? `^${d}(\\p{L}|\\p{N})` : `^\\${d}(\\p{L}|\\p{N})`, 'u'); 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))) { if (i < text.length-1 && regex.test(text.slice(i))) {
...@@ -68,7 +75,7 @@ function getDirective (text, i, opening=true) { ...@@ -68,7 +75,7 @@ function getDirective (text, i, opening=true) {
let d; let d;
if ((/(^```\s*\n|^```\s*$)/).test(text.slice(i)) && (i === 0 || text[i-1] === '\n' || text[i-1] === '>')) { if ((/(^```\s*\n|^```\s*$)/).test(text.slice(i)) && (i === 0 || text[i-1] === '\n' || text[i-1] === '>')) {
d = text.slice(i, i+3); 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); d = text.slice(i, i+1);
if (!isValidDirective(d, text, i, opening)) return null; if (!isValidDirective(d, text, i, opening)) return null;
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment