mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FIX: Which topic do you want to reply to rendering raw HTML (#30962)
Because of
2b63830496
`Which topic do you want to reply to rendering HTML` was rendering raw
HTML.
Added `htmlSafe` for now.
I'll work on testing for this feature.
This commit is contained in:
parent
1b9e2ff4f9
commit
e78c937a5c
@ -0,0 +1,76 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { hash } from "@ember/helper";
|
||||
import { action } from "@ember/object";
|
||||
import { eq } from "truth-helpers";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import { categoryLinkHTML } from "discourse/helpers/category-link";
|
||||
import dIcon from "discourse/helpers/d-icon";
|
||||
import discourseTags from "discourse/helpers/discourse-tags";
|
||||
|
||||
const TopicLabelButton = <template>
|
||||
<DButton class={{@class}} @action={{@action}}>
|
||||
<div class="topic-title">
|
||||
<div class="topic-title__top-line">
|
||||
<span class="topic-statuses">
|
||||
{{#if (eq @topic.archetype "private_message")}}
|
||||
<span class="topic-status">
|
||||
{{dIcon "envelope"}}
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
{{#if @topic.bookmarked}}
|
||||
<span class="topic-status">
|
||||
{{dIcon "bookmark"}}
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
{{#if @topic.closed}}
|
||||
<span class="topic-status">
|
||||
{{dIcon "lock"}}
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
{{#if @topic.pinned}}
|
||||
<span class="topic-status">
|
||||
{{dIcon "thumbtack"}}
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
</span>
|
||||
<span class="fancy-title">
|
||||
{{@topic.title}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="topic-title__bottom-line">
|
||||
{{categoryLinkHTML @topic (hash link=false)}}
|
||||
{{discourseTags @topic}}
|
||||
</div>
|
||||
</div>
|
||||
</DButton>
|
||||
</template>;
|
||||
|
||||
export default class TopicLabelContent extends Component {
|
||||
@action
|
||||
replyOnOriginal() {
|
||||
this.args.model.replyOnOriginal();
|
||||
}
|
||||
|
||||
@action
|
||||
replyOnCurrent() {
|
||||
this.args.model.replyOnCurrent();
|
||||
}
|
||||
|
||||
<template>
|
||||
<TopicLabelButton
|
||||
@class="btn-primary btn-reply-where btn-reply-on-original"
|
||||
@action={{this.replyOnOriginal}}
|
||||
@topic={{@model.originalTopic}}
|
||||
/>
|
||||
|
||||
<TopicLabelButton
|
||||
@class="btn-reply-where btn-reply-here"
|
||||
@action={{this.replyOnCurrent}}
|
||||
@topic={{@model.currentTopic}}
|
||||
/>
|
||||
</template>
|
||||
}
|
@ -2,7 +2,6 @@ import EmberObject, { action, computed } from "@ember/object";
|
||||
import { alias, and, or, reads } from "@ember/object/computed";
|
||||
import { cancel, scheduleOnce } from "@ember/runloop";
|
||||
import Service, { service } from "@ember/service";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { observes, on } from "@ember-decorators/object";
|
||||
import $ from "jquery";
|
||||
@ -10,7 +9,7 @@ import { Promise } from "rsvp";
|
||||
import DiscardDraftModal from "discourse/components/modal/discard-draft";
|
||||
import PostEnqueuedModal from "discourse/components/modal/post-enqueued";
|
||||
import SpreadsheetEditor from "discourse/components/modal/spreadsheet-editor";
|
||||
import { categoryBadgeHTML } from "discourse/helpers/category-link";
|
||||
import TopicLabelContent from "discourse/components/topic-label-content";
|
||||
import {
|
||||
cannotPostAgain,
|
||||
durationTextFromSeconds,
|
||||
@ -26,11 +25,9 @@ import prepareFormTemplateData, {
|
||||
import { shortDate } from "discourse/lib/formatter";
|
||||
import { getOwnerWithFallback } from "discourse/lib/get-owner";
|
||||
import getURL from "discourse/lib/get-url";
|
||||
import { iconHTML } from "discourse/lib/icon-library";
|
||||
import { disableImplicitInjections } from "discourse/lib/implicit-injections";
|
||||
import { wantsNewWindow } from "discourse/lib/intercept-click";
|
||||
import { buildQuote } from "discourse/lib/quote";
|
||||
import renderTags from "discourse/lib/render-tags";
|
||||
import { emojiUnescape } from "discourse/lib/text";
|
||||
import {
|
||||
authorizesOneOrMoreExtensions,
|
||||
@ -1092,58 +1089,27 @@ export default class ComposerService extends Service {
|
||||
return;
|
||||
}
|
||||
|
||||
const topicLabelContent = function (topicOption) {
|
||||
const topicClosed = topicOption.closed
|
||||
? `<span class="topic-status">${iconHTML("lock")}</span>`
|
||||
: "";
|
||||
const topicPinned = topicOption.pinned
|
||||
? `<span class="topic-status">${iconHTML("thumbtack")}</span>`
|
||||
: "";
|
||||
const topicBookmarked = topicOption.bookmarked
|
||||
? `<span class="topic-status">${iconHTML("bookmark")}</span>`
|
||||
: "";
|
||||
const topicPM =
|
||||
topicOption.archetype === "private_message"
|
||||
? `<span class="topic-status">${iconHTML("envelope")}</span>`
|
||||
: "";
|
||||
|
||||
return `<div class="topic-title">
|
||||
<div class="topic-title__top-line">
|
||||
<span class="topic-statuses">
|
||||
${topicPM}${topicBookmarked}${topicClosed}${topicPinned}
|
||||
</span>
|
||||
<span class="fancy-title">
|
||||
${topicOption.fancyTitle}
|
||||
</span>
|
||||
</div>
|
||||
<div class="topic-title__bottom-line">
|
||||
${categoryBadgeHTML(topicOption.category, {
|
||||
link: false,
|
||||
})}${htmlSafe(renderTags(topicOption))}
|
||||
</div>
|
||||
</div>`;
|
||||
};
|
||||
|
||||
if (
|
||||
currentTopic.id !== composer.get("topic.id") &&
|
||||
(this.isStaffUser || !currentTopic.closed)
|
||||
) {
|
||||
this.dialog.alert({
|
||||
title: i18n("composer.posting_not_on_topic"),
|
||||
buttons: [
|
||||
{
|
||||
label: topicLabelContent(originalTopic),
|
||||
class: "btn-primary btn-reply-where btn-reply-on-original",
|
||||
action: () => this.save(true),
|
||||
bodyComponent: TopicLabelContent,
|
||||
bodyComponentModel: {
|
||||
originalTopic,
|
||||
replyOnOriginal: () => {
|
||||
this.save(true);
|
||||
this.dialog.didConfirmWrapped();
|
||||
},
|
||||
{
|
||||
label: topicLabelContent(currentTopic),
|
||||
class: "btn-reply-where btn-reply-here",
|
||||
action: () => {
|
||||
currentTopic,
|
||||
replyOnCurrent: () => {
|
||||
composer.setProperties({ topic: currentTopic, post: null });
|
||||
this.save(true);
|
||||
this.dialog.didConfirmWrapped();
|
||||
},
|
||||
},
|
||||
buttons: [
|
||||
{
|
||||
label: i18n("composer.cancel"),
|
||||
class: "btn-flat btn-text btn-reply-where__cancel",
|
||||
|
@ -406,6 +406,8 @@ acceptance("Composer", function (needs) {
|
||||
await click("#reply-control button.create");
|
||||
assert.dom(".reply-where-modal").exists("pops up a modal");
|
||||
|
||||
assert.dom(".topic-title").exists({ count: 2 }); // modal buttons
|
||||
|
||||
await click(".btn-reply-here");
|
||||
assert
|
||||
.dom(".topic-post:last-of-type .cooked p")
|
||||
|
Loading…
Reference in New Issue
Block a user