A11Y: Fix selecting topic when navigation via keyboard (#22996)
This fixes:
- a regression from 30c152c
, where navigating to a topic's last reply
via keyboard would lose track of the topic when returning to the topic
list
- an issue where if a topic's last post is a small post, navigating to it
via keyboard would not focus the post
Co-authored-by: David Taylor <david@taylorhq.com>
This commit is contained in:
parent
976219ed5c
commit
161d3d190a
|
@ -4,6 +4,7 @@ import DiscourseURL from "discourse/lib/url";
|
|||
import I18n from "I18n";
|
||||
import discourseComputed, { bind } from "discourse-common/utils/decorators";
|
||||
import { scheduleOnce } from "@ember/runloop";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
function entranceDate(dt, showTime) {
|
||||
const today = new Date();
|
||||
|
@ -29,6 +30,8 @@ function entranceDate(dt, showTime) {
|
|||
}
|
||||
|
||||
export default Component.extend(CleansUp, {
|
||||
router: service(),
|
||||
session: service(),
|
||||
elementId: "topic-entrance",
|
||||
classNameBindings: ["visible::hidden"],
|
||||
topic: null,
|
||||
|
@ -161,6 +164,11 @@ export default Component.extend(CleansUp, {
|
|||
},
|
||||
|
||||
_jumpTo(destination) {
|
||||
this.session.set("lastTopicIdViewed", {
|
||||
topicId: this.topic.id,
|
||||
historyUuid: this.router.location.getState?.().uuid,
|
||||
});
|
||||
|
||||
this.cleanUp();
|
||||
DiscourseURL.routeTo(destination);
|
||||
},
|
||||
|
|
|
@ -37,9 +37,9 @@ export function showEntrance(e) {
|
|||
|
||||
export function navigateToTopic(topic, href) {
|
||||
const owner = getOwner(this);
|
||||
const siteSettings = owner.lookup("service:site-settings");
|
||||
const router = owner.lookup("service:router");
|
||||
const session = owner.lookup("service:session");
|
||||
const siteSettings = owner.lookup("service:site-settings");
|
||||
const appEvents = owner.lookup("service:appEvents");
|
||||
|
||||
if (siteSettings.page_loading_indicator !== "slider") {
|
||||
|
@ -284,7 +284,10 @@ export default Component.extend({
|
|||
}
|
||||
}
|
||||
|
||||
if (classList.contains("raw-topic-link")) {
|
||||
if (
|
||||
classList.contains("raw-topic-link") ||
|
||||
classList.contains("post-activity")
|
||||
) {
|
||||
if (wantsNewWindow(e)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -319,6 +322,13 @@ export default Component.extend({
|
|||
|
||||
unhandledRowClick() {},
|
||||
|
||||
keyDown(e) {
|
||||
if (e.key === "Enter" && e.target.classList.contains("post-activity")) {
|
||||
e.preventDefault();
|
||||
return this.navigateToTopic(this.topic, e.target.getAttribute("href"));
|
||||
}
|
||||
},
|
||||
|
||||
navigateToTopic,
|
||||
|
||||
highlight(opts = { isLastViewedTopic: false }) {
|
||||
|
|
|
@ -76,6 +76,9 @@ export function highlightPost(postNumber) {
|
|||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
container.querySelector(".tabLoc")?.focus();
|
||||
|
||||
const element = container.querySelector(".topic-body");
|
||||
if (!element || element.classList.contains("highlighted")) {
|
||||
return;
|
||||
|
@ -88,7 +91,6 @@ export function highlightPost(postNumber) {
|
|||
element.removeEventListener("animationend", removeHighlighted);
|
||||
};
|
||||
element.addEventListener("animationend", removeHighlighted);
|
||||
container.querySelector(".tabLoc").focus();
|
||||
}
|
||||
|
||||
export function emailValid(email) {
|
||||
|
|
|
@ -186,6 +186,9 @@ export default createWidget("post-small-action", {
|
|||
}
|
||||
|
||||
return [
|
||||
h("span.tabLoc", {
|
||||
attributes: { "aria-hidden": true, tabindex: -1 },
|
||||
}),
|
||||
h("div.topic-avatar", iconNode(icons[attrs.actionCode] || "exclamation")),
|
||||
h("div.small-action-desc", [
|
||||
h("div.small-action-contents", contents),
|
||||
|
|
|
@ -328,6 +328,9 @@
|
|||
.num.activity {
|
||||
a {
|
||||
padding: 15px 5px;
|
||||
span.relative-date {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,15 @@ module PageObjects
|
|||
find("#{topic_list_item_class(topic)} a.raw-topic-link").click
|
||||
end
|
||||
|
||||
def visit_topic_last_reply_via_keyboard(topic)
|
||||
find("#{topic_list_item_class(topic)} a.post-activity").native.send_keys(:return)
|
||||
end
|
||||
|
||||
def visit_topic_first_reply_via_keyboard(topic)
|
||||
find("#{topic_list_item_class(topic)} button.posts-map").native.send_keys(:return)
|
||||
find("#topic-entrance button.jump-top").native.send_keys(:return)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def topic_list_item_class(topic)
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe "Topic list focus", type: :system do
|
||||
let!(:topics) { Fabricate.times(10, :post).map(&:topic) }
|
||||
fab!(:topics) { Fabricate.times(10, :post).map(&:topic) }
|
||||
|
||||
before { Fabricate(:admin) }
|
||||
before_all do
|
||||
sidebar_url = Fabricate(:sidebar_url, name: "my topic link", value: "/t/#{topics[4].id}")
|
||||
|
||||
Fabricate(
|
||||
:sidebar_section_link,
|
||||
sidebar_section:
|
||||
SidebarSection.find_by(section_type: SidebarSection.section_types[:community]),
|
||||
linkable: sidebar_url,
|
||||
)
|
||||
end
|
||||
|
||||
let(:discovery) { PageObjects::Pages::Discovery.new }
|
||||
let(:topic) { PageObjects::Pages::Topic.new }
|
||||
|
@ -15,7 +24,7 @@ describe "Topic list focus", type: :system do
|
|||
end
|
||||
|
||||
it "refocusses last clicked topic when going back to topic list" do
|
||||
visit("/")
|
||||
visit("/latest")
|
||||
expect(page).to have_css("body.navigation-topics")
|
||||
expect(discovery.topic_list).to have_topics
|
||||
|
||||
|
@ -37,4 +46,39 @@ describe "Topic list focus", type: :system do
|
|||
expect(page).to have_css("body.navigation-topics")
|
||||
expect(focussed_topic_id).to eq(nil)
|
||||
end
|
||||
|
||||
it "refocusses properly when navigating via the 'last activity' link" do
|
||||
visit("/latest")
|
||||
|
||||
# Visit topic via activity column and keyboard
|
||||
discovery.topic_list.visit_topic_last_reply_via_keyboard(topics[2])
|
||||
expect(topic).to have_topic_title(topics[2].title)
|
||||
|
||||
# Going back to the topic-list should re-focus
|
||||
page.go_back
|
||||
expect(page).to have_css("body.navigation-topics")
|
||||
expect(focussed_topic_id).to eq(topics[2].id)
|
||||
|
||||
# Visit topic via keyboard using posts map (OP button)
|
||||
discovery.topic_list.visit_topic_first_reply_via_keyboard(topics[4])
|
||||
expect(topic).to have_topic_title(topics[4].title)
|
||||
|
||||
# Going back to the topic-list should re-focus
|
||||
page.go_back
|
||||
expect(page).to have_css("body.navigation-topics")
|
||||
expect(focussed_topic_id).to eq(topics[4].id)
|
||||
end
|
||||
|
||||
it "does not refocus topic when visiting via something other than topic list" do
|
||||
visit("/latest")
|
||||
|
||||
# Clicking sidebar link should visit topic
|
||||
find(".sidebar-section-link[data-link-name='my topic link']").click
|
||||
expect(topic).to have_topic_title(topics[4].title)
|
||||
|
||||
# Going back to the topic-list should not re-focus
|
||||
page.go_back
|
||||
expect(page).to have_css("body.navigation-topics")
|
||||
expect(focussed_topic_id).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue