mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-08-18 09:06:52 +02:00
fix: correct image source for quoted reply (#8565)
- Since v10 replies are generated on the fly to handle quoted reply (forgejo/forgejo#5677), this means that we have to do some work to construct markdown that is equivalent to the HTML of the comment. - Images are slightly strange in the context of issues and pull requests, as Forgejo will render them in the context of the repository and as such links such as `/attachments` become `/user/repo/attachments`, the quoted reply did not take into account and would use `/user/repo/attachments` as link which means it gets transformed to `/user/repo//user/repo/attachments`. - Instead of fixing this on the backend (and maybe break some existing links), teach the quoted reply about this context and remove it from the image source before generating the markdown. Reported-by: mrwusel (via Matrix) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8565 Reviewed-by: 0ko <0ko@noreply.codeberg.org> Reviewed-by: Beowulf <beowulf@beocode.eu> Co-authored-by: Gusted <postmaster@gusted.xyz> Co-committed-by: Gusted <postmaster@gusted.xyz>
This commit is contained in:
parent
b705cfcdd8
commit
8c8d646099
4 changed files with 38 additions and 27 deletions
|
@ -531,6 +531,13 @@ const filters = {
|
|||
}
|
||||
return el;
|
||||
},
|
||||
IMG(el, context) {
|
||||
const src = el.getAttribute('src');
|
||||
if (src?.startsWith(context)) {
|
||||
el.src = src.slice(context.length);
|
||||
}
|
||||
return el;
|
||||
},
|
||||
};
|
||||
|
||||
function hasContent(node) {
|
||||
|
@ -538,32 +545,34 @@ function hasContent(node) {
|
|||
}
|
||||
|
||||
// This code matches that of what is done by @github/quote-selection
|
||||
function preprocessFragment(fragment) {
|
||||
const nodeIterator = document.createNodeIterator(fragment, NodeFilter.SHOW_ELEMENT, {
|
||||
acceptNode(node) {
|
||||
if (node.nodeName in filters && hasContent(node)) {
|
||||
return NodeFilter.FILTER_ACCEPT;
|
||||
function preprocessFragment(context) {
|
||||
return function(fragment) {
|
||||
const nodeIterator = document.createNodeIterator(fragment, NodeFilter.SHOW_ELEMENT, {
|
||||
acceptNode(node) {
|
||||
if (node.nodeName in filters && hasContent(node)) {
|
||||
return NodeFilter.FILTER_ACCEPT;
|
||||
}
|
||||
|
||||
return NodeFilter.FILTER_SKIP;
|
||||
},
|
||||
});
|
||||
const results = [];
|
||||
let node = nodeIterator.nextNode();
|
||||
|
||||
while (node) {
|
||||
if (node instanceof HTMLElement) {
|
||||
results.push(node);
|
||||
}
|
||||
|
||||
return NodeFilter.FILTER_SKIP;
|
||||
},
|
||||
});
|
||||
const results = [];
|
||||
let node = nodeIterator.nextNode();
|
||||
|
||||
while (node) {
|
||||
if (node instanceof HTMLElement) {
|
||||
results.push(node);
|
||||
node = nodeIterator.nextNode();
|
||||
}
|
||||
node = nodeIterator.nextNode();
|
||||
}
|
||||
|
||||
// process deepest matches first
|
||||
results.reverse();
|
||||
results.reverse();
|
||||
|
||||
for (const el of results) {
|
||||
el.replaceWith(filters[el.nodeName](el));
|
||||
}
|
||||
for (const el of results) {
|
||||
el.replaceWith(filters[el.nodeName](el, context));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function initRepoIssueCommentEdit() {
|
||||
|
@ -573,7 +582,7 @@ function initRepoIssueCommentEdit() {
|
|||
// Quote reply
|
||||
$(document).on('click', '.quote-reply', async (event) => {
|
||||
event.preventDefault();
|
||||
const quote = new MarkdownQuote('', preprocessFragment);
|
||||
const quote = new MarkdownQuote('', preprocessFragment(event.target.getAttribute('data-context')));
|
||||
|
||||
let editorTextArea;
|
||||
if (event.target.classList.contains('quote-reply-diff')) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue