Skip to content

Commit a375701

Browse files
committed
FIX: Quotes with new lines were broken
1 parent d759684 commit a375701

4 files changed

Lines changed: 86 additions & 47 deletions

File tree

app/assets/javascripts/discourse/dialects/bbcode_dialect.js

Lines changed: 68 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -107,46 +107,80 @@ Discourse.Dialect.on("register", function(event) {
107107
@return {Array} the JsonML containing the markup or undefined if nothing changed.
108108
@namespace Discourse.Dialect
109109
**/
110-
dialect.inline["[quote="] = function bbcodeQuote(text, orig_match) {
111-
var bbcodePattern = new RegExp("\\[quote=?([^\\[\\]]+)?\\]([\\s\\S]*?)\\[\\/quote\\]", "igm"),
112-
m = bbcodePattern.exec(text);
110+
dialect.block['quote'] = function bbcodeQuote(block, next) {
111+
var m = new RegExp("\\[quote=?([^\\[\\]]+)?\\]([\\s\\S]*)", "igm").exec(block);
112+
if (m) {
113+
var paramsString = m[1].replace(/\"/g, ''),
114+
params = {'class': 'quote'},
115+
paramsSplit = paramsString.split(/\, */),
116+
username = paramsSplit[0],
117+
opts = dialect.options,
118+
startPos = block.indexOf(m[0]),
119+
leading,
120+
quoteContents = [],
121+
result = [];
122+
123+
if (startPos > 0) {
124+
leading = block.slice(0, startPos);
125+
126+
var para = ['p'];
127+
this.processInline(leading).forEach(function (l) {
128+
para.push(l);
129+
});
130+
131+
result.push(para);
132+
}
113133

114-
if (!m) { return; }
115-
var paramsString = m[1].replace(/\"/g, ''),
116-
params = {'class': 'quote'},
117-
paramsSplit = paramsString.split(/\, */),
118-
username = paramsSplit[0],
119-
opts = dialect.options;
120-
121-
paramsSplit.forEach(function(p,i) {
122-
if (i > 0) {
123-
var assignment = p.split(':');
124-
if (assignment[0] && assignment[1]) {
125-
params['data-' + assignment[0]] = assignment[1].trim();
134+
paramsSplit.forEach(function(p,i) {
135+
if (i > 0) {
136+
var assignment = p.split(':');
137+
if (assignment[0] && assignment[1]) {
138+
params['data-' + assignment[0]] = assignment[1].trim();
139+
}
126140
}
141+
});
142+
143+
var avatarImg;
144+
if (opts.lookupAvatarByPostNumber) {
145+
// client-side, we can retrieve the avatar from the post
146+
var postNumber = parseInt(params['data-post'], 10);
147+
avatarImg = opts.lookupAvatarByPostNumber(postNumber);
148+
} else if (opts.lookupAvatar) {
149+
// server-side, we need to lookup the avatar from the username
150+
avatarImg = opts.lookupAvatar(username);
127151
}
128-
});
129152

130-
var avatarImg;
131-
if (opts.lookupAvatarByPostNumber) {
132-
// client-side, we can retrieve the avatar from the post
133-
var postNumber = parseInt(params['data-post'], 10);
134-
avatarImg = opts.lookupAvatarByPostNumber(postNumber);
135-
} else if (opts.lookupAvatar) {
136-
// server-side, we need to lookup the avatar from the username
137-
avatarImg = opts.lookupAvatar(username);
138-
}
153+
if (m[2]) { next.unshift(MD.mk_block(m[2])); }
139154

140-
var quote = ['aside', params,
141-
['div', {'class': 'title'},
142-
['div', {'class': 'quote-controls'}],
143-
avatarImg ? avatarImg + "\n" : "",
144-
I18n.t('user.said',{username: username})
145-
],
146-
['blockquote'].concat(this.processInline(m[2]))
147-
];
155+
while (next.length > 0) {
156+
var b = next.shift(),
157+
n = b.match(/([\s\S]*)\[\/quote\]([\s\S]*)/m);
148158

149-
return [m[0].length, quote];
159+
if (n) {
160+
if (n[2]) {
161+
next.unshift(MD.mk_block(n[2]));
162+
}
163+
quoteContents.push(n[1]);
164+
break;
165+
} else {
166+
quoteContents.push(b);
167+
}
168+
}
169+
170+
var contents = this.processInline(quoteContents.join(" \n \n"));
171+
contents.unshift('blockquote');
172+
173+
174+
result.push(['p', ['aside', params,
175+
['div', {'class': 'title'},
176+
['div', {'class': 'quote-controls'}],
177+
avatarImg ? avatarImg + "\n" : "",
178+
I18n.t('user.said',{username: username})
179+
],
180+
contents
181+
]]);
182+
return result;
183+
}
150184
};
151185

152186
});

app/assets/javascripts/discourse/views/composer_view.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,12 @@ Discourse.ComposerView = Discourse.View.extend({
192192

193193
this.editor = editor = Discourse.Markdown.createEditor({
194194
lookupAvatarByPostNumber: function(postNumber) {
195-
var quotedPost = composerView.get('controller.controllers.topic.postStream.posts').findProperty("post_number", postNumber);
196-
if (quotedPost) {
197-
return Discourse.Utilities.tinyAvatar(quotedPost.get("avatar_template"));
195+
var posts = composerView.get('controller.controllers.topic.postStream.posts');
196+
if (posts) {
197+
var quotedPost = posts.findProperty("post_number", postNumber);
198+
if (quotedPost) {
199+
return Discourse.Utilities.tinyAvatar(quotedPost.get("avatar_template"));
200+
}
198201
}
199202
}
200203
});

test/javascripts/components/bbcode_test.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,9 @@ test("quote formatting", function() {
8888

8989
format("[quote=\"eviltrout, post:1, topic:1\"]abc[/quote]\nhello",
9090
"<aside class=\"quote\" data-post=\"1\" data-topic=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>eviltrout said:" +
91-
"</div><blockquote>abc</blockquote></aside><br/>\nhello",
91+
"</div><blockquote>abc</blockquote></aside></p>\n\n<p>\nhello",
9292
"handles new lines properly");
9393

94-
format("before[quote=\"eviltrout, post:1, topic:1\"]first[/quote]middle[quote=\"eviltrout, post:2, topic:2\"]second[/quote]after",
95-
"before<aside class=\"quote\" data-post=\"1\" data-topic=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>eviltrout said:</div><blockquote>" +
96-
"first</blockquote></aside><br/>middle<aside class=\"quote\" data-post=\"2\" data-topic=\"2\"><div class=\"title\"><div class=\"quote-controls\"></div>" +
97-
"eviltrout said:</div><blockquote>second</blockquote></aside><br/>after",
98-
"can handle more than one quote");
99-
10094
});
10195

10296

test/javascripts/components/markdown_test.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,23 @@ test("Links", function() {
8585
});
8686

8787
test("Quotes", function() {
88+
89+
cookedOptions("[quote=\"eviltrout, post: 1\"]\na quote\n\nsecond line\n[/quote]",
90+
{ topicId: 2 },
91+
"<p><aside class=\"quote\" data-post=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>eviltrout said:</div><blockquote>\n" +
92+
"a quote<br/><br/>second line<br/></blockquote></aside></p>",
93+
"works with multiple lines");
94+
8895
cookedOptions("1[quote=\"bob, post:1\"]my quote[/quote]2",
8996
{ topicId: 2, lookupAvatar: function(name) { return "" + name; } },
90-
"<p>1<aside class=\"quote\" data-post=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>bob\n" +
91-
"bob said:</div><blockquote>my quote</blockquote></aside><br/>2</p>",
97+
"<p>1</p>\n\n<p><aside class=\"quote\" data-post=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>bob\n" +
98+
"bob said:</div><blockquote>my quote</blockquote></aside></p>\n\n<p>2</p>",
9299
"handles quotes properly");
93100

94101
cookedOptions("1[quote=\"bob, post:1\"]my quote[/quote]2",
95102
{ topicId: 2, lookupAvatar: function(name) { } },
96-
"<p>1<aside class=\"quote\" data-post=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>bob said:</div><blockquote>my quote</blockquote></aside><br/>2</p>",
103+
"<p>1</p>\n\n<p><aside class=\"quote\" data-post=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>bob said:" +
104+
"</div><blockquote>my quote</blockquote></aside></p>\n\n<p>2</p>",
97105
"includes no avatar if none is found");
98106
});
99107

0 commit comments

Comments
 (0)