From daddd8698bb4c622305126776f1bf40142c652ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20H=C3=A1jek?= Date: Mon, 29 Dec 2025 22:53:28 +0100 Subject: [PATCH 01/14] fix: Text used by screen readers to announce help links is unclear --- app/helpers/application_helper.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 9a288d9a1a..d2d6da7638 100755 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -172,6 +172,8 @@ def link_to_modal(content = "", options = {}) options[:title] ||= options[:for] html_options = { class: "#{options[:class]} modal", title: options[:title] } + html_options[:aria_label] = options[:aria_label] if options[:aria_label] + link_to content, options[:for], html_options end @@ -183,7 +185,8 @@ def link_to_help(help_entry, link = '? Date: Fri, 2 Jan 2026 17:01:38 +0100 Subject: [PATCH 02/14] fix: Removed title, changed the dynamic modal instead --- app/helpers/application_helper.rb | 10 ++++------ app/views/preferences/index.html.erb | 2 +- config/locales/views/en.yml | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index d2d6da7638..c68faae4b9 100755 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -169,10 +169,9 @@ def text_byline(creation, options={}) def link_to_modal(content = "", options = {}) options[:class] ||= "" options[:for] ||= "" - options[:title] ||= options[:for] html_options = { class: "#{options[:class]} modal", title: options[:title] } - html_options[:aria_label] = options[:aria_label] if options[:aria_label] + html_options[:'aria-label'] = options[:aria_label] if options[:aria_label] link_to content, options[:for], html_options end @@ -185,13 +184,12 @@ def link_to_help(help_entry, link = '?<%= f.label :time_zone, t(".your_time_zone") %>
<%= f.time_zone_select :time_zone, nil, default: Time.zone.name %>
<% if $rollout.active?(:set_locale_preference, @user) %> -
<%= f.label :preferred_locale, t(".your_locale") %> <%= link_to_help_modal(help_preferences_locale_path, t(".locale_help_title", locale: current_user.preference.locale_for_mails)) %>
+
<%= f.label :preferred_locale, t(".your_locale") %> <%= link_to_help_modal(help_preferences_locale_path, t(".locale_help_label", locale: current_user.preference.locale_for_mails)) %>
<%= f.select :preferred_locale, locale_options_for_select(@available_locales, "id"), default: @preference.preferred_locale %>
<% end %> diff --git a/config/locales/views/en.yml b/config/locales/views/en.yml index 12b3e8d85d..24d3712e14 100644 --- a/config/locales/views/en.yml +++ b/config/locales/views/en.yml @@ -2127,7 +2127,7 @@ en: legend: Display show_adult_content: Show me adult content without checking. show_whole_work_default: Show the whole work by default. - locale_help_title: Locale preferences + locale_help_label: Locale preferences help misc: heading: Misc legend: Misc From 273d3192864ae28f5e120af0c5e3d3bf4671ff6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20H=C3=A1jek?= Date: Fri, 2 Jan 2026 17:03:10 +0100 Subject: [PATCH 03/14] fix: changed quotes to what they were before --- app/helpers/application_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index c68faae4b9..7a3fea89d9 100755 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -184,7 +184,7 @@ def link_to_help(help_entry, link = '? Date: Fri, 2 Jan 2026 17:14:15 +0100 Subject: [PATCH 04/14] fix: rubocop lint --- app/helpers/application_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 7a3fea89d9..edb3f33677 100755 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -171,7 +171,7 @@ def link_to_modal(content = "", options = {}) options[:for] ||= "" html_options = { class: "#{options[:class]} modal", title: options[:title] } - html_options[:'aria-label'] = options[:aria_label] if options[:aria_label] + html_options[:"aria-label"] = options[:aria_label] if options[:aria_label] link_to content, options[:for], html_options end From a5fa1a78e4e52e44e24d3c1557b88289a1f0293a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20H=C3=A1jek?= Date: Fri, 2 Jan 2026 18:44:00 +0100 Subject: [PATCH 05/14] revert: readded changes to link_to_help --- app/helpers/application_helper.rb | 2 +- app/views/preferences/index.html.erb | 2 +- config/locales/views/en.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index edb3f33677..16fcbf9f37 100755 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -184,7 +184,7 @@ def link_to_help(help_entry, link = '?<%= f.label :time_zone, t(".your_time_zone") %>
<%= f.time_zone_select :time_zone, nil, default: Time.zone.name %>
<% if $rollout.active?(:set_locale_preference, @user) %> -
<%= f.label :preferred_locale, t(".your_locale") %> <%= link_to_help_modal(help_preferences_locale_path, t(".locale_help_label", locale: current_user.preference.locale_for_mails)) %>
+
<%= f.label :preferred_locale, t(".your_locale") %> <%= link_to_help_modal(help_preferences_locale_path, t(".locale_help_title", locale: current_user.preference.locale_for_mails)) %>
<%= f.select :preferred_locale, locale_options_for_select(@available_locales, "id"), default: @preference.preferred_locale %>
<% end %> diff --git a/config/locales/views/en.yml b/config/locales/views/en.yml index 24d3712e14..f0b987d550 100644 --- a/config/locales/views/en.yml +++ b/config/locales/views/en.yml @@ -2127,7 +2127,7 @@ en: legend: Display show_adult_content: Show me adult content without checking. show_whole_work_default: Show the whole work by default. - locale_help_label: Locale preferences help + locale_help_title: Locale preferences help misc: heading: Misc legend: Misc From 816a3e5fffc6f4048254df05f410f97cea168b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20H=C3=A1jek?= Date: Fri, 2 Jan 2026 18:51:58 +0100 Subject: [PATCH 06/14] revert: link_to_help_modal arg back to title --- app/helpers/application_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 16fcbf9f37..e8e3ff1e7b 100755 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -187,9 +187,9 @@ def link_to_help(help_entry, link = '? Date: Fri, 2 Jan 2026 18:57:02 +0100 Subject: [PATCH 07/14] lint: rubocop --- app/helpers/application_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e8e3ff1e7b..a23313f40b 100755 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -184,7 +184,7 @@ def link_to_help(help_entry, link = '? Date: Sun, 4 Jan 2026 14:08:25 +0100 Subject: [PATCH 08/14] wip: testing test changes --- features/other_a/help.feature | 2 +- features/step_definitions/web_steps.rb | 10 ++++++++-- public/javascripts/ao3modal.js | 2 +- public/javascripts/ao3modal.min.js | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/features/other_a/help.feature b/features/other_a/help.feature index 91d6f3058a..c6be1df83c 100644 --- a/features/other_a/help.feature +++ b/features/other_a/help.feature @@ -9,7 +9,7 @@ Feature: Help Given I am logged in as "first_user" When I go to the collections page When I follow "New Collection" - And I follow "Collection moderated" + And I follow help tag "Collection moderated" Then I should see "By default, collections are not moderated" Scenario: view the help popup for chapter title diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb index 65b27cd447..4e57585f5a 100644 --- a/features/step_definitions/web_steps.rb +++ b/features/step_definitions/web_steps.rb @@ -2,8 +2,8 @@ require 'cgi' module WithinHelpers - def with_scope(locator) - locator ? within(locator) { yield } : yield + def with_scope(*args, **options) + args ? within(*args, **options) { yield } : yield end end World(WithinHelpers) @@ -40,6 +40,12 @@ def with_scope(locator) end end +When /^(?:|I )follow help tag "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector| + with_scope('//*[@aria-label=\'' + selector + '\']', kind: :xpath) do + click_link(link) + end +end + When /^(?:|I )follow '([^']*)'(?: within "([^"]*)")?$/ do |link, selector| with_scope(selector) do click_link(link) diff --git a/public/javascripts/ao3modal.js b/public/javascripts/ao3modal.js index 3f16fae3a5..835c7343a2 100644 --- a/public/javascripts/ao3modal.js +++ b/public/javascripts/ao3modal.js @@ -197,7 +197,7 @@ jQuery(document).ready(function() { .filter(function() { return $(this).closest('.userstuff').length === 0; }).click(function(event){ - _show($(this).attr('href'), $(this).attr('title')); + _show($(this).attr('href'), $(this).attr('title') ? $(this).attr('title') : $(this).attr('aria-label')); event.preventDefault(); }); diff --git a/public/javascripts/ao3modal.min.js b/public/javascripts/ao3modal.min.js index 612e712852..afc44ba5b5 100644 --- a/public/javascripts/ao3modal.min.js +++ b/public/javascripts/ao3modal.min.js @@ -1 +1 @@ -jQuery(document).ready(function(){window.ao3modal=function(t){var e,a,i,o,s,l,n,d,c,r,p,h,m=!1,$=t("
",{id:"modal-bg"}).addClass("modal-closer"),f=t("
").addClass("loading"),g=t("
",{id:"modal-wrap"}).addClass("modal-closer"),u=t("
",{id:"modal"}),v=t("
").addClass("content userstuff"),w=t("").addClass("action modal-closer").click(function(t){t.preventDefault()}).attr("href","#").text("Close"),b=t("").addClass("title"),_=(l=navigator.userAgent||navigator.vendor||window.opera,/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(ad|hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(l)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(l.substr(0,4))),k=-1,y=_?0:(d=t("

").css({width:"100%",height:200}),c=t("

").css({height:150,left:0,overflow:"hidden",top:0,visibility:"hidden",width:200}).append(d).appendTo(t("body")),r=d[0].offsetWidth,c.css("overflow","scroll"),r==(n=d[0].offsetWidth)&&(n=c[0].clientWidth),c.remove(),r-n);function x(e){!_&&t("body").css({"margin-right":e?"":y,overflow:e?"":"hidden",height:e?"":$.height()})}function C(){var e,a,i,o=!u.is(":visible");_&&k<0&&(k=t(window).scrollTop()),o&&u.css("opacity",0).show(),u.removeClass("tall"),u.hasClass("img")?(e=v.children("img").first(),u.toggleClass("tall",u.height()>=.95*$.height())):_||(i=Math.min(a=$.height()*p.scale,p.max),u.toggleClass("tall",!i||u[0].scrollHeight>i)),o&&u.hide().css("opacity",""),_?g.css("top",k):g.css("top",t(window).scrollTop())}function z(e,a){m=!1,v.empty(),e instanceof t?v.append(e):v.html(e),a=a instanceof t?a:t("").addClass("title").text(a||""),b.replaceWith(a),b=a,v.is(":empty")||(C(),v.is(":visible")||(h.toggleHandlers(!0),f.hide(),u.fadeIn(function(){v.focus()})))}function O(e,a){if(u.hide(),g.show(),t.support.opacity?$.add(f).fadeIn():$.add(f).show(),x(!1),m=!0,0===e.indexOf("#"))z(t(e).html(),a||"");else if(e.indexOf(".jpg")==e.length-4||e.indexOf(".gif")==e.length-4||e.indexOf(".bmp")==e.length-4||e.indexOf(".png")==e.length-4){u.addClass("img");var i=t("").appendTo(t("body")).attr("src",e),o=function(){var o=t("").addClass("title").attr({href:e,title:"View original",target:"_blank"}).text(a||(-1!=e.indexOf("/")?e.substring(e.lastIndexOf("/")+1):e)).css("text-decoration","underline");i.remove(),m&&(a&&i.attr("alt",a),z(i[0],o))};i[0].complete?o():i.load(o)}else t.ajax({url:e,success:function(t){m&&z(t,a)}})}function D(){m=!1,b.text(""),h.toggleHandlers(!1),g.fadeOut(function(){z(""),x(!0),u.css("width","").removeClass("tall img"),_&&k>=0&&(t("html, body").animate({scrollTop:k},"fast"),k=-1)}),t.support.opacity?$.fadeOut():$.hide()}function j(e){e.each(function(){var e=!!t(this).is("img")&&t(this).removeClass("modal"),a=e?t("").css("border","none").attr({title:e.attr("title")||e.attr("alt"),href:e.attr("src")}).replaceAll(e).append(e):t(this);a.addClass("modal modal-attached").attr("aria-controls","modal").filter(function(){return 0===t(this).closest(".userstuff").length}).click(function(e){O(t(this).attr("href"),t(this).attr("title")),e.preventDefault()}),0===a.attr("href").indexOf("#")&&t(a.attr("href")).hide()})}return t("body").append($.append(f),g.append(u.append(v,t("
").addClass("footer").append(b,w)).trap())),p=_?null:(e={},(a=u.clone()).css("margin-top",9001).addClass("tall").appendTo($),e.scale=a.height()?parseInt(a.css("height"))/100:.8,e.max=parseInt(a.css("max-height")),a.remove(),e),t("body").click(function(e){(t(e.target).hasClass("modal-closer")||u.hasClass("img")&&t(e.target).hasClass("content"))&&D()}),t(window).resize(function(){u.is(":visible")&&C()}),h=(i={38:-20,40:20,33:-200,34:200},o=!1,s={keydown:function(e){if(i[e.which])v[0].scrollTop+=i[e.which],e.preventDefault();else if(u.is(":visible")){var a=e.target,o=a.tagName.toLowerCase(),s=27==e.which,l=13==e.which,n=/^(input|textarea|a|button)$/.test(o),d=!!t(a).closest("#modal")[0];(s||l&&(!d||!n))&&D();var c=e.ctrlKey||e.metaKey;!s&&(d||c)&&(!l||n)||(e.preventDefault(),e.stopPropagation())}},keypress:function(t){i[t.which]&&t.preventDefault()},keyup:function(t){i[t.which]?t.preventDefault():9!=t.which||o||(w.focus(),o=!0,t.preventDefault())}},{toggleHandlers:function(e){for(var a in o=!1,s)s.hasOwnProperty(a)&&(e?t("body").on(a,s[a]):t("body").off(a,s[a]))}}),j(t("a.modal, img.modal")),t("body").on("click","a.modal, img.modal",function(e){var a=t(this);!a.is(".modal-attached")&&(j(a),e.preventDefault(),a.is("img")?a.parent().click():a.click())}),{show:O,setContent:z,hide:D,addLink:j}}(jQuery)}); +const{keys:A}=Object;jQuery(document).ready(function(){window.ao3modal=(function($){var b=!1,c=$('
',{'id':'modal-bg'}).addClass('modal-closer'),d=$('
').addClass('loading'),e=$('
',{'id':'modal-wrap'}).addClass('modal-closer'),f=$('
',{'id':'modal'}),g=$('
').addClass('content userstuff'),h=$('').addClass('action modal-closer').click(_=>_.preventDefault()).attr('href','#').text('Close'),i=$('').addClass('title'),j,k=(function(B){return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(ad|hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(B)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly([-_])|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c([- ]|_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t([- ]|o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8c]))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c([-0]|1)|47|mc|nd|ri)|sgh\-|shar|sie([-m])|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c([- ])|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(B.substr(0,4))})(navigator.userAgent||navigator.vendor||window.opera),l=-1,m=k?0:(function(){var C=$('

').css({'width':'100%','height':200}),_b=$('

').css({'height':150,'left':0,'overflow':'hidden','top':0,'visibility':'hidden','width':200}).append(C).appendTo($('body')),_c=C[0].offsetWidth,D;_b.css('overflow','scroll');D=C[0].offsetWidth;_c==D&&(D=_b[0].clientWidth);_b.remove();return (_c-D)})(),n;function o(_a){if(k)return;$('body').css({'margin-right':_a?'':m,'overflow':_a?'':'hidden','height':_a?'':c.height()})}function p(){var _A,_B,_C=!f.is(':visible');(k&&l<0)&&(l=$(window).scrollTop());_C&&f.css('opacity',0).show();f.removeClass('tall');if(f.hasClass('img')){f.toggleClass('tall',f.height()>=0.95*c.height())}else !k&&(_A=c.height()*j.scale,_B=Math.min(_A,j.max),f.toggleClass('tall',(!_B||f[0].scrollHeight>_B)));_C&&f.hide().css('opacity','');k?e.css('top',l):e.css('top',$(window).scrollTop())}function q(E,aA){b=!1;g.empty();E instanceof $?g.append(E):g.html(E);!(aA instanceof $)&&(aA=$('').addClass('title').text(aA||''));i.replaceWith(aA);i=aA;if(!g.is(':empty')){p();!g.is(':visible')&&(n.toggleHandlers(!0),d.hide(),f.fadeIn(()=>g.focus()))}}function r(aB,aC){f.hide();e.show();$.support.opacity?c.add(d).fadeIn():c.add(d).show();o(!1);b=!0;if(aB.indexOf('#')===0)q($(aB).html(),aC||'');else if(aB.indexOf('.jpg')==aB.length-'.jpg'.length||aB.indexOf('.gif')==aB.length-'.gif'.length||aB.indexOf('.bmp')==aB.length-'.bmp'.length||aB.indexOf('.png')==aB.length-'.png'.length){f.addClass('img');var aD=$('').appendTo($('body')).attr('src',aB),_d=function(){aD.remove();if(!b)return;aC&&aD.attr('alt',aC);q(aD[0],$('').addClass('title').attr({'href':aB,'title':'View original','target':'_blank'}).text(aC||(aB.indexOf('/')!=-1?aB.substring(aB.lastIndexOf('/')+1):aB)).css('text-decoration','underline'))};aD[0].complete?_d():aD.load(_d)}else $.ajax({url:aB,success:function(aE){if(!b)return;q(aE,aC)}})}function s(){b=!1;i.text('');n.toggleHandlers(!1);e.fadeOut(()=>{q('');o(!0);f.css('width','').removeClass('tall img');(k&&l>=0)&&($('html, body').animate({'scrollTop':l},'fast'),l=-1)});$.support.opacity?c.fadeOut():c.hide()}function t(aF){aF.each(function(){var aG=$(this).is('img')&&$(this).removeClass('modal'),a=!aG?$(this):$('').css('border','none').attr({'title':(aG.attr('title')||aG.attr('alt')),'href':aG.attr('src')}).replaceAll(aG).append(aG);a.addClass('modal modal-attached').attr('aria-controls','modal').filter(function(){return $(this).closest('.userstuff').length===0}).click(function(aH){r($(this).attr('href'),$(this).attr('title')||$(this).attr('aria-label'));aH.preventDefault()});a.attr('href').indexOf('#')===0&&$(a.attr('href')).hide()})}$('body').append(c.append(d),e.append(f.append(g,$('
').addClass('footer').append(i,h)).trap()));j=k?null:(function(){var aI={},aJ=f.clone();aJ.css('margin-top',9001).addClass('tall').appendTo(c);aI.scale=!aJ.height()?0.8:parseInt(aJ.css('height'))/100;aI.max=parseInt(aJ.css('max-height'));aJ.remove();return aI})();$('body').click(aK=>{($(aK.target).hasClass('modal-closer')||(f.hasClass('img')&&$(aK.target).hasClass('content')))&&s()});$(window).resize(()=>{f.is(':visible')&&p()});n=(function(){var aL={38:-20,40:20,33:-200,34:200},aM=!1,aN={'keydown':function(aO){if(aL[aO.which]){g[0].scrollTop+=aL[aO.which];aO.preventDefault()}else if(f.is(':visible')){var aP=aO.target,aQ=aP.tagName.toLowerCase(),_D=aO.which==27,_e=aO.which==13,F=/^(input|textarea|a|button)$/.test(aQ),G=!!$(aP).closest('#modal')[0];(_D||_e&&(!G||!F))&&s();var H=aO.ctrlKey||aO.metaKey;(_D||(!G&&!H)||_e&&!F)&&(aO.preventDefault(),aO.stopPropagation())}},'keypress':function(aR){aL[aR.which]&&aR.preventDefault()},'keyup':function(aS){if(aL[aS.which])aS.preventDefault();else (aS.which==9&&!aM)&&(h.focus(),aM=!0,aS.preventDefault())}};return{toggleHandlers:function(aT){aM=!1;for(const aU of A(aN))aT?$('body').on(aU,aN[aU]):$('body').off(aU,aN[aU])}}})();t($('a.modal, img.modal'));$('body').on('click','a.modal, img.modal',function(aV){var aW=$(this);if(aW.is('.modal-attached'))return;t(aW);aV.preventDefault();aW.is('img')?aW.parent().click():aW.click()});return{show:r,setContent:q,hide:s,addLink:t}})(jQuery)}); From c7e9fe2ca4ef293f152821f05b683cdcbbaa98fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20H=C3=A1jek?= Date: Sun, 4 Jan 2026 15:46:01 +0100 Subject: [PATCH 09/14] wip: tests --- features/other_a/help.feature | 2 +- features/step_definitions/web_steps.rb | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/features/other_a/help.feature b/features/other_a/help.feature index c6be1df83c..aaf94bbf29 100644 --- a/features/other_a/help.feature +++ b/features/other_a/help.feature @@ -29,7 +29,7 @@ Feature: Help And I fill in "content" with "Well, maybe not so epic." And I press "Post" And I follow "Add Chapter" - And I follow "Chapter title" + And I follow help tag "Chapter title" Then I should see "You can add a chapter title" Scenario: Asked to log in if trying to access the first login page as guest diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb index 4e57585f5a..0c4d8e6f5b 100644 --- a/features/step_definitions/web_steps.rb +++ b/features/step_definitions/web_steps.rb @@ -3,7 +3,11 @@ module WithinHelpers def with_scope(*args, **options) - args ? within(*args, **options) { yield } : yield + if args.any? || options.any? + within(*args, **options) {yield} + else + yield + end end end World(WithinHelpers) @@ -41,8 +45,8 @@ def with_scope(*args, **options) end When /^(?:|I )follow help tag "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector| - with_scope('//*[@aria-label=\'' + selector + '\']', kind: :xpath) do - click_link(link) + with_scope(selector) do + find(:xpath, '//*[@aria-label=\'' + link + '\']').click end end From f715d3b013070af2c805ff1196e9e896c67c0a1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20H=C3=A1jek?= Date: Sun, 4 Jan 2026 15:47:42 +0100 Subject: [PATCH 10/14] wip: reverted unnecessary changes --- features/step_definitions/web_steps.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb index 0c4d8e6f5b..71cfde10c9 100644 --- a/features/step_definitions/web_steps.rb +++ b/features/step_definitions/web_steps.rb @@ -2,12 +2,8 @@ require 'cgi' module WithinHelpers - def with_scope(*args, **options) - if args.any? || options.any? - within(*args, **options) {yield} - else - yield - end + def with_scope(locator) + locator ? within(locator) { yield } : yield end end World(WithinHelpers) From 20b3ca6c5c079aa3e11497fea5718142ce23b0e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20H=C3=A1jek?= Date: Sun, 4 Jan 2026 16:08:16 +0100 Subject: [PATCH 11/14] wip: supress rubocop --- features/step_definitions/web_steps.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb index 71cfde10c9..ae6c589b5a 100644 --- a/features/step_definitions/web_steps.rb +++ b/features/step_definitions/web_steps.rb @@ -40,7 +40,7 @@ def with_scope(locator) end end -When /^(?:|I )follow help tag "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector| +When /^(?:|I )follow help tag "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector| # rubocop:disable Cucumber/RegexStepName with_scope(selector) do find(:xpath, '//*[@aria-label=\'' + link + '\']').click end From 34f9807273660fb40ef45a46b2726d33f08e33f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20H=C3=A1jek?= Date: Sun, 4 Jan 2026 16:11:26 +0100 Subject: [PATCH 12/14] fix: rubocop lints --- features/step_definitions/web_steps.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb index ae6c589b5a..2833a86baa 100644 --- a/features/step_definitions/web_steps.rb +++ b/features/step_definitions/web_steps.rb @@ -42,7 +42,7 @@ def with_scope(locator) When /^(?:|I )follow help tag "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector| # rubocop:disable Cucumber/RegexStepName with_scope(selector) do - find(:xpath, '//*[@aria-label=\'' + link + '\']').click + find(:xpath, "//*[@aria-label='#{link}']").click end end From e7ed7151b6512d45d1b29407f4ba9f40b0a56534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20H=C3=A1jek?= Date: Mon, 5 Jan 2026 22:17:56 +0100 Subject: [PATCH 13/14] org: moved files, renamed steps, things and stuffs --- features/other_a/help.feature | 4 ++-- features/step_definitions/help_steps.rb | 4 ++++ features/step_definitions/web_steps.rb | 6 ------ 3 files changed, 6 insertions(+), 8 deletions(-) create mode 100644 features/step_definitions/help_steps.rb diff --git a/features/other_a/help.feature b/features/other_a/help.feature index aaf94bbf29..268ff42927 100644 --- a/features/other_a/help.feature +++ b/features/other_a/help.feature @@ -9,7 +9,7 @@ Feature: Help Given I am logged in as "first_user" When I go to the collections page When I follow "New Collection" - And I follow help tag "Collection moderated" + And I open help modal "Collection moderated" Then I should see "By default, collections are not moderated" Scenario: view the help popup for chapter title @@ -29,7 +29,7 @@ Feature: Help And I fill in "content" with "Well, maybe not so epic." And I press "Post" And I follow "Add Chapter" - And I follow help tag "Chapter title" + And I open help modal "Chapter title" Then I should see "You can add a chapter title" Scenario: Asked to log in if trying to access the first login page as guest diff --git a/features/step_definitions/help_steps.rb b/features/step_definitions/help_steps.rb new file mode 100644 index 0000000000..f782c0d9bf --- /dev/null +++ b/features/step_definitions/help_steps.rb @@ -0,0 +1,4 @@ +When /^(?:|I )open help modal "([^"]*)"$/ do |link| # rubocop:disable Cucumber/RegexStepName + Capybara.enable_aria_label = true + step %{I follow "#{link}"} +end \ No newline at end of file diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb index 2833a86baa..65b27cd447 100644 --- a/features/step_definitions/web_steps.rb +++ b/features/step_definitions/web_steps.rb @@ -40,12 +40,6 @@ def with_scope(locator) end end -When /^(?:|I )follow help tag "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector| # rubocop:disable Cucumber/RegexStepName - with_scope(selector) do - find(:xpath, "//*[@aria-label='#{link}']").click - end -end - When /^(?:|I )follow '([^']*)'(?: within "([^"]*)")?$/ do |link, selector| with_scope(selector) do click_link(link) From 78fdf41f1c06a986555b76e02c9426b012d43fd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20H=C3=A1jek?= Date: Mon, 5 Jan 2026 22:24:43 +0100 Subject: [PATCH 14/14] feat: \n --- features/step_definitions/help_steps.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/step_definitions/help_steps.rb b/features/step_definitions/help_steps.rb index f782c0d9bf..2daf87cc34 100644 --- a/features/step_definitions/help_steps.rb +++ b/features/step_definitions/help_steps.rb @@ -1,4 +1,4 @@ When /^(?:|I )open help modal "([^"]*)"$/ do |link| # rubocop:disable Cucumber/RegexStepName Capybara.enable_aria_label = true step %{I follow "#{link}"} -end \ No newline at end of file +end