From f3011d3b74254ef257f8f755a1257e97ccf5a552 Mon Sep 17 00:00:00 2001 From: Dylan Nugent Date: Wed, 17 Jun 2020 15:57:12 -0400 Subject: [PATCH] spoilers: Improve UI for spoilers. Adds support for clicking anywhere on the header (except in a link) to expand a spoiler block. Also fixes jumpy animation glitch on spoiler collapse. Fixes #15414. Co-authored-by: Sara Gulotta --- static/js/click_handlers.js | 4 +++- static/js/spoilers.js | 24 +++++++++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/static/js/click_handlers.js b/static/js/click_handlers.js index 0bd984c3ac..3d1862d34c 100644 --- a/static/js/click_handlers.js +++ b/static/js/click_handlers.js @@ -19,7 +19,9 @@ exports.initialize = function () { function is_clickable_message_element(target) { return target.is("a") || target.is("img.message_inline_image") || target.is("img.twitter-avatar") || target.is("div.message_length_controller") || target.is("textarea") || target.is("input") || - target.is("i.edit_content_button") || target.is(".spoiler-arrow") || + target.is("i.edit_content_button") || + // For spoilers, allow clicking either the header or elements within it + target.is(".spoiler-header") || target.parents(".spoiler-header").length > 0 || target.is(".highlight") && target.parent().is("a"); } diff --git a/static/js/spoilers.js b/static/js/spoilers.js index 8a51a8c4ce..27cdec8bcb 100644 --- a/static/js/spoilers.js +++ b/static/js/spoilers.js @@ -1,5 +1,5 @@ function collapse_spoiler(spoiler) { - const spoiler_height = spoiler.prop('scrollHeight'); + const spoiler_height = spoiler.height(); // Set height to rendered height on next frame, then to zero on following // frame to allow CSS transition animation to work @@ -34,19 +34,29 @@ function expand_spoiler(spoiler) { } exports.initialize = function () { - $("body").on("click", ".spoiler-button", function (e) { + $("body").on("click", ".spoiler-header", function (e) { + const button = $(this).children('.spoiler-button'); + const arrow = button.children('.spoiler-arrow'); + const spoiler_content = $(this).siblings(".spoiler-content"); + const target = $(e.target); + + // Spoiler headers can contain markdown, including links. We follow the link + // and don't expand the spoiler if a link has been clicked (unless it's the dropdown arrow) + // This can be accomplished by just breaking from this function before preventing default + // or toggling the state of the spoiler block. + if (target.is('a') && !target.hasClass('.spoiler-button')) { + return; + } + e.preventDefault(); e.stopPropagation(); - const arrow = $(this).children('.spoiler-arrow'); - const spoiler_content = $(this).parent().siblings(".spoiler-content"); - if (spoiler_content.hasClass("spoiler-content-open")) { // Content was open, we are collapsing arrow.removeClass("spoiler-button-open"); // Modify ARIA roles for screen readers - $(this).attr("aria-expanded", "false"); + button.attr("aria-expanded", "false"); spoiler_content.attr("aria-hidden", "true"); collapse_spoiler(spoiler_content); @@ -55,7 +65,7 @@ exports.initialize = function () { arrow.addClass("spoiler-button-open"); // Modify ARIA roles for screen readers - $(this).attr("aria-expanded", "true"); + button.attr("aria-expanded", "true"); spoiler_content.attr("aria-hidden", "false"); expand_spoiler(spoiler_content);