Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions ts/WoltLabSuite/Core/Component/Ckeditor/Quote.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/**
* Inserts quotes into the editor.
*
* @author Alexander Ebert
* @copyright 2001-2023 WoltLab GmbH
* @author Alexander Ebert, Marcel Werk
* @copyright 2001-2026 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.0
* @woltlabExcludeBundle tiny
Expand All @@ -22,9 +22,10 @@ function insertQuote(editor: CKEditor, payload: InsertQuoteEventPayload) {

author = escapeHTML(author);
link = escapeHTML(link);
const quoteId = payload.uuid !== undefined ? ` data-quote-id="${escapeHTML(payload.uuid)}"` : "";

editor.insertHtml(
`<woltlab-quote data-author="${author}" data-link="${link}">${content}</woltlab-quote>
`<woltlab-quote data-author="${author}" data-link="${link}"${quoteId}>${content}</woltlab-quote>
<p><br data-cke-filler="true"></p>`,
);
}
Expand All @@ -50,6 +51,7 @@ export type InsertQuoteEventPayload = {
content: string;
isText: boolean;
link: string;
uuid?: string;
};

export function setup(element: HTMLElement): void {
Expand Down
37 changes: 34 additions & 3 deletions ts/WoltLabSuite/Core/Component/Quote/List.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
/**
* Handles quotes for CKEditor 5 message fields.
*
* @author Olaf Braun
* @copyright 2001-2024 WoltLab GmbH
* @author Olaf Braun, Marcel Werk
* @copyright 2001-2026 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.2
* @woltlabExcludeBundle tiny
*/

import { getCkeditor } from "WoltLabSuite/Core/Component/Ckeditor";
import { listenToCkeditor, dispatchToCkeditor } from "WoltLabSuite/Core/Component/Ckeditor/Event";
import { getTabMenu } from "WoltLabSuite/Core/Component/Message/MessageTabMenu";
import { getPhrase } from "WoltLabSuite/Core/Language";
Expand All @@ -19,6 +20,7 @@ import {
markQuoteAsUsed,
getUsedQuotes,
} from "WoltLabSuite/Core/Component/Quote/Storage";
import { debounce } from "WoltLabSuite/Core/Core";
import DomUtil from "WoltLabSuite/Core/Dom/Util";
import { escapeHTML } from "WoltLabSuite/Core/StringUtil";

Expand All @@ -40,6 +42,12 @@ class QuoteList {
this.#formSubmitted();
});

listenToCkeditor(this.#editor).changeData(
debounce(() => {
this.#markInsertedQuotes();
}, 500),
);

this.renderQuotes();
}

Expand All @@ -57,12 +65,15 @@ class QuoteList {

quotes.forEach((quote, uuid) => {
const fragment = DomUtil.createFragmentFromHtml(`
<div class="quoteBox quoteBox--tabMenu">
<div class="quoteBox quoteBox--tabMenu" data-uuid="${escapeHTML(uuid)}">
<div class="quoteBoxIcon">
<img src="${escapeHTML(message.avatar)}" alt="" class="userAvatarImage" height="24" width="24">
</div>
<div class="quoteBoxTitle">
<a href="${escapeHTML(message.link)}" target="_blank">${escapeHTML(message.author)}</a>
<span class="quoteBox__indicator green jsTooltip" title="${getPhrase("wcf.message.quote.inserted")}" aria-hidden="true">
<fa-icon name="circle-check"></fa-icon>
</span>
</div>
<div class="quoteBoxButtons">
<button type="button" class="button small jsTooltip" title="${getPhrase("wcf.global.button.delete")}" data-action="delete">
Expand Down Expand Up @@ -91,6 +102,7 @@ class QuoteList {
content,
isText: !quote.rawMessage,
link: message.link,
uuid,
});
});

Expand All @@ -116,6 +128,25 @@ class QuoteList {
} else {
tabMenu.hideTab("quotes");
}

this.#markInsertedQuotes();
}

#markInsertedQuotes(): void {
// The editor of an inline edit may already have been destroyed.
const ckeditor = getCkeditor(this.#editor);
if (ckeditor === undefined) {
return;
}

const insertedQuotes = new Set<string>();
ckeditor.element.querySelectorAll<HTMLElement>("blockquote[data-quote-id]").forEach((blockquote) => {
insertedQuotes.add(blockquote.dataset.quoteId!);
});

this.#container.querySelectorAll<HTMLElement>(".quoteBox--tabMenu").forEach((quoteBox) => {
quoteBox.classList.toggle("quoteBox--inserted", insertedQuotes.has(quoteBox.dataset.uuid!));
});
}

#addBulkButtons(): void {
Expand Down
6 changes: 4 additions & 2 deletions ts/WoltLabSuite/Core/Component/Quote/Message.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/**
* Handles quotes selection in messages.
*
* @author Olaf Braun
* @copyright 2001-2024 WoltLab GmbH
* @author Olaf Braun, Marcel Werk
* @copyright 2001-2026 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.2
* @woltlabExcludeBundle tiny
Expand Down Expand Up @@ -139,6 +139,7 @@ export function registerContainer(
content,
isText: quote.rawMessage === null,
link: quote.link,
uuid: quote.uuid,
});

markQuoteAsUsed(activeEditor.sourceElement.id, quote.uuid);
Expand Down Expand Up @@ -226,6 +227,7 @@ function setup() {
content,
isText: quote.rawMessage === null,
link: quote.link,
uuid: quote.uuid,
});

markQuoteAsUsed(activeEditor.sourceElement.id, quote.uuid);
Expand Down

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ public function __invoke(PreloadPhrasesCollecting $event): void
$event->preload('wcf.message.quote.deleteAllQuotes');
$event->preload('wcf.message.quote.insertAllQuotes');
$event->preload('wcf.message.quote.insertQuote');
$event->preload('wcf.message.quote.inserted');
$event->preload('wcf.message.quote.quoteSelected');
$event->preload('wcf.message.quote.quoteSelected.success');
$event->preload('wcf.message.quote.quoteAndReply');
Expand Down
10 changes: 10 additions & 0 deletions wcfsetup/install/files/style/bbcode/quote.scss
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
.quoteBoxTitle {
align-self: center;
color: var(--wcfContentDimmedText);
display: flex;
gap: 5px;
grid-area: title;

a {
Expand Down Expand Up @@ -110,6 +112,14 @@
pointer-events: none !important;
}

.quoteBox__indicator {
display: none;
}

.quoteBox--inserted .quoteBox__indicator {
display: inline;
}

.quoteBox__bulk__actions {
display: flex;
gap: 5px;
Expand Down
1 change: 1 addition & 0 deletions wcfsetup/install/lang/de.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4219,6 +4219,7 @@ Dateianhänge:
<category name="wcf.message">
<item name="wcf.message.bbcode.code.copy"><![CDATA[Inhalt kopieren]]></item>
<item name="wcf.message.quote.insertQuote"><![CDATA[Zitat einfügen]]></item>
<item name="wcf.message.quote.inserted"><![CDATA[Eingefügt]]></item>
<item name="wcf.message.quote.insertAllQuotes"><![CDATA[Alle Zitate einfügen]]></item>
<item name="wcf.message.quote.deleteAllQuotes"><![CDATA[Alle Zitate löschen]]></item>
<item name="wcf.message.quote.quoteSelected"><![CDATA[Zitat speichern]]></item>
Expand Down
1 change: 1 addition & 0 deletions wcfsetup/install/lang/en.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4165,6 +4165,7 @@ Attachments:
<category name="wcf.message">
<item name="wcf.message.bbcode.code.copy"><![CDATA[Copy Contents]]></item>
<item name="wcf.message.quote.insertQuote"><![CDATA[Insert Quote]]></item>
<item name="wcf.message.quote.inserted"><![CDATA[Inserted]]></item>
<item name="wcf.message.quote.insertAllQuotes"><![CDATA[Insert All Quotes]]></item>
<item name="wcf.message.quote.deleteAllQuotes"><![CDATA[Delete All Quotes]]></item>
<item name="wcf.message.quote.quoteSelected"><![CDATA[Save Quote]]></item>
Expand Down
Loading