mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FIX: Add aria-label attribute to cooked hashtags (#22182)
This commit adds an aria-label attribute to cooked hashtags using the post/chat message decorateCooked functionality. I have just used the inner content of the hashtag (the tag/category/channel name) for the label -- we can reexamine at some point if we want something different like "Link to dev category" or something, but from what I can tell things like Twitter don't even have aria-labels for hashtags so the text would be read out directly. This commit also refactors any ruby specs checking the HTML of hashtags to use rspec-html-matchers which is far clearer than having to maintain the HTML structure in a HEREDOC for comparison, and gives better spec failures. c.f. https://meta.discourse.org/t/hashtags-are-getting-a-makeover/248866/23?u=martin
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { decorateGithubOneboxBody } from "discourse/instance-initializers/onebox-decorators";
|
||||
import { replaceHashtagIconPlaceholder } from "discourse/lib/hashtag-autocomplete";
|
||||
import { decorateHashtags } from "discourse/lib/hashtag-autocomplete";
|
||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
import highlightSyntax from "discourse/lib/highlight-syntax";
|
||||
import I18n from "I18n";
|
||||
@@ -73,10 +73,9 @@ export default {
|
||||
}
|
||||
);
|
||||
|
||||
api.decorateChatMessage(
|
||||
(element) => replaceHashtagIconPlaceholder(element, site),
|
||||
{ id: "hashtagIcons" }
|
||||
);
|
||||
api.decorateChatMessage((element) => decorateHashtags(element, site), {
|
||||
id: "hashtagIcons",
|
||||
});
|
||||
},
|
||||
|
||||
_getScrollParent(node, maxParentSelector) {
|
||||
|
||||
@@ -194,9 +194,20 @@ describe Chat::ChannelArchiveService do
|
||||
subject.new(@channel_archive).execute
|
||||
expect(@channel_archive.reload.complete?).to eq(true)
|
||||
pm_topic = Topic.private_messages.last
|
||||
expect(pm_topic.first_post.cooked).to include(
|
||||
"<a class=\"hashtag-cooked\" href=\"#{channel.relative_url}\" data-type=\"channel\" data-slug=\"#{channel.slug}\" data-id=\"#{channel.id}\" data-ref=\"#{channel.slug}::channel\"><span class=\"hashtag-icon-placeholder\"></span><span>#{channel.title(user)}</span></a>",
|
||||
)
|
||||
expect(pm_topic.first_post.cooked).to have_tag(
|
||||
"a",
|
||||
with: {
|
||||
class: "hashtag-cooked",
|
||||
href: channel.relative_url,
|
||||
"data-type": "channel",
|
||||
"data-slug": channel.slug,
|
||||
"data-id": channel.id,
|
||||
"data-ref": "#{channel.slug}::channel",
|
||||
},
|
||||
) do
|
||||
with_tag("span", with: { class: "hashtag-icon-placeholder" })
|
||||
with_tag("span", text: channel.title(user))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -241,7 +241,7 @@ describe Chat::Message do
|
||||
)
|
||||
end
|
||||
|
||||
it "supports hashtag-autocomplete plugin" do
|
||||
it "supports hashtag autocomplete" do
|
||||
SiteSetting.chat_enabled = true
|
||||
SiteSetting.enable_experimental_hashtag_autocomplete = true
|
||||
|
||||
@@ -250,9 +250,18 @@ describe Chat::Message do
|
||||
|
||||
cooked = described_class.cook("##{category.slug}", user_id: user.id)
|
||||
|
||||
expect(cooked).to eq(
|
||||
"<p><a class=\"hashtag-cooked\" href=\"#{category.url}\" data-type=\"category\" data-slug=\"#{category.slug}\" data-id=\"#{category.id}\"><span class=\"hashtag-icon-placeholder\"></span><span>#{category.name}</span></a></p>",
|
||||
)
|
||||
expect(cooked).to have_tag(
|
||||
"a",
|
||||
with: {
|
||||
class: "hashtag-cooked",
|
||||
href: category.url,
|
||||
"data-type": "category",
|
||||
"data-slug": category.slug,
|
||||
"data-id": category.id,
|
||||
},
|
||||
) do
|
||||
with_tag("span", with: { class: "hashtag-icon-placeholder" })
|
||||
end
|
||||
end
|
||||
|
||||
it "supports censored plugin" do
|
||||
|
||||
@@ -68,15 +68,63 @@ describe "Using #hashtag autocompletion to search for and lookup channels", type
|
||||
|
||||
cooked_hashtags = page.all(".hashtag-cooked", count: 3)
|
||||
|
||||
expect(cooked_hashtags[0]["outerHTML"]).to eq(<<~HTML.chomp)
|
||||
<a class=\"hashtag-cooked\" href=\"#{channel2.relative_url}\" data-type=\"channel\" data-slug=\"random\" data-id=\"#{channel2.id}\"><svg class=\"fa d-icon d-icon-comment svg-icon hashtag-color--channel-#{channel2.id} svg-string\" xmlns=\"http://www.w3.org/2000/svg\"><use href=\"#comment\"></use></svg><span>Random</span></a>
|
||||
HTML
|
||||
expect(cooked_hashtags[1]["outerHTML"]).to eq(<<~HTML.chomp)
|
||||
<a class=\"hashtag-cooked\" href=\"#{category.url}\" data-type=\"category\" data-slug=\"raspberry-beret\" data-id="#{category.id}"><span class=\"hashtag-category-badge hashtag-color--category-#{category.id}\"></span><span>Raspberry</span></a>
|
||||
HTML
|
||||
expect(cooked_hashtags[2]["outerHTML"]).to eq(<<~HTML.chomp)
|
||||
<a class=\"hashtag-cooked\" href=\"#{tag.url}\" data-type=\"tag\" data-slug=\"razed\" data-id="#{tag.id}"><svg class=\"fa d-icon d-icon-tag svg-icon hashtag-color--tag-#{tag.id} svg-string\" xmlns=\"http://www.w3.org/2000/svg\"><use href=\"#tag\"></use></svg><span>razed</span></a>
|
||||
HTML
|
||||
expect(cooked_hashtags[0]["outerHTML"]).to have_tag(
|
||||
"a",
|
||||
with: {
|
||||
class: "hashtag-cooked",
|
||||
href: channel2.relative_url,
|
||||
"data-type": "channel",
|
||||
"data-slug": "random",
|
||||
"data-id": channel2.id,
|
||||
"aria-label": "Random",
|
||||
},
|
||||
) do
|
||||
with_tag(
|
||||
"svg",
|
||||
with: {
|
||||
class:
|
||||
"fa d-icon d-icon-comment svg-icon hashtag-color--channel-#{channel2.id} svg-string",
|
||||
},
|
||||
) { with_tag("use", with: { href: "#comment" }) }
|
||||
end
|
||||
|
||||
expect(cooked_hashtags[1]["outerHTML"]).to have_tag(
|
||||
"a",
|
||||
with: {
|
||||
class: "hashtag-cooked",
|
||||
href: category.url,
|
||||
"data-type": "category",
|
||||
"data-slug": "raspberry-beret",
|
||||
"data-id": category.id,
|
||||
"aria-label": "Raspberry",
|
||||
},
|
||||
) do
|
||||
with_tag(
|
||||
"span",
|
||||
with: {
|
||||
class: "hashtag-category-badge hashtag-color--category-#{category.id}",
|
||||
},
|
||||
)
|
||||
end
|
||||
|
||||
expect(cooked_hashtags[2]["outerHTML"]).to have_tag(
|
||||
"a",
|
||||
with: {
|
||||
class: "hashtag-cooked",
|
||||
href: tag.url,
|
||||
"data-type": "tag",
|
||||
"data-slug": "razed",
|
||||
"data-id": tag.id,
|
||||
"aria-label": "razed",
|
||||
},
|
||||
) do
|
||||
with_tag(
|
||||
"svg",
|
||||
with: {
|
||||
class: "fa d-icon d-icon-tag svg-icon hashtag-color--tag-#{tag.id} svg-string",
|
||||
},
|
||||
) { with_tag("use", with: { href: "#tag" }) }
|
||||
end
|
||||
end
|
||||
|
||||
context "when a user cannot access the category for a cooked channel hashtag" do
|
||||
|
||||
Reference in New Issue
Block a user