mirror of
https://github.com/discourse/discourse.git
synced 2024-11-29 07:43:38 +08:00
FIX: Properly convert quotes to Markdown (#8808)
* FIX: Properly convert quotes to Markdown When quoting a quote it used to convert the quote header, including the user avatar and username, into a image and some text and then the contents. This also caused issues when quoting full paragraphs (or when selecting paragraphs by triple-clicking) because the user avatar and name from the following quote would also be included. This commit implements the support necessary to convert <aside class="quote"> elements to proper Discourse quotes.
This commit is contained in:
parent
6f3952e7f1
commit
88a4d5a2c1
|
@ -48,23 +48,21 @@ export default Component.extend({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let opts;
|
let opts = { raw: true };
|
||||||
for (
|
for (
|
||||||
let element = selectedElement();
|
let element = selectedElement();
|
||||||
element && element.tagName !== "ARTICLE";
|
element && element.tagName !== "ARTICLE";
|
||||||
element = element.parentElement
|
element = element.parentElement
|
||||||
) {
|
) {
|
||||||
if (element.tagName === "ASIDE" && element.classList.contains("quote")) {
|
if (element.tagName === "ASIDE" && element.classList.contains("quote")) {
|
||||||
opts = {
|
opts.username =
|
||||||
username:
|
|
||||||
element.dataset.username ||
|
element.dataset.username ||
|
||||||
element
|
element
|
||||||
.querySelector(".title")
|
.querySelector(".title")
|
||||||
.textContent.trim()
|
.textContent.trim()
|
||||||
.replace(/:$/, ""),
|
.replace(/:$/, "");
|
||||||
post: element.dataset.post,
|
opts.post = element.dataset.post;
|
||||||
topic: element.dataset.topic
|
opts.topic = element.dataset.topic;
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ export class Tag {
|
||||||
return [
|
return [
|
||||||
"address",
|
"address",
|
||||||
"article",
|
"article",
|
||||||
"aside",
|
|
||||||
"dd",
|
"dd",
|
||||||
"div",
|
"div",
|
||||||
"dl",
|
"dl",
|
||||||
|
@ -89,6 +88,7 @@ export class Tag {
|
||||||
...Tag.blocks(),
|
...Tag.blocks(),
|
||||||
...Tag.headings(),
|
...Tag.headings(),
|
||||||
...Tag.slices(),
|
...Tag.slices(),
|
||||||
|
"aside",
|
||||||
"li",
|
"li",
|
||||||
"td",
|
"td",
|
||||||
"th",
|
"th",
|
||||||
|
@ -126,6 +126,45 @@ export class Tag {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static aside() {
|
||||||
|
return class extends Tag.block("aside") {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
toMarkdown() {
|
||||||
|
if (!/\bquote\b/.test(this.element.attributes.class)) {
|
||||||
|
return super.toMarkdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
const blockquote = this.element.children.find(
|
||||||
|
child => child.name === "blockquote"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!blockquote) {
|
||||||
|
return super.toMarkdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
let text = Element.parse([blockquote], this.element) || "";
|
||||||
|
text = text.trim().replace(/^>/g, "");
|
||||||
|
if (text.length === 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const username = this.element.attributes["data-username"];
|
||||||
|
const post = this.element.attributes["data-post"];
|
||||||
|
const topic = this.element.attributes["data-topic"];
|
||||||
|
|
||||||
|
const prefix =
|
||||||
|
username && post && topic
|
||||||
|
? `[quote="${username}, post:${post}, topic:${topic}"]`
|
||||||
|
: "[quote]";
|
||||||
|
|
||||||
|
return `\n\n${prefix}\n${text}\n[/quote]\n\n`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static heading(name, i) {
|
static heading(name, i) {
|
||||||
const prefix = `${[...Array(i)].map(() => "#").join("")} `;
|
const prefix = `${[...Array(i)].map(() => "#").join("")} `;
|
||||||
return Tag.block(name, prefix, "");
|
return Tag.block(name, prefix, "");
|
||||||
|
@ -484,6 +523,7 @@ function tags() {
|
||||||
...Tag.slices().map(s => Tag.slice(s, "\n")),
|
...Tag.slices().map(s => Tag.slice(s, "\n")),
|
||||||
...Tag.emphases().map(e => Tag.emphasis(e[0], e[1])),
|
...Tag.emphases().map(e => Tag.emphasis(e[0], e[1])),
|
||||||
...Tag.whitelists().map(t => Tag.whitelist(t)),
|
...Tag.whitelists().map(t => Tag.whitelist(t)),
|
||||||
|
Tag.aside(),
|
||||||
Tag.cell("td"),
|
Tag.cell("td"),
|
||||||
Tag.cell("th"),
|
Tag.cell("th"),
|
||||||
Tag.replace("br", "\n"),
|
Tag.replace("br", "\n"),
|
||||||
|
|
|
@ -386,3 +386,30 @@ QUnit.test("converts image lightboxes to markdown", assert => {
|
||||||
|
|
||||||
assert.equal(toMarkdown(html), markdown);
|
assert.equal(toMarkdown(html), markdown);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test("converts quotes to markdown", assert => {
|
||||||
|
let html = `
|
||||||
|
<p>there is a quote below</p>
|
||||||
|
<aside class="quote no-group" data-username="foo" data-post="1" data-topic="2">
|
||||||
|
<div class="title" style="cursor: pointer;">
|
||||||
|
<div class="quote-controls"><span class="svg-icon-title" title="expand/collapse"><svg class="fa d-icon d-icon-chevron-down svg-icon svg-string" xmlns="http://www.w3.org/2000/svg"><use xlink:href="#chevron-down"></use></svg></span><a href="/t/hello-world-i-am-posting-an-image/158/1" title="go to the quoted post" class="back"><svg class="fa d-icon d-icon-arrow-up svg-icon svg-string" xmlns="http://www.w3.org/2000/svg"><use xlink:href="#arrow-up"></use></svg></a></div>
|
||||||
|
<img alt="" width="20" height="20" src="" class="avatar"> foo:</div>
|
||||||
|
<blockquote>
|
||||||
|
<p>this is a quote</p>
|
||||||
|
</blockquote>
|
||||||
|
</aside>
|
||||||
|
<p>there is a quote above</p>
|
||||||
|
`;
|
||||||
|
|
||||||
|
let markdown = `
|
||||||
|
there is a quote below
|
||||||
|
|
||||||
|
[quote="foo, post:1, topic:2"]
|
||||||
|
this is a quote
|
||||||
|
[/quote]
|
||||||
|
|
||||||
|
there is a quote above
|
||||||
|
`;
|
||||||
|
|
||||||
|
assert.equal(toMarkdown(html), markdown.trim());
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user