From 7be2f35fff06e7b0a64488f5f0f7770448f39aee Mon Sep 17 00:00:00 2001 From: Rebecca Pearce <17481621+beccapearce@users.noreply.github.com> Date: Tue, 12 Mar 2024 13:52:39 +0000 Subject: [PATCH 1/3] Use publishing component to render contents list on service manual guide When the contents list on service manual guides was being read out by screen readers it would read the dashes in the contents list as "en dash" This was not desired behaviour and has been fixed in the govuk-publishing-components. This uses the fixed publishing component to take advantage of the fixed behaviour. Using the new publishing component also makes the page more consistent with other pages within the app. --- .../service_manual_guide_presenter.rb | 2 +- .../service_manual_guide.html.erb | 31 +++---------------- .../service_manual_guide_presenter_test.rb | 4 +++ 3 files changed, 10 insertions(+), 27 deletions(-) diff --git a/app/presenters/service_manual_guide_presenter.rb b/app/presenters/service_manual_guide_presenter.rb index 5f0c3d3a0..deade88aa 100644 --- a/app/presenters/service_manual_guide_presenter.rb +++ b/app/presenters/service_manual_guide_presenter.rb @@ -8,7 +8,7 @@ def body def header_links header_links = details.fetch("header_links", {}) - Array(header_links).map { |h| ActiveSupport::HashWithIndifferentAccess.new(h) } + Array(header_links).map { |h| ActiveSupport::HashWithIndifferentAccess.new(h.transform_keys { |k| k == "title" ? "text" : k }) } end def content_owners diff --git a/app/views/content_items/service_manual_guide.html.erb b/app/views/content_items/service_manual_guide.html.erb index fadba9aaf..a2b05696c 100644 --- a/app/views/content_items/service_manual_guide.html.erb +++ b/app/views/content_items/service_manual_guide.html.erb @@ -54,32 +54,11 @@
-
-
- <%= render "govuk_publishing_components/components/heading", { - text: "Page contents:", - heading_level: 2, - font_size: "s", - margin_bottom: 1, - } %> -
-
    "> - <% @content_item.header_links.each do |header_link| %> -
  • - <%= link_to(header_link[:title], header_link[:href], class: 'govuk-link') %> -
  • - <% end %> -
-
- + <%= render "govuk_publishing_components/components/contents_list", { + underline_links: true, + contents: @content_item.header_links, + id: "contents" + } %>
diff --git a/test/presenters/service_manual_guide_presenter_test.rb b/test/presenters/service_manual_guide_presenter_test.rb index f740865e7..309894132 100644 --- a/test/presenters/service_manual_guide_presenter_test.rb +++ b/test/presenters/service_manual_guide_presenter_test.rb @@ -138,4 +138,8 @@ def schema_name assert_equal expected_history, presented_item.previous_changes end + + test "#header_links returns a list of hrefs and text" do + assert_equal [{ "text" => "What is it, why it works and how to do it", "href" => "#what-is-it-why-it-works-and-how-to-do-it" }], presented_item.header_links + end end From 271654fa41a19c2ff2661d7f5d8b814c5463cff1 Mon Sep 17 00:00:00 2001 From: Rebecca Pearce <17481621+beccapearce@users.noreply.github.com> Date: Tue, 12 Mar 2024 15:58:14 +0000 Subject: [PATCH 2/3] Delete unused styling In the previous commit we changed the contents list on the service service_manual_guide page to use the publishing component. This means that we are now able to delete the custom styles and javascript that were being used previously. --- .../highlight-active-section-heading.js | 156 ------------------ .../stylesheets/modules/_page-contents.scss | 18 -- .../views/_service_manual_guide.scss | 1 - .../service_manual_guide.html.erb | 2 +- 4 files changed, 1 insertion(+), 176 deletions(-) delete mode 100644 app/assets/javascripts/modules/highlight-active-section-heading.js delete mode 100644 app/assets/stylesheets/modules/_page-contents.scss diff --git a/app/assets/javascripts/modules/highlight-active-section-heading.js b/app/assets/javascripts/modules/highlight-active-section-heading.js deleted file mode 100644 index d4c6fa86b..000000000 --- a/app/assets/javascripts/modules/highlight-active-section-heading.js +++ /dev/null @@ -1,156 +0,0 @@ -window.GOVUK = window.GOVUK || {} -window.GOVUK.Modules = window.GOVUK.Modules || {}; - -(function (Modules) { - function HighlightActiveSectionHeading ($module) { - this.$module = $module - this._hasResized = true - this._hasScrolled = true - this._interval = 50 - this.anchorIDs = [] - } - - HighlightActiveSectionHeading.prototype.init = function () { - window.addEventListener('resize', function () { this._hasResized = true }.bind(this)) - window.addEventListener('scroll', function () { this._hasScrolled = true }.bind(this)) - - setInterval(this.checkResize.bind(this), this._interval) - setInterval(this.checkScroll.bind(this), this._interval) - - this.anchors = this.$module.querySelectorAll('.js-page-contents a') - this.getAnchors() - - this.checkResize() - this.checkScroll() - } - - HighlightActiveSectionHeading.prototype.checkResize = function () { - if (this._hasResized) { - this._hasResized = false - this._hasScrolled = true - } - } - - HighlightActiveSectionHeading.prototype.checkScroll = function () { - if (this._hasScrolled) { - this._hasScrolled = false - var windowDimensions = this.getWindowDimensions() - if (windowDimensions.width <= 768) { - this.removeActiveItem() - } else { - this.updateActiveNavItem() - } - } - } - - HighlightActiveSectionHeading.prototype.getWindowDimensions = function () { - return { - height: window.innerHeight, - width: window.innerWidth - } - } - - HighlightActiveSectionHeading.prototype.getAnchors = function () { - for (var i = 0; i < this.anchors.length; i++) { - var anchorID = this.anchors[i].getAttribute('href') - // e.g. anchorIDs['#meeting-the-digital-service-standard', '#understand-your-users', '#research-continually'] - this.anchorIDs.push(anchorID) - } - } - - HighlightActiveSectionHeading.prototype.updateActiveNavItem = function () { - var windowVerticalPosition = this.getWindowPositions() - var footerPosition = this.getFooterPosition() - - for (var i = 0; i < this.anchors.length; i++) { - var theID = this.anchorIDs[i] - var theNextID = this.anchorIDs[i + 1] - - var $theID = document.getElementById(theID.substring(1)) // remove the # at the start - var $theNextID = theNextID ? document.getElementById(theNextID.substring(1)) : null // remove the # at the start - - var headingPosition = this.getHeadingPosition($theID) - if (!headingPosition) { - return - } - - headingPosition = headingPosition - 53 // fix the offset from top of page - - if (theNextID) { - var nextHeadingPosition = this.getNextHeadingPosition($theNextID) - } - - var distanceBetweenHeadings = this.getDistanceBetweenHeadings(headingPosition, nextHeadingPosition) - var isPastHeading - - if (distanceBetweenHeadings) { - isPastHeading = (windowVerticalPosition >= headingPosition && windowVerticalPosition < (headingPosition + distanceBetweenHeadings)) - } else { - // when distanceBetweenHeadings is false (as there isn't a next heading) - isPastHeading = (windowVerticalPosition >= headingPosition && windowVerticalPosition < footerPosition) - } - - if (isPastHeading) { - this.setActiveItem(theID) - } - } - } - - HighlightActiveSectionHeading.prototype.getFooterPosition = function () { - var footer = document.querySelector('.govuk-footer') - if (footer) { - return this.getElementPosition(footer) - } - } - - // these two functions call getElementPosition because the test needs to individually - // override them - otherwise we could combine these four functions into one - HighlightActiveSectionHeading.prototype.getHeadingPosition = function (element) { - return this.getElementPosition(element) - } - - HighlightActiveSectionHeading.prototype.getNextHeadingPosition = function (element) { - return this.getHeadingPosition(element) - } - - HighlightActiveSectionHeading.prototype.getElementPosition = function (element) { - if (element) { - var rect = element.getBoundingClientRect() - var offset = { - top: rect.top + window.scrollY, - left: rect.left + window.scrollX - } - return offset.top - } - } - - HighlightActiveSectionHeading.prototype.getDistanceBetweenHeadings = function (headingPosition, nextHeadingPosition) { - var distanceBetweenHeadings = (nextHeadingPosition - headingPosition) - return distanceBetweenHeadings - } - - HighlightActiveSectionHeading.prototype.setActiveItem = function (theID) { - for (var i = 0; i < this.anchors.length; i++) { - var href = this.anchors[i].getAttribute('href') - if (href === theID) { - this.anchors[i].classList.add('active') - } else { - this.anchors[i].classList.remove('active') - } - } - } - - HighlightActiveSectionHeading.prototype.removeActiveItem = function () { - for (var i = 0; i < this.anchors.length; i++) { - this.anchors[i].classList.remove('active') - } - } - - HighlightActiveSectionHeading.prototype.getWindowPositions = function () { - var doc = document.documentElement - var top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0) - return top - } - - Modules.HighlightActiveSectionHeading = HighlightActiveSectionHeading -})(window.GOVUK.Modules) diff --git a/app/assets/stylesheets/modules/_page-contents.scss b/app/assets/stylesheets/modules/_page-contents.scss deleted file mode 100644 index e3f3411d1..000000000 --- a/app/assets/stylesheets/modules/_page-contents.scss +++ /dev/null @@ -1,18 +0,0 @@ -.app-page-contents { - &__list li { - margin-left: govuk-spacing(0); - padding-right: govuk-spacing(3); - - &::before { - content: "– "; - display: inline-block; - padding-right: govuk-spacing(1); - } - } - - // Styles required by GOVUK.HighlightActiveNavItem JS - &__list .active { - letter-spacing: 0; - font-weight: bold; - } -} diff --git a/app/assets/stylesheets/views/_service_manual_guide.scss b/app/assets/stylesheets/views/_service_manual_guide.scss index 10d0dbb4f..0521500e9 100644 --- a/app/assets/stylesheets/views/_service_manual_guide.scss +++ b/app/assets/stylesheets/views/_service_manual_guide.scss @@ -5,7 +5,6 @@ @import "../modules/govspeak-wrapper"; @import "../modules/hero"; @import "../modules/notice"; -@import "../modules/page-contents"; @import "../modules/page-header"; @import "../modules/panel"; @import "../modules/related-content"; diff --git a/app/views/content_items/service_manual_guide.html.erb b/app/views/content_items/service_manual_guide.html.erb index a2b05696c..5a0c8ba9a 100644 --- a/app/views/content_items/service_manual_guide.html.erb +++ b/app/views/content_items/service_manual_guide.html.erb @@ -51,7 +51,7 @@
-
+
<%= render "govuk_publishing_components/components/contents_list", { From f73055662e97af12e879d10e68bd45838bcef4eb Mon Sep 17 00:00:00 2001 From: Rebecca Pearce <17481621+beccapearce@users.noreply.github.com> Date: Fri, 5 Apr 2024 14:58:10 +0100 Subject: [PATCH 3/3] Add a 20px margin on the sticky contents Add a margin to the top of the contents list on service manual guides so it isn't too high up the page when scrolling --- app/assets/stylesheets/modules/_sticky.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/modules/_sticky.scss b/app/assets/stylesheets/modules/_sticky.scss index 444b4a699..ee07626e3 100644 --- a/app/assets/stylesheets/modules/_sticky.scss +++ b/app/assets/stylesheets/modules/_sticky.scss @@ -1,6 +1,6 @@ .app-sticky-element { @include govuk-media-query($from: tablet) { position: sticky; - top: 0; + top: govuk-spacing(4); } }