diff --git a/app/assets/javascripts/discourse/app/helpers/plugin-outlet.gjs b/app/assets/javascripts/discourse/app/helpers/plugin-outlet.gjs new file mode 100644 index 00000000000..f695a967ab2 --- /dev/null +++ b/app/assets/javascripts/discourse/app/helpers/plugin-outlet.gjs @@ -0,0 +1,26 @@ +import { htmlSafe } from "@ember/template"; +import PluginOutlet from "discourse/components/plugin-outlet"; +import { connectorsExist } from "discourse/lib/plugin-connectors"; +import rawRenderGlimmer from "discourse/lib/raw-render-glimmer"; +import RawHandlebars from "discourse-common/lib/raw-handlebars"; + +RawHandlebars.registerHelper("plugin-outlet", function (options) { + const { name, tagName, outletArgs } = options.hash; + + if (!connectorsExist(name)) { + return htmlSafe(""); + } + + return htmlSafe( + rawRenderGlimmer( + this, + `${tagName || "span"}.hbr-ember-outlet`, + , + { name, outletArgs } + ) + ); +}); diff --git a/app/assets/javascripts/discourse/app/helpers/raw-hash.js b/app/assets/javascripts/discourse/app/helpers/raw-hash.js new file mode 100644 index 00000000000..3f5329fa257 --- /dev/null +++ b/app/assets/javascripts/discourse/app/helpers/raw-hash.js @@ -0,0 +1,5 @@ +import { registerRawHelper } from "discourse-common/lib/helpers"; + +registerRawHelper("raw-hash", function (params) { + return params; +}); diff --git a/app/assets/javascripts/discourse/app/lib/raw-render-glimmer.js b/app/assets/javascripts/discourse/app/lib/raw-render-glimmer.js index 8a1e7c488e8..da0eb9815ce 100644 --- a/app/assets/javascripts/discourse/app/lib/raw-render-glimmer.js +++ b/app/assets/javascripts/discourse/app/lib/raw-render-glimmer.js @@ -12,7 +12,7 @@ let counter = 0; * * ```hbs * {{! raw-templates/something-cool.hbr }} - * {{{view.html}}} + * {{html-safe view.html}} * ``` * * ```gjs @@ -21,7 +21,7 @@ let counter = 0; * import rawRenderGlimmer from "discourse/lib/raw-render-glimmer"; * * export default class SomethingCool extends EmberObject { - * get html(){ + * get html() { * return rawRenderGlimmer(this, "div", , { name: this.name }); * } * ``` diff --git a/app/assets/javascripts/discourse/app/raw-templates/list/activity-column.hbr b/app/assets/javascripts/discourse/app/raw-templates/list/activity-column.hbr index 384909db023..d2d4313272c 100644 --- a/app/assets/javascripts/discourse/app/raw-templates/list/activity-column.hbr +++ b/app/assets/javascripts/discourse/app/raw-templates/list/activity-column.hbr @@ -1,6 +1,7 @@ <{{tagName}} class="{{class}} {{cold-age-class topic.createdAt startDate=topic.bumpedAt class=""}} activity" title="{{html-safe topic.bumpedAtTitle}}"> {{~raw-plugin-outlet name="topic-list-before-relative-date"~}} + {{~plugin-outlet name="topic-list-before-relative-date" outletArgs=(raw-hash topic=topic)~}} {{~format-date topic.bumpedAt format="tiny" noTitle="true"~}} diff --git a/app/assets/javascripts/discourse/app/raw-templates/list/posts-count-column.hbr b/app/assets/javascripts/discourse/app/raw-templates/list/posts-count-column.hbr index 71d40199e97..28a7f200960 100644 --- a/app/assets/javascripts/discourse/app/raw-templates/list/posts-count-column.hbr +++ b/app/assets/javascripts/discourse/app/raw-templates/list/posts-count-column.hbr @@ -1,6 +1,7 @@ <{{view.tagName}} class='num posts-map posts {{view.likesHeat}} topic-list-data'> diff --git a/app/assets/javascripts/discourse/app/raw-templates/list/topic-list-item.hbr b/app/assets/javascripts/discourse/app/raw-templates/list/topic-list-item.hbr index c24e5be24f3..0cdb6e8a453 100644 --- a/app/assets/javascripts/discourse/app/raw-templates/list/topic-list-item.hbr +++ b/app/assets/javascripts/discourse/app/raw-templates/list/topic-list-item.hbr @@ -17,14 +17,17 @@ --}} {{~raw-plugin-outlet name="topic-list-before-link"}} + {{~plugin-outlet name="topic-list-before-link" outletArgs=(raw-hash topic=topic)}} {{~raw-plugin-outlet name="topic-list-before-status"}} + {{~plugin-outlet name="topic-list-before-status" outletArgs=(raw-hash topic=topic)}} {{~raw "topic-status" topic=topic}} {{~topic-link topic class="raw-link raw-topic-link"}} {{~#if topic.featured_link}}  {{~topic-featured-link topic}} {{~/if}} {{~raw-plugin-outlet name="topic-list-after-title"}} + {{~plugin-outlet name="topic-list-after-title" outletArgs=(raw-hash topic=topic)}} {{~raw "list/unread-indicator" includeUnreadIndicator=includeUnreadIndicator topicId=topic.id unreadClass=unreadClass~}} @@ -36,6 +39,7 @@ {{#unless hideCategory}} {{#unless topic.isPinnedUncategorized}} {{~raw-plugin-outlet name="topic-list-before-category"}} + {{~plugin-outlet name="topic-list-before-category" outletArgs=(raw-hash topic=topic)}} {{category-link topic.category}} {{/unless}} {{/unless}} @@ -50,9 +54,11 @@ {{/if}} {{~raw-plugin-outlet name="topic-list-main-link-bottom"}} + {{~plugin-outlet name="topic-list-main-link-bottom" outletArgs=(raw-hash topic=topic)}} {{~raw-plugin-outlet name="topic-list-after-main-link"}} +{{~plugin-outlet name="topic-list-after-main-link" outletArgs=(raw-hash topic=topic)}} {{#if showPosters}} {{raw "list/posters-column" posters=topic.featuredUsers}} @@ -82,6 +88,7 @@ {{raw-plugin-outlet name="topic-list-before-view-count"}} + {{plugin-outlet name="topic-list-before-view-count" outletArgs=(raw-hash topic=topic)}} {{number topic.views numberKey="views_long"}} diff --git a/app/assets/javascripts/discourse/app/raw-templates/mobile/list/topic-list-item.hbr b/app/assets/javascripts/discourse/app/raw-templates/mobile/list/topic-list-item.hbr index 4acd87b41d2..8c56a7f6b99 100644 --- a/app/assets/javascripts/discourse/app/raw-templates/mobile/list/topic-list-item.hbr +++ b/app/assets/javascripts/discourse/app/raw-templates/mobile/list/topic-list-item.hbr @@ -18,14 +18,17 @@ at the end of the link, preventing it from line wrapping onto its own line. --}} {{~raw-plugin-outlet name="topic-list-before-link"}} + {{~plugin-outlet name="topic-list-before-link" outletArgs=(raw-hash topic=topic)}} {{~raw-plugin-outlet name="topic-list-after-main-link"}} + {{~plugin-outlet name="topic-list-after-main-link" outletArgs=(raw-hash topic=topic)}}
{{raw "list/post-count-or-badges" topic=topic postBadgesEnabled=showTopicPostBadges}}
@@ -42,6 +47,7 @@ {{#unless hideCategory}} {{~raw-plugin-outlet name="topic-list-before-category"}} + {{~plugin-outlet name="topic-list-before-category" outletArgs=(raw-hash topic=topic)}} {{category-link topic.category~}} {{~/unless}} {{~discourse-tags topic mode="list"}} diff --git a/app/assets/javascripts/discourse/app/raw-templates/topic-list-header.hbr b/app/assets/javascripts/discourse/app/raw-templates/topic-list-header.hbr index 11543c5151f..fbd04182db8 100644 --- a/app/assets/javascripts/discourse/app/raw-templates/topic-list-header.hbr +++ b/app/assets/javascripts/discourse/app/raw-templates/topic-list-header.hbr @@ -1,4 +1,5 @@ {{~raw-plugin-outlet name="topic-list-header-before"~}} +{{~plugin-outlet name="topic-list-header-before"~}} {{#if bulkSelectEnabled}} {{#if canBulkSelect}} @@ -8,6 +9,7 @@ {{/if}} {{raw "topic-list-header-column" order='default' name=listTitle bulkSelectEnabled=bulkSelectEnabled showBulkToggle=toggleInTitle canBulkSelect=canBulkSelect canDoBulkActions=canDoBulkActions showTopicsAndRepliesToggle=showTopicsAndRepliesToggle newListSubset=newListSubset newRepliesCount=newRepliesCount newTopicsCount=newTopicsCount bulkSelectHelper=bulkSelectHelper }} {{raw-plugin-outlet name="topic-list-header-after-main-link"}} +{{plugin-outlet name="topic-list-header-after-main-link"}} {{#if showPosters}} {{raw "topic-list-header-column" name='posters' screenreaderOnly='true'}} {{/if}} @@ -21,3 +23,4 @@ {{raw "topic-list-header-column" sortable=sortable number='true' order='views' name='views'}} {{raw "topic-list-header-column" sortable=sortable number='true' order='activity' name='activity'}} {{~raw-plugin-outlet name="topic-list-header-after"~}} +{{~plugin-outlet name="topic-list-header-after"~}} \ No newline at end of file diff --git a/app/assets/javascripts/discourse/tests/acceptance/hbr-plugin-outlet-test.gjs b/app/assets/javascripts/discourse/tests/acceptance/hbr-plugin-outlet-test.gjs new file mode 100644 index 00000000000..472110f9f17 --- /dev/null +++ b/app/assets/javascripts/discourse/tests/acceptance/hbr-plugin-outlet-test.gjs @@ -0,0 +1,20 @@ +import { visit } from "@ember/test-helpers"; +import { hbs } from "ember-cli-htmlbars"; +import { test } from "qunit"; +import { acceptance } from "discourse/tests/helpers/qunit-helpers"; +import { registerTemporaryModule } from "discourse/tests/helpers/temporary-module-helper"; + +acceptance("Hbr Plugin Outlet", function (needs) { + needs.hooks.beforeEach(function () { + registerTemporaryModule( + "discourse/theme-12/templates/connectors/topic-list-before-link/hello", + hbs`{{@outletArgs.topic.id}}` + ); + }); + + test("renders ember plugin outlets in hbr contexts", async function (assert) { + await visit("/"); + assert.dom(".lala").exists("renders the outlet"); + assert.dom(".lala").hasText("11557", "has the topic id"); + }); +}); diff --git a/app/assets/javascripts/discourse/tests/acceptance/raw-plugin-outlet-test.js b/app/assets/javascripts/discourse/tests/acceptance/raw-plugin-outlet-test.js index 7c042fa03b4..e04a3622d2e 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/raw-plugin-outlet-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/raw-plugin-outlet-test.js @@ -1,11 +1,7 @@ import { visit } from "@ember/test-helpers"; import { compile } from "handlebars"; import { test } from "qunit"; -import { - acceptance, - exists, - query, -} from "discourse/tests/helpers/qunit-helpers"; +import { acceptance } from "discourse/tests/helpers/qunit-helpers"; import { addRawTemplate, removeRawTemplate, @@ -15,23 +11,20 @@ const CONNECTOR = "javascripts/raw-test/connectors/topic-list-before-status/lala"; acceptance("Raw Plugin Outlet", function (needs) { - needs.hooks.beforeEach(() => { + needs.hooks.beforeEach(function () { addRawTemplate( CONNECTOR, compile(`{{context.topic.id}}`) ); }); - needs.hooks.afterEach(() => { + needs.hooks.afterEach(function () { removeRawTemplate(CONNECTOR); }); + test("Renders the raw plugin outlet", async function (assert) { await visit("/"); - assert.ok(exists(".topic-lala"), "it renders the outlet"); - assert.strictEqual( - query(".topic-lala:nth-of-type(1)").innerText, - "11557", - "it has the topic id" - ); + assert.dom(".topic-lala").exists("renders the outlet"); + assert.dom(".topic-lala").hasText("11557", "has the topic id"); }); }); diff --git a/app/assets/stylesheets/common/base/discourse.scss b/app/assets/stylesheets/common/base/discourse.scss index 5116f759ec8..ea543897798 100644 --- a/app/assets/stylesheets/common/base/discourse.scss +++ b/app/assets/stylesheets/common/base/discourse.scss @@ -836,3 +836,7 @@ a#skip-link { overflow: hidden !important; margin-right: var(--scroll-gap, 0); } + +.hbr-ember-outlet { + display: contents; +}