From f66551af557fd9e876f95277598be9635a290b8d Mon Sep 17 00:00:00 2001 From: owenatgov Date: Thu, 4 Mar 2021 13:37:54 +0000 Subject: [PATCH] Tidy up untranslated content and formatting on accordion docs --- CHANGELOG.md | 5 + .../components/accordion.js | 39 ++++- .../component_guide/show.html.erb | 2 +- .../components/_accordion.html.erb | 25 +++ .../components/docs/accordion.yml | 146 +++++++++--------- config/locales/en.yml | 9 ++ spec/javascripts/components/accordion-spec.js | 65 +++++++- 7 files changed, 205 insertions(+), 86 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c4ef3d185..ff39ed4d70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,14 @@ useful summary for people upgrading their application, not a replication of the commit log. +<<<<<<< HEAD ## 24.9.1 * Change to the exceptions list for Brexit branding ([PR #2011](https://github.com/alphagov/govuk_publishing_components/pull/2011)) +======= +## Unreleased +* Tidy up untranslated content and formatting on accordion docs ([PR #1958](https://github.com/alphagov/govuk_publishing_components/pull/1958)) PATCH +>>>>>>> Tidy up untranslated content and formatting on accordion docs ## 24.9.0 diff --git a/app/assets/javascripts/govuk_publishing_components/components/accordion.js b/app/assets/javascripts/govuk_publishing_components/components/accordion.js index 78f725a00f..5a6402f5bc 100644 --- a/app/assets/javascripts/govuk_publishing_components/components/accordion.js +++ b/app/assets/javascripts/govuk_publishing_components/components/accordion.js @@ -31,7 +31,16 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; this.upChevonIconClass = 'gem-c-accordion-nav__chevron' this.downChevonIconClass = 'gem-c-accordion-nav__chevron--down' - // Indicate that js has worked + // Translated component content and language attribute pulled from data attributes + this.$module.actions = {} + this.$module.actions.locale = this.$module.getAttribute('data-locale') + this.$module.actions.showText = this.$module.getAttribute('data-show-text') + this.$module.actions.hideText = this.$module.getAttribute('data-hide-text') + this.$module.actions.showAllText = this.$module.getAttribute('data-show-all-text') + this.$module.actions.hideAllText = this.$module.getAttribute('data-hide-all-text') + this.$module.actions.thisSectionVisuallyHidden = this.$module.getAttribute('data-this-section-visually-hidden') + + // Indicate that JavaScript has worked this.$module.classList.add('gem-c-accordion--active') this.initControls() @@ -117,7 +126,11 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; // Build additional copy for assistive technology var srAdditionalCopy = document.createElement('span') srAdditionalCopy.classList.add('govuk-visually-hidden') - srAdditionalCopy.innerHTML = ' this section' + srAdditionalCopy.innerHTML = this.$module.actions.thisSectionVisuallyHidden + + if (this.$module.actions.locale) { + srAdditionalCopy.lang = this.filterLocale('this_section_visually_hidden') + } // Build additional wrapper for toggle text, place icon after wrapped text. var wrapperShowHideIcon = document.createElement('span') @@ -178,12 +191,16 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; var icon = section.querySelector('.' + this.upChevonIconClass) var showHideText = section.querySelector('.' + this.sectionShowHideTextClass) var button = section.querySelector('.' + this.sectionButtonClass) - var newButtonText = expanded ? 'Hide' : 'Show' + var newButtonText = expanded ? this.$module.actions.hideText : this.$module.actions.showText showHideText.innerHTML = newButtonText button.setAttribute('aria-expanded', expanded) button.classList.add(this.toggleLinkClass) + if (this.$module.actions.locale) { + showHideText.lang = this.filterLocale(expanded ? 'hide_text' : 'show_text') + } + // Swap icon, change class if (expanded) { section.classList.add(this.sectionExpandedClass) @@ -218,10 +235,15 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; GemAccordion.prototype.updateOpenAllButton = function (expanded) { var icon = this.openAllButton.querySelector('.' + this.upChevonIconClass) var openAllCopy = this.openAllButton.querySelector('.' + this.openAllTextClass) - var newButtonText = expanded ? 'Hide all sections' : 'Show all sections' + var newButtonText = expanded ? this.$module.actions.hideAllText : this.$module.actions.showAllText + this.openAllButton.setAttribute('aria-expanded', expanded) openAllCopy.innerHTML = newButtonText + if (this.$module.actions.locale) { + openAllCopy.lang = this.filterLocale(expanded ? 'hide_all_text' : 'show_all_text') + } + // Swap icon, toggle class if (expanded) { icon.classList.remove(this.downChevonIconClass) @@ -329,5 +351,14 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; return target } + GemAccordion.prototype.filterLocale = function (key) { + if (this.$module.actions.locale && this.$module.actions.locale.indexOf('{') !== -1) { + var locales = JSON.parse(this.$module.actions.locale) + return locales[key] + } else if (this.$module.actions.locale) { + return this.$module.actions.locale + } + } + Modules.GemAccordion = GemAccordion })(window.GOVUK.Modules) diff --git a/app/views/govuk_publishing_components/component_guide/show.html.erb b/app/views/govuk_publishing_components/component_guide/show.html.erb index 76766160dc..7c660ed1f2 100644 --- a/app/views/govuk_publishing_components/component_guide/show.html.erb +++ b/app/views/govuk_publishing_components/component_guide/show.html.erb @@ -24,7 +24,7 @@ <% end %> -

<%= link_to "Search for usage of this component on GitHub", @component_doc.github_search_url, class: "govuk-link" %>

+

<%= link_to "Search for usage of this component on GitHub", @component_doc.github_search_url, class: "govuk-link" %>.

diff --git a/app/views/govuk_publishing_components/components/_accordion.html.erb b/app/views/govuk_publishing_components/components/_accordion.html.erb index 487572fc5a..56aed0f431 100644 --- a/app/views/govuk_publishing_components/components/_accordion.html.erb +++ b/app/views/govuk_publishing_components/components/_accordion.html.erb @@ -11,9 +11,34 @@ accordion_classes << 'gem-c-accordion--condensed' if condensed accordion_classes << (shared_helper.get_margin_bottom) + translations = { + show_text: "components.accordion.show", + hide_text: "components.accordion.hide", + show_all_text: "components.accordion.show_all", + hide_all_text: "components.accordion.hide_all", + this_section_visually_hidden: "components.accordion.this_section_visually_hidden", + } + + locales = {} + data_attributes ||= {} data_attributes[:module] = 'gem-accordion' data_attributes[:anchor_navigation] = anchor_navigation + + translations.each do |key, translation| + locales[key] = shared_helper.t_locale(translation) + data_attributes[key] = t(translation) + end + + unique_locales = locales.values.uniq + + if unique_locales.length > 1 + data_attributes[:locale] = locales + else + if unique_locales[0] != I18n.locale + data_attributes[:locale] = unique_locales[0] + end + end %> <% if items.any? %> <%= tag.div(class: accordion_classes, id: id, data: data_attributes) do %> diff --git a/app/views/govuk_publishing_components/components/docs/accordion.yml b/app/views/govuk_publishing_components/components/docs/accordion.yml index 6bfc9f641b..63939dbe82 100644 --- a/app/views/govuk_publishing_components/components/docs/accordion.yml +++ b/app/views/govuk_publishing_components/components/docs/accordion.yml @@ -40,21 +40,21 @@ examples: data: items: - heading: - text: "Writing well for the web" + text: Writing well for the web content: - html: "

This is the content for Writing well for the web.

" + html:

This is the content for Writing well for the web.

- heading: - text: "Writing well for specialists" + text: Writing well for specialists content: - html: "

This is the content for Writing well for specialists.

" + html:

This is the content for Writing well for specialists.

- heading: - text: "Know your audience" + text: Know your audience content: - html: "

This is the content for Know your audience.

" + html:

This is the content for Know your audience.

- heading: - text: "How people read" + text: How people read content: - html: "

This is the content for How people read.

" + html:

This is the content for How people read.

with_supplied_identification: description: | An `id` is optional as it's automatically generated, but it can be supplied if a specific `id` is required. @@ -66,29 +66,29 @@ examples: id: with-supplied-id-thats-unique-across-the-domain items: - heading: - text: "Writing well for the web" + text: Writing well for the web content: - html: "

This is the content for Writing well for the web.

" + html:

This is the content for Writing well for the web.

- heading: - text: "Writing well for specialists" + text: Writing well for specialists content: - html: "

This is the content for Writing well for specialists.

" + html:

This is the content for Writing well for specialists.

- heading: - text: "Know your audience" + text: Know your audience content: - html: "

This is the content for Know your audience.

" + html:

This is the content for Know your audience.

- heading: - text: "How people read" + text: How people read content: - html: "

This is the content for How people read.

" + html:

This is the content for How people read.

with_summary: description: Adds a subheading below each section heading. data: items: - heading: - text: "Understanding agile project management" + text: Understanding agile project management summary: - text: "Introductions, methods, core features." + text: Introductions, methods, core features. content: html: '' - heading: - text: "Working with agile methods" + text: Working with agile methods summary: - text: "Workspaces, tools and techniques, user stories, planning." + text: Workspaces, tools and techniques, user stories, planning. content: html: '' - heading: - text: "Governing agile services" + text: Governing agile services summary: - text: "Principles, measuring progress, spending money." + text: Principles, measuring progress, spending money. content: html: '' - heading: - text: "Phases of an agile project" + text: Phases of an agile project summary: - text: "Discovery, alpha, beta, live and retirement." + text: Discovery, alpha, beta, live and retirement. content: html: '' \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index ab5244bc98..e877f81e96 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -23,6 +23,12 @@ en: common: translations: "Translations" components: + accordion: + show: "Show" + hide: "Hide" + show_all: "Show all sections" + hide_all: "Hide all sections" + this_section_visually_hidden: " this section" attachment: opendocument_html: "This file is in an OpenDocument format" request_format_text: "This file may not be suitable for users of assistive technology." @@ -58,6 +64,9 @@ en: search_button: "Search GOV.UK" show_button: "Show search" hide_button: "Hide search" + top_level: "Top level" + nav_items_aria_label: "Show or hide Top Level Navigation" + menu: "Menu" organisation_schema: all_content_search_description: "Find all content from %{organisation}" radio: diff --git a/spec/javascripts/components/accordion-spec.js b/spec/javascripts/components/accordion-spec.js index 33f0581fd7..b838321016 100644 --- a/spec/javascripts/components/accordion-spec.js +++ b/spec/javascripts/components/accordion-spec.js @@ -5,12 +5,10 @@ describe('An accordion component', function () { 'use strict' var element - var container - - beforeEach(function () { - container = document.createElement('div') - container.innerHTML = - '
' + + var container = document.createElement('div') + var localeData = {} + var html = + '
' + '
' + '
' + '

' + @@ -34,13 +32,33 @@ describe('An accordion component', function () { '

' + '
' + beforeEach(function () { + container.innerHTML = html document.body.appendChild(container) + + // This gunky eslint disable is to account for ruby's rules on object (hash) attribute keys + /* eslint-disable dot-notation */ + localeData['show_text'] = 'st' + localeData['hide_text'] = 'ht' + localeData['show_all_text'] = 'sa' + localeData['hide_all_text'] = 'ha' + localeData['this_section_visually_hidden'] = 'vh' + /* eslint-enable dot-notation */ + + // Because we're passing stringified JSON data, we have to pass this separately so that innerHTML doesn't strip anything and break these tests unexpectedly + container.querySelector('.gem-c-accordion').setAttribute('data-locale', JSON.stringify(localeData)) + element = document.getElementById('default-id') new GOVUK.Modules.GemAccordion().start($(element)) }) afterEach(function () { + $(document).off() + window.sessionStorage.clear() document.body.removeChild(container) + + // This is to account for the anchor link test persisting the page hash after clicking the link + window.location.hash = '' }) describe('on page load', function () { @@ -85,7 +103,7 @@ describe('An accordion component', function () { topLevelControl.click() expect(topLevelControl.innerText).toEqual('Hide all sections') - element.querySelectorAll('.gem-c-accordion__section').forEach(function (section, i) { + element.querySelectorAll('.gem-c-accordion__section').forEach(function (section) { expect(section).toHaveClass('gem-c-accordion__section--expanded') expect(section.querySelector('.gem-c-accordion__toggle-text').innerText).toEqual('Hide') }) @@ -93,7 +111,7 @@ describe('An accordion component', function () { topLevelControl.click() expect(topLevelControl.innerText).toEqual('Show all sections') - element.querySelectorAll('.gem-c-accordion__section').forEach(function (section, i) { + element.querySelectorAll('.gem-c-accordion__section').forEach(function (section) { expect(section).not.toHaveClass('gem-c-accordion__section--expanded') expect(section.querySelector('.gem-c-accordion__toggle-text').innerText).toEqual('Show') }) @@ -110,4 +128,35 @@ describe('An accordion component', function () { expect(element.querySelectorAll('.gem-c-accordion__section')[1]).toHaveClass('gem-c-accordion__section--expanded') }) }) + + describe('when translation is applied to accordion', function () { + // These tests rely on the locale value passed in the markup snapshot above in the form of the following JSON object: + // { + // show_text: 'st', + // hide_text: 'ht', + // show_all_text: 'sa', + // hide_all_text: 'ha', + // this_section_visually_hidden: 'vh' + // } + it('sets lang attributes if locale attribute is present', function () { + expect(element.querySelector('.gem-c-accordion__open-all-text').lang).toEqual('sa') + + element.querySelectorAll('.gem-c-accordion__section-button').forEach(function (control) { + expect(control.querySelector('.gem-c-accordion__toggle-text').lang).toEqual('st') + expect(control.querySelectorAll('.govuk-visually-hidden')[1].lang).toEqual('vh') + }) + }) + + it('resets lang attributes upon button click if the locales for hide text is different', function () { + var topLevelControlText = element.querySelector('.gem-c-accordion__open-all-text') + + topLevelControlText.click() + + expect(topLevelControlText.lang).toEqual('ha') + + element.querySelectorAll('.gem-c-accordion__section-button').forEach(function (control) { + expect(control.querySelector('.gem-c-accordion__toggle-text').lang).toEqual('ht') + }) + }) + }) })