From d766f663dd51c0af20c249eede1f7c262ffee5b0 Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Thu, 31 May 2018 17:05:07 +0200 Subject: [PATCH 01/36] GTD-14: A WIP proof of concept for the multipage navigation --- lib/assets/stylesheets/modules/_toc.scss | 7 +++++++ lib/source/layouts/layout.erb | 5 +---- lib/source/layouts/sidebar.erb | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 lib/source/layouts/sidebar.erb diff --git a/lib/assets/stylesheets/modules/_toc.scss b/lib/assets/stylesheets/modules/_toc.scss index be21991e..60b01f0b 100644 --- a/lib/assets/stylesheets/modules/_toc.scss +++ b/lib/assets/stylesheets/modules/_toc.scss @@ -40,6 +40,13 @@ } } + // Current page + .active > a:link { + color: $link-active-colour; + border-left-color: $link-active-colour; + background-color: $grey-4; + } + // Top level > ul > li > a:link { @include bold-19; diff --git a/lib/source/layouts/layout.erb b/lib/source/layouts/layout.erb index edece68b..7203b2f7 100644 --- a/lib/source/layouts/layout.erb +++ b/lib/source/layouts/layout.erb @@ -5,10 +5,7 @@ wrap_layout :core do content_for(:toc_module, "in-page-navigation") content_for :sidebar do - table_of_contents( - html, - max_level: config[:tech_docs][:max_toc_heading_level] - ) + partial "layouts/sidebar" end html diff --git a/lib/source/layouts/sidebar.erb b/lib/source/layouts/sidebar.erb new file mode 100644 index 00000000..e1eed35b --- /dev/null +++ b/lib/source/layouts/sidebar.erb @@ -0,0 +1,16 @@ + From f7385b9374bf837fc3888354004a893a2b4d457c Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Mon, 4 Jun 2018 15:17:29 +0200 Subject: [PATCH 02/36] GTD-14: Print H1 tags from frontmatter --- lib/source/layouts/core.erb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/source/layouts/core.erb b/lib/source/layouts/core.erb index 6085c0e3..2cff16e4 100644 --- a/lib/source/layouts/core.erb +++ b/lib/source/layouts/core.erb @@ -53,6 +53,7 @@
+

<%= current_page.data.title %>

<%= yield %> <%= partial "layouts/page_review" %>
From aec7f33009fac873a168aea862cde2fd73c516dc Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Mon, 4 Jun 2018 22:53:07 +0100 Subject: [PATCH 03/36] GTD-14: Moved the h1s back into the markdown content They are required by table_of_contents and if you pass through content that's been through a layout you end up with infinite recursion. --- lib/source/layouts/core.erb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/source/layouts/core.erb b/lib/source/layouts/core.erb index 2cff16e4..6085c0e3 100644 --- a/lib/source/layouts/core.erb +++ b/lib/source/layouts/core.erb @@ -53,7 +53,6 @@
-

<%= current_page.data.title %>

<%= yield %> <%= partial "layouts/page_review" %>
From 48381dbce9813d639f37ff32362c00657afd2c5f Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Mon, 4 Jun 2018 22:55:08 +0100 Subject: [PATCH 04/36] GTD-14: Modfied the table of contents generator so it prepends the page url before the fragment id --- lib/govuk_tech_docs/table_of_contents/heading.rb | 9 +++++++-- .../table_of_contents/headings_builder.rb | 6 ++++-- lib/govuk_tech_docs/table_of_contents/helpers.rb | 5 +++-- lib/source/layouts/layout.erb | 15 ++++++++++++++- lib/source/layouts/sidebar.erb | 16 ---------------- 5 files changed, 28 insertions(+), 23 deletions(-) delete mode 100644 lib/source/layouts/sidebar.erb diff --git a/lib/govuk_tech_docs/table_of_contents/heading.rb b/lib/govuk_tech_docs/table_of_contents/heading.rb index 738eebd0..50a71e12 100644 --- a/lib/govuk_tech_docs/table_of_contents/heading.rb +++ b/lib/govuk_tech_docs/table_of_contents/heading.rb @@ -1,10 +1,11 @@ module GovukTechDocs module TableOfContents class Heading - def initialize(element_name:, text:, attributes:) + def initialize(element_name:, text:, attributes:, page_url:) @element_name = element_name @text = text @attributes = attributes + @page_url = page_url end def size @@ -12,7 +13,11 @@ def size end def href - '#' + @attributes['id'] + if @element_name == 'h1' + @page_url + else + @page_url + '#' + @attributes['id'] + end end def title diff --git a/lib/govuk_tech_docs/table_of_contents/headings_builder.rb b/lib/govuk_tech_docs/table_of_contents/headings_builder.rb index 65d9fce5..e0f737dc 100644 --- a/lib/govuk_tech_docs/table_of_contents/headings_builder.rb +++ b/lib/govuk_tech_docs/table_of_contents/headings_builder.rb @@ -1,8 +1,9 @@ module GovukTechDocs module TableOfContents class HeadingsBuilder - def initialize(html) + def initialize(html, url) @html = html + @url = url end def headings @@ -10,7 +11,8 @@ def headings Heading.new( element_name: element.node_name, text: element.content, - attributes: convert_nokogiri_attr_objects_to_hashes(element.attributes) + attributes: convert_nokogiri_attr_objects_to_hashes(element.attributes), + page_url: @url ) end end diff --git a/lib/govuk_tech_docs/table_of_contents/helpers.rb b/lib/govuk_tech_docs/table_of_contents/helpers.rb index 281d104c..1b158239 100644 --- a/lib/govuk_tech_docs/table_of_contents/helpers.rb +++ b/lib/govuk_tech_docs/table_of_contents/helpers.rb @@ -7,8 +7,9 @@ module GovukTechDocs module TableOfContents module Helpers - def table_of_contents(html, max_level: nil) - headings = HeadingsBuilder.new(html).headings + def table_of_contents(html, url: '', max_level: nil) + print url + html + headings = HeadingsBuilder.new(html, url).headings if headings.none? { |heading| heading.size == 1 } raise "No H1 tag found. You have to at least add one H1 heading to the page." diff --git a/lib/source/layouts/layout.erb b/lib/source/layouts/layout.erb index 7203b2f7..809c3862 100644 --- a/lib/source/layouts/layout.erb +++ b/lib/source/layouts/layout.erb @@ -5,7 +5,20 @@ wrap_layout :core do content_for(:toc_module, "in-page-navigation") content_for :sidebar do - partial "layouts/sidebar" + %> + <% sitemap.resources.each do |resource| %> + <%if resource.path.end_with?('.html') && resource.data.title %> + <% content = resource.render({layout: false}) %> + <%= + table_of_contents( + content, + url: resource.url, + max_level: config[:tech_docs][:max_toc_heading_level] + ) %> + <% end %> + <% end %> + + <% end html diff --git a/lib/source/layouts/sidebar.erb b/lib/source/layouts/sidebar.erb deleted file mode 100644 index e1eed35b..00000000 --- a/lib/source/layouts/sidebar.erb +++ /dev/null @@ -1,16 +0,0 @@ -
    - <% sitemap.resources.each do |resource| %> - <%if resource.path.end_with?('.html') && resource.data.title %> - class="active"<% end %>> - <%= link_to(resource.data.title, resource.path) %> - <%= if active_page(resource.url) - content = resource.render({layout: false}) - table_of_contents( - content, - max_level: config[:tech_docs][:max_toc_heading_level] - ) - end %> - - <% end %> - <% end %> -
From 8cd8ffea72c286a951c1664e6b376b5c3caad513 Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 5 Jun 2018 11:06:23 +0100 Subject: [PATCH 05/36] GTD-14: Keep the fragment for H1 links because this still needs to work for single pages --- lib/govuk_tech_docs/table_of_contents/heading.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/govuk_tech_docs/table_of_contents/heading.rb b/lib/govuk_tech_docs/table_of_contents/heading.rb index 50a71e12..884c2cc1 100644 --- a/lib/govuk_tech_docs/table_of_contents/heading.rb +++ b/lib/govuk_tech_docs/table_of_contents/heading.rb @@ -13,11 +13,7 @@ def size end def href - if @element_name == 'h1' - @page_url - else - @page_url + '#' + @attributes['id'] - end + @page_url + '#' + @attributes['id'] end def title From 4bbcd3c67a9a3a9e753179d6006a08de29014ddf Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 5 Jun 2018 11:39:44 +0100 Subject: [PATCH 06/36] GTD-14: Implemention of weight frontmatter to sort navigation items --- lib/source/layouts/layout.erb | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/source/layouts/layout.erb b/lib/source/layouts/layout.erb index 809c3862..f60208bb 100644 --- a/lib/source/layouts/layout.erb +++ b/lib/source/layouts/layout.erb @@ -6,16 +6,14 @@ wrap_layout :core do content_for :sidebar do %> - <% sitemap.resources.each do |resource| %> - <%if resource.path.end_with?('.html') && resource.data.title %> - <% content = resource.render({layout: false}) %> - <%= - table_of_contents( - content, - url: resource.url, - max_level: config[:tech_docs][:max_toc_heading_level] - ) %> - <% end %> + <% sitemap.resources.select{ |r| r.path.end_with?('.html')}.sort_by{ |r| r.data.weight }.each do |resource| %> + <% content = resource.render({layout: false}) %> + <%= + table_of_contents( + content, + url: resource.url, + max_level: config[:tech_docs][:max_toc_heading_level] + ) %> <% end %> <% From 2d62b65545ad9adde5a75450508dc368ecf1e6b5 Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 5 Jun 2018 11:47:18 +0100 Subject: [PATCH 07/36] GTD-14: Catch pages where weight frontmatter is not defined and sort them to the bottom of the navigation instead of crashing. --- lib/source/layouts/layout.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/source/layouts/layout.erb b/lib/source/layouts/layout.erb index f60208bb..5125b3e9 100644 --- a/lib/source/layouts/layout.erb +++ b/lib/source/layouts/layout.erb @@ -6,7 +6,7 @@ wrap_layout :core do content_for :sidebar do %> - <% sitemap.resources.select{ |r| r.path.end_with?('.html')}.sort_by{ |r| r.data.weight }.each do |resource| %> + <% sitemap.resources.select{ |r| r.path.end_with?('.html')}.sort_by{ |r| [r.data.weight ? 0 : 1,r.data.weight || 0] }.each do |resource| %> <% content = resource.render({layout: false}) %> <%= table_of_contents( From c15333ee1f5e9ba7c122c9464310eb171a890f5d Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 5 Jun 2018 12:31:01 +0100 Subject: [PATCH 08/36] GTD-14: Do not generate the current page content twice when parsing for heading structure, as it increments the heading ids, and causes a mismatch between the navigation and the page content --- lib/source/layouts/layout.erb | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/source/layouts/layout.erb b/lib/source/layouts/layout.erb index 5125b3e9..00c49d77 100644 --- a/lib/source/layouts/layout.erb +++ b/lib/source/layouts/layout.erb @@ -5,9 +5,17 @@ wrap_layout :core do content_for(:toc_module, "in-page-navigation") content_for :sidebar do - %> - <% sitemap.resources.select{ |r| r.path.end_with?('.html')}.sort_by{ |r| [r.data.weight ? 0 : 1,r.data.weight || 0] }.each do |resource| %> - <% content = resource.render({layout: false}) %> + + sitemap.resources.select{ |r| r.path.end_with?('.html')}.sort_by{ |r| [r.data.weight ? 0 : 1,r.data.weight || 0] }.each do |resource| + + # Reuse the generated content for the active page + # If we generate it twice it increments the heading ids + if active_page(resource.url) + content = html + else + content = resource.render({layout: false}) + end + %> <%= table_of_contents( content, From 7f5a686d6cd58b9bf1c3a775f722f566e714dfa6 Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 5 Jun 2018 12:37:27 +0100 Subject: [PATCH 09/36] GTD-14: Update the in-view javascript code so it works with the new urls that include paths as well as fragment ids --- lib/assets/javascripts/_modules/in-page-navigation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/assets/javascripts/_modules/in-page-navigation.js b/lib/assets/javascripts/_modules/in-page-navigation.js index 2b2d80fa..d83b2f8b 100644 --- a/lib/assets/javascripts/_modules/in-page-navigation.js +++ b/lib/assets/javascripts/_modules/in-page-navigation.js @@ -70,7 +70,7 @@ } function highlightActiveItemInToc(fragment) { - var $activeTocItem = $tocItems.filter('[href="' + fragment + '"]'); + var $activeTocItem = $tocItems.filter('[href="' + window.location.pathname + fragment + '"]'); if ($activeTocItem.get(0)) { $tocItems.removeClass('toc-link--in-view'); From 415fab37bf73818ed04e5ccda81c4fcce743119d Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 5 Jun 2018 15:11:57 +0100 Subject: [PATCH 10/36] GTD-14: Proof of concept interaction for collapsible navigation --- .../javascripts/_modules/table-of-contents.js | 27 +++++++++++++++++-- lib/assets/stylesheets/_core.scss | 1 + .../stylesheets/modules/_collapsible.scss | 10 +++++++ lib/assets/stylesheets/modules/_toc.scss | 7 ----- .../table_of_contents/helpers.rb | 1 - 5 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 lib/assets/stylesheets/modules/_collapsible.scss diff --git a/lib/assets/javascripts/_modules/table-of-contents.js b/lib/assets/javascripts/_modules/table-of-contents.js index 4bad8e91..42220691 100644 --- a/lib/assets/javascripts/_modules/table-of-contents.js +++ b/lib/assets/javascripts/_modules/table-of-contents.js @@ -6,6 +6,7 @@ var $toc; var $tocList; + var $topLevelItems; var $openLink; var $closeLink; @@ -13,6 +14,7 @@ this.start = function ($element) { $toc = $element; $tocList = $toc.find('.js-toc-list'); + $topLevelItems = $tocList.find('> ul > li'); // Open link is not inside the module $openLink = $html.find('.js-toc-show'); @@ -21,6 +23,9 @@ fixRubberBandingInIOS(); updateAriaAttributes(); + // Attach collapsible heading functionality,on mobile and desktop + collapsibleHeadings($topLevelItems); + // Need delegated handler for show link as sticky polyfill recreates element $openLink.on('click.toc', preventingScrolling(openNavigation)); $closeLink.on('click.toc', preventingScrolling(closeNavigation)); @@ -39,12 +44,30 @@ }); }; + function collapsibleHeadings($elements) { + + var $headings = $elements.find('> a'); + var $listings = $elements.find('> ul'); + var $activeParent = $headings.filter('[href^="' + window.location.pathname + '"]').parent(); + + $elements.addClass('collapsible'); + $listings.addClass('collapsible__body'); + $headings.addClass('collapsible__heading').on('click', function(e) { + e.preventDefault(); + var $parent = $(this).parent(); + $parent.toggleClass('is-open'); + }); + + $activeParent.addClass('is-open'); + + } + function fixRubberBandingInIOS() { // By default when the table of contents is at the top or bottom, // scrolling in that direction will scroll the body 'behind' the table of // contents. Fix this by preventing ever reaching the top or bottom of the // table of contents (by 1 pixel). - // + // // http://blog.christoffer.me/six-things-i-learnt-about-ios-safaris-rubber-band-scrolling/ $toc.on("touchstart.toc", function () { var $this = $(this), @@ -62,7 +85,7 @@ function openNavigation() { $html.addClass('toc-open'); - + toggleBackgroundVisiblity(false); updateAriaAttributes(); diff --git a/lib/assets/stylesheets/_core.scss b/lib/assets/stylesheets/_core.scss index 7e96c279..a2a6117f 100644 --- a/lib/assets/stylesheets/_core.scss +++ b/lib/assets/stylesheets/_core.scss @@ -30,6 +30,7 @@ $desktop-breakpoint: 992px !default; @import "modules/contribution-banner"; @import "modules/technical-documentation"; @import "modules/toc"; +@import "modules/collapsible"; @import "accessibility"; diff --git a/lib/assets/stylesheets/modules/_collapsible.scss b/lib/assets/stylesheets/modules/_collapsible.scss new file mode 100644 index 00000000..00718af7 --- /dev/null +++ b/lib/assets/stylesheets/modules/_collapsible.scss @@ -0,0 +1,10 @@ +// Collapsible JS component styling, made for the navigation tree. +// These classes are added in table-of-contents.js. +// They should not be applied without the JS. + +.collapsible__body { + display: none; + .collapsible.is-open & { + display: block + } +} diff --git a/lib/assets/stylesheets/modules/_toc.scss b/lib/assets/stylesheets/modules/_toc.scss index 60b01f0b..be21991e 100644 --- a/lib/assets/stylesheets/modules/_toc.scss +++ b/lib/assets/stylesheets/modules/_toc.scss @@ -40,13 +40,6 @@ } } - // Current page - .active > a:link { - color: $link-active-colour; - border-left-color: $link-active-colour; - background-color: $grey-4; - } - // Top level > ul > li > a:link { @include bold-19; diff --git a/lib/govuk_tech_docs/table_of_contents/helpers.rb b/lib/govuk_tech_docs/table_of_contents/helpers.rb index 1b158239..c0ff1585 100644 --- a/lib/govuk_tech_docs/table_of_contents/helpers.rb +++ b/lib/govuk_tech_docs/table_of_contents/helpers.rb @@ -8,7 +8,6 @@ module GovukTechDocs module TableOfContents module Helpers def table_of_contents(html, url: '', max_level: nil) - print url + html headings = HeadingsBuilder.new(html, url).headings if headings.none? { |heading| heading.size == 1 } From f182c0c57b4b1c513a4c17cbc4abcf85f5b584b2 Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 5 Jun 2018 16:03:09 +0100 Subject: [PATCH 11/36] GTD-14: Search each top level nav item and children for an exact href match for the current browser location. This results in less false positives --- .../javascripts/_modules/table-of-contents.js | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/assets/javascripts/_modules/table-of-contents.js b/lib/assets/javascripts/_modules/table-of-contents.js index 42220691..4920a901 100644 --- a/lib/assets/javascripts/_modules/table-of-contents.js +++ b/lib/assets/javascripts/_modules/table-of-contents.js @@ -45,10 +45,8 @@ }; function collapsibleHeadings($elements) { - var $headings = $elements.find('> a'); var $listings = $elements.find('> ul'); - var $activeParent = $headings.filter('[href^="' + window.location.pathname + '"]').parent(); $elements.addClass('collapsible'); $listings.addClass('collapsible__body'); @@ -58,8 +56,34 @@ $parent.toggleClass('is-open'); }); - $activeParent.addClass('is-open'); + var $activeElement = findActiveElement(); + if($activeElement) { + $activeElement.addClass('is-open'); + } + + } + + function findActiveElement() { + var currentLocation = window.location.pathname + window.location.hash; + var $activeElement; + for (var i = $topLevelItems.length - 1; i >= 0; i--) { + var $element = $($topLevelItems[i]); + var $heading = $element.find('> a'); + // Check if this item href matches + if($heading.is('[href="' + currentLocation + '"]')) { + $activeElement = $element; + break; + } + // Otherwise check the children + var $children = $element.find('li > a'); + var $matchingChildren = $children.filter('[href="' + currentLocation + '"]'); + if ($matchingChildren.length) { + $activeElement = $element; + break; + } + } + return $activeElement; } function fixRubberBandingInIOS() { From 607c1e0d08283ea828e294b9c6662230d506645c Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Wed, 6 Jun 2018 14:14:20 +0100 Subject: [PATCH 12/36] GTD-14: Automatically open collapsed navigation sections if you scroll within them (for single page docs) --- .../javascripts/_modules/table-of-contents.js | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/lib/assets/javascripts/_modules/table-of-contents.js b/lib/assets/javascripts/_modules/table-of-contents.js index 4920a901..4fe56fcf 100644 --- a/lib/assets/javascripts/_modules/table-of-contents.js +++ b/lib/assets/javascripts/_modules/table-of-contents.js @@ -4,6 +4,7 @@ Modules.TableOfContents = function () { var $html = $('html'); + var $contentPane; var $toc; var $tocList; var $topLevelItems; @@ -15,6 +16,7 @@ $toc = $element; $tocList = $toc.find('.js-toc-list'); $topLevelItems = $tocList.find('> ul > li'); + $contentPane = $('.app-pane__content'); // Open link is not inside the module $openLink = $html.find('.js-toc-show'); @@ -24,7 +26,9 @@ updateAriaAttributes(); // Attach collapsible heading functionality,on mobile and desktop - collapsibleHeadings($topLevelItems); + collapsibleHeadings(); + openActiveHeading(); + $contentPane.on('scroll', _.debounce(openActiveHeading, 100, { maxWait: 100 })); // Need delegated handler for show link as sticky polyfill recreates element $openLink.on('click.toc', preventingScrolling(openNavigation)); @@ -44,26 +48,20 @@ }); }; - function collapsibleHeadings($elements) { - var $headings = $elements.find('> a'); - var $listings = $elements.find('> ul'); + function collapsibleHeadings() { + var $headings = $topLevelItems.find('> a'); + var $listings = $topLevelItems.find('> ul'); - $elements.addClass('collapsible'); + $topLevelItems.addClass('collapsible'); $listings.addClass('collapsible__body'); $headings.addClass('collapsible__heading').on('click', function(e) { e.preventDefault(); var $parent = $(this).parent(); $parent.toggleClass('is-open'); }); - - var $activeElement = findActiveElement(); - if($activeElement) { - $activeElement.addClass('is-open'); - } - } - function findActiveElement() { + function openActiveHeading() { var currentLocation = window.location.pathname + window.location.hash; var $activeElement; for (var i = $topLevelItems.length - 1; i >= 0; i--) { @@ -82,8 +80,9 @@ break; } } - - return $activeElement; + if($activeElement) { + $activeElement.addClass('is-open'); + } } function fixRubberBandingInIOS() { From 7418c347092984fd53f0fee827f91d311dd1e60f Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Wed, 6 Jun 2018 14:27:30 +0100 Subject: [PATCH 13/36] GTD-14: Add some basic affordances for open/closed navigation headings --- .../stylesheets/modules/_collapsible.scss | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/assets/stylesheets/modules/_collapsible.scss b/lib/assets/stylesheets/modules/_collapsible.scss index 00718af7..5a5c8e0f 100644 --- a/lib/assets/stylesheets/modules/_collapsible.scss +++ b/lib/assets/stylesheets/modules/_collapsible.scss @@ -8,3 +8,22 @@ display: block } } +.collapsible__heading { + position: relative; + &::after { + content: '+'; + display: block; + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 20px; + font-size: 34px; + line-height: 41px; + font-weight: normal; + } + .collapsible.is-open &::after { + content: '-'; + width: 16px; + } +} From d4b9dacee40ce8ef6181993b5e09290078befbee Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Thu, 7 Jun 2018 15:01:26 +0100 Subject: [PATCH 14/36] GTD-14: Only iterate through the top level pages in the navigation, for now --- lib/source/layouts/layout.erb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/source/layouts/layout.erb b/lib/source/layouts/layout.erb index 00c49d77..7f886de7 100644 --- a/lib/source/layouts/layout.erb +++ b/lib/source/layouts/layout.erb @@ -6,8 +6,16 @@ wrap_layout :core do content_for :sidebar do - sitemap.resources.select{ |r| r.path.end_with?('.html')}.sort_by{ |r| [r.data.weight ? 0 : 1,r.data.weight || 0] }.each do |resource| + # Only use html files + # Only use top level pages (index.html + it's children) + # Sorted by weight frontmatter + resources = sitemap.resources + .select { |r| + r.path.end_with?('.html') && ( r.parent.nil? || r.parent.path.include?('index.html') ) + } + .sort_by{ |r| [r.data.weight ? 0 : 1,r.data.weight || 0] } + resources.each do |resource| # Reuse the generated content for the active page # If we generate it twice it increments the heading ids if active_page(resource.url) @@ -17,6 +25,7 @@ wrap_layout :core do end %> <%= + # Parse the headings structure of every page table_of_contents( content, url: resource.url, From a1bb48aef1e0000814a6ee46225f6177e625f4dd Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 12 Jun 2018 15:26:23 +0100 Subject: [PATCH 15/36] GTD-3: Improve the accessibility of the collapsible TOC navigation Add dedicated ') + $topLevelItem.on('click', '.collapsible__toggle', function(e) { + e.preventDefault(); + var $parent = $(this).parent(); + toggleHeading($parent); + }); + } + } + + function toggleHeading($topLevelItem) { + var isOpen = $topLevelItem.hasClass('is-open'); + var $heading = $topLevelItem.find('> a'); + var $body = $topLevelItem.find('collapsible__body'); + var $toggleLabel = $topLevelItem.find('.collapsible__toggle-label'); + + $topLevelItem.toggleClass('is-open', !isOpen); + $body.attr('aria-expanded', isOpen ? 'true' : 'false'); + $toggle.text(isOpen ? 'Expand ' + $heading.text() : 'Collapse ' + $heading.text()); } function openActiveHeading() { @@ -80,8 +104,8 @@ break; } } - if($activeElement) { - $activeElement.addClass('is-open'); + if($activeElement && !$activeElement.hasClass('is-open')) { + toggleHeading($activeElement); } } diff --git a/lib/assets/stylesheets/modules/_collapsible.scss b/lib/assets/stylesheets/modules/_collapsible.scss index 5a5c8e0f..1eabdaa7 100644 --- a/lib/assets/stylesheets/modules/_collapsible.scss +++ b/lib/assets/stylesheets/modules/_collapsible.scss @@ -2,28 +2,43 @@ // These classes are added in table-of-contents.js. // They should not be applied without the JS. +.collapsible { + position: relative; +} .collapsible__body { display: none; .collapsible.is-open & { display: block } } -.collapsible__heading { - position: relative; +.collapsible__toggle { + position: absolute; + top: 0; + right: -30px; + width: 50px; + height: 40px; + overflow: hidden; + text-indent: -999em; + border: 0; + background: 0; + color: inherit; + padding: 0; +} +.collapsible__toggle-icon { + position: absolute; + top: 0; + right: 30px; &::after { + text-indent: 0; content: '+'; display: block; - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 20px; - font-size: 34px; + font-size: 30px; line-height: 41px; font-weight: normal; + text-align: center; } .collapsible.is-open &::after { content: '-'; - width: 16px; + padding-right: .1em; } } From f73c3b840e3a2fd43e8d52e899ddefb07e9c0c85 Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 12 Jun 2018 16:06:37 +0100 Subject: [PATCH 16/36] GTD-3: Add weight frontmatter documentation --- docs/frontmatter.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/frontmatter.md b/docs/frontmatter.md index 0fa4b144..72846f2a 100644 --- a/docs/frontmatter.md +++ b/docs/frontmatter.md @@ -110,6 +110,17 @@ title: My beautiful page --- ``` +## `weight` + +Affects the order a page is displayed in the sidebar navigation tree. Lower +weights float to the top. Higher weights sink to the bottom. + +```yaml +--- +weight: 20 +--- +``` + ## `parent` The page that should be highlighted as ‘active’ in the navigation. From 6af07c3619cf2ecaa4912b20a42b0de02ae1ff8b Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 12 Jun 2018 16:38:11 +0100 Subject: [PATCH 17/36] GTD-3: Avoid parsing the heading structure of redirect pages Also add the url to the error message to help locate the pages to fix --- lib/govuk_tech_docs/table_of_contents/helpers.rb | 2 +- lib/source/layouts/layout.erb | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/govuk_tech_docs/table_of_contents/helpers.rb b/lib/govuk_tech_docs/table_of_contents/helpers.rb index c0ff1585..1c0b3bf0 100644 --- a/lib/govuk_tech_docs/table_of_contents/helpers.rb +++ b/lib/govuk_tech_docs/table_of_contents/helpers.rb @@ -11,7 +11,7 @@ def table_of_contents(html, url: '', max_level: nil) headings = HeadingsBuilder.new(html, url).headings if headings.none? { |heading| heading.size == 1 } - raise "No H1 tag found. You have to at least add one H1 heading to the page." + raise "No H1 tag found. You have to at least add one H1 heading to the page: " + url end tree = HeadingTreeBuilder.new(headings).tree diff --git a/lib/source/layouts/layout.erb b/lib/source/layouts/layout.erb index 7f886de7..62c61532 100644 --- a/lib/source/layouts/layout.erb +++ b/lib/source/layouts/layout.erb @@ -11,7 +11,7 @@ wrap_layout :core do # Sorted by weight frontmatter resources = sitemap.resources .select { |r| - r.path.end_with?('.html') && ( r.parent.nil? || r.parent.path.include?('index.html') ) + r.path.end_with?(".html") && ( r.parent.nil? || r.parent.path.include?("index.html") ) } .sort_by{ |r| [r.data.weight ? 0 : 1,r.data.weight || 0] } @@ -23,9 +23,11 @@ wrap_layout :core do else content = resource.render({layout: false}) end + + # Avoid redirect pages + next if content.include? "http-equiv=refresh" %> <%= - # Parse the headings structure of every page table_of_contents( content, url: resource.url, From 7368edbc70aee1204cb6cec82a1cdb1b34bd5f5c Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 12 Jun 2018 16:50:56 +0100 Subject: [PATCH 18/36] GTD-3: Add focus styling to toc toggle button --- lib/assets/stylesheets/modules/_collapsible.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/assets/stylesheets/modules/_collapsible.scss b/lib/assets/stylesheets/modules/_collapsible.scss index 1eabdaa7..c0fb3047 100644 --- a/lib/assets/stylesheets/modules/_collapsible.scss +++ b/lib/assets/stylesheets/modules/_collapsible.scss @@ -23,6 +23,9 @@ background: 0; color: inherit; padding: 0; + &:focus { + outline: 3px solid $focus-colour; + } } .collapsible__toggle-icon { position: absolute; From dfb182831fba9d2093d10b4ff26a330faadc5dc2 Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 12 Jun 2018 17:48:19 +0100 Subject: [PATCH 19/36] GTD-3: Fixing tests Heading class no longer requires page_url but headings builder still does, all headings should have an associated url --- lib/govuk_tech_docs/table_of_contents/heading.rb | 2 +- spec/table_of_contents/headings_builder_spec.rb | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/govuk_tech_docs/table_of_contents/heading.rb b/lib/govuk_tech_docs/table_of_contents/heading.rb index 884c2cc1..3bd94198 100644 --- a/lib/govuk_tech_docs/table_of_contents/heading.rb +++ b/lib/govuk_tech_docs/table_of_contents/heading.rb @@ -1,7 +1,7 @@ module GovukTechDocs module TableOfContents class Heading - def initialize(element_name:, text:, attributes:, page_url:) + def initialize(element_name:, text:, attributes:, page_url: '') @element_name = element_name @text = text @attributes = attributes diff --git a/spec/table_of_contents/headings_builder_spec.rb b/spec/table_of_contents/headings_builder_spec.rb index d9c6c5b8..1c151346 100644 --- a/spec/table_of_contents/headings_builder_spec.rb +++ b/spec/table_of_contents/headings_builder_spec.rb @@ -9,8 +9,9 @@

Get some apples..

Pears

} + url = '' - headings = described_class.new(html).headings + headings = described_class.new(html, url).headings expect(headings).to eq([ GovukTechDocs::TableOfContents::Heading.new(element_name: 'h1', text: 'Apples', attributes: { 'id' => 'apples' }), From ebca17cfdf22c52cebb62c39c96391bf48722bde Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Thu, 14 Jun 2018 11:40:55 +0100 Subject: [PATCH 20/36] GTD-3 Moved multiple page tree navigation into a helper Also tidied up the doc a bit now that it's being linted --- .../table_of_contents/helpers.rb | 26 ++++++++++++++++++- lib/source/layouts/layout.erb | 22 ++-------------- spec/table_of_contents/helpers_spec.rb | 12 ++++----- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/lib/govuk_tech_docs/table_of_contents/helpers.rb b/lib/govuk_tech_docs/table_of_contents/helpers.rb index 1c0b3bf0..7d5039e8 100644 --- a/lib/govuk_tech_docs/table_of_contents/helpers.rb +++ b/lib/govuk_tech_docs/table_of_contents/helpers.rb @@ -7,7 +7,7 @@ module GovukTechDocs module TableOfContents module Helpers - def table_of_contents(html, url: '', max_level: nil) + def single_page_table_of_contents(html, url: '', max_level: nil) headings = HeadingsBuilder.new(html, url).headings if headings.none? { |heading| heading.size == 1 } @@ -17,6 +17,30 @@ def table_of_contents(html, url: '', max_level: nil) tree = HeadingTreeBuilder.new(headings).tree HeadingTreeRenderer.new(tree, max_level: max_level).html end + + def multi_page_table_of_contents(resources, active_page_html) + output = ''; + resources.each do |resource| + # Reuse the generated content for the active page + # If we generate it twice it increments the heading ids + content = + if active_page(resource.url) + active_page_html + else + resource.render(layout: false) + end + + # Avoid redirect pages + next if content.include? "http-equiv=refresh" + output << + single_page_table_of_contents( + content, + url: resource.url, + max_level: config[:tech_docs][:max_toc_heading_level] + ) + end + output + end end end end diff --git a/lib/source/layouts/layout.erb b/lib/source/layouts/layout.erb index 62c61532..3685a332 100644 --- a/lib/source/layouts/layout.erb +++ b/lib/source/layouts/layout.erb @@ -13,27 +13,9 @@ wrap_layout :core do .select { |r| r.path.end_with?(".html") && ( r.parent.nil? || r.parent.path.include?("index.html") ) } - .sort_by{ |r| [r.data.weight ? 0 : 1,r.data.weight || 0] } + .sort_by{ |r| [r.data.weight ? 0 : 1,r.data.weight || 0] } %> - resources.each do |resource| - # Reuse the generated content for the active page - # If we generate it twice it increments the heading ids - if active_page(resource.url) - content = html - else - content = resource.render({layout: false}) - end - - # Avoid redirect pages - next if content.include? "http-equiv=refresh" - %> - <%= - table_of_contents( - content, - url: resource.url, - max_level: config[:tech_docs][:max_toc_heading_level] - ) %> - <% end %> + <%= multi_page_table_of_contents(resources, html) %> <% end diff --git a/spec/table_of_contents/helpers_spec.rb b/spec/table_of_contents/helpers_spec.rb index ba4001ce..d6172b70 100644 --- a/spec/table_of_contents/helpers_spec.rb +++ b/spec/table_of_contents/helpers_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe GovukTechDocs::TableOfContents::Helpers do - describe '#table_of_contents' do + describe '#single_page_table_of_contents' do class Subject include GovukTechDocs::TableOfContents::Helpers end @@ -17,7 +17,7 @@ class Subject

Get some apples..

} - expected_table_of_contents = %{ + expected_single_page_table_of_contents = %{
  • Fruit @@ -33,7 +33,7 @@ class Subject
} - expect(subject.table_of_contents(html).strip).to eq(expected_table_of_contents.strip) + expect(subject.single_page_table_of_contents(html).strip).to eq(expected_single_page_table_of_contents.strip) end it 'builds a table of contents from html when headings suddenly change by more than one size' do @@ -46,7 +46,7 @@ class Subject

Bread

} - expected_table_of_contents = %{ + expected_single_page_table_of_contents = %{
  • Fruit @@ -71,7 +71,7 @@ class Subject
} - expect(subject.table_of_contents(html).strip).to eq(expected_table_of_contents.strip) + expect(subject.single_page_table_of_contents(html).strip).to eq(expected_single_page_table_of_contents.strip) end it 'builds a table of contents from HTML without an h1' do @@ -79,7 +79,7 @@ class Subject

Apples

} - expect { subject.table_of_contents(html).strip }.to raise_error(RuntimeError) + expect { subject.single_page_table_of_contents(html).strip }.to raise_error(RuntimeError) end end end From 8d725bd2515f2b3efc57de10150c470869dc6e61 Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Thu, 14 Jun 2018 16:02:21 +0100 Subject: [PATCH 21/36] GTD-3: Added a unit test for multiple page navigation I had to restructure the function a little to pass in Middleman globals --- .../table_of_contents/helpers.rb | 6 +- lib/source/layouts/layout.erb | 2 +- spec/table_of_contents/helpers_spec.rb | 75 +++++++++++++++++++ 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/lib/govuk_tech_docs/table_of_contents/helpers.rb b/lib/govuk_tech_docs/table_of_contents/helpers.rb index 7d5039e8..ade27b65 100644 --- a/lib/govuk_tech_docs/table_of_contents/helpers.rb +++ b/lib/govuk_tech_docs/table_of_contents/helpers.rb @@ -18,14 +18,14 @@ def single_page_table_of_contents(html, url: '', max_level: nil) HeadingTreeRenderer.new(tree, max_level: max_level).html end - def multi_page_table_of_contents(resources, active_page_html) + def multi_page_table_of_contents(resources, current_page, config, current_page_html = nil) output = ''; resources.each do |resource| # Reuse the generated content for the active page # If we generate it twice it increments the heading ids content = - if active_page(resource.url) - active_page_html + if current_page.url == resource.url && current_page_html + current_page_html else resource.render(layout: false) end diff --git a/lib/source/layouts/layout.erb b/lib/source/layouts/layout.erb index 3685a332..7bc49f2a 100644 --- a/lib/source/layouts/layout.erb +++ b/lib/source/layouts/layout.erb @@ -15,7 +15,7 @@ wrap_layout :core do } .sort_by{ |r| [r.data.weight ? 0 : 1,r.data.weight || 0] } %> - <%= multi_page_table_of_contents(resources, html) %> + <%= multi_page_table_of_contents(resources, current_page, config, html) %> <% end diff --git a/spec/table_of_contents/helpers_spec.rb b/spec/table_of_contents/helpers_spec.rb index d6172b70..4e75f1d1 100644 --- a/spec/table_of_contents/helpers_spec.rb +++ b/spec/table_of_contents/helpers_spec.rb @@ -82,4 +82,79 @@ class Subject expect { subject.single_page_table_of_contents(html).strip }.to raise_error(RuntimeError) end end + + describe '#multi_page_table_of_contents' do + class Subject + include GovukTechDocs::TableOfContents::Helpers + end + + class FakeResource + attr_reader :url + def initialize(url, html) + @url = url + @html = html + end + + def render(_layout) + @html + end + end + + subject { Subject.new } + + it 'builds a table of contents from several page resources' do + resources = [] + resources.push FakeResource.new('/index.html', '

Heading one

Heading two

'); + resources.push FakeResource.new('/a.html', '

Heading one

Heading two

'); + resources.push FakeResource.new('/b.html', '

Heading one

Heading two

'); + + current_page = double("current_page", + data: double("page_frontmatter", description: "The description.", title: "The Title"), + url: "/index.html", + metadata: { locals: {} }) + + current_page_html = '

Heading one

Heading two

'; + + config = { + tech_docs: { + max_toc_heading_level: 3 + } + } + + expected_multi_page_table_of_contents = %{ + + + + } + + expect(subject.multi_page_table_of_contents(resources, current_page, config, current_page_html).strip).to eq(expected_multi_page_table_of_contents.strip) + end + end end From 04610856ee4e68347286a0b4cb282c00e98f74fd Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Thu, 14 Jun 2018 16:08:05 +0100 Subject: [PATCH 22/36] GTD-3: Ensure multipage nav still supports single page sites --- spec/table_of_contents/helpers_spec.rb | 49 ++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/spec/table_of_contents/helpers_spec.rb b/spec/table_of_contents/helpers_spec.rb index 4e75f1d1..bcd2d063 100644 --- a/spec/table_of_contents/helpers_spec.rb +++ b/spec/table_of_contents/helpers_spec.rb @@ -156,5 +156,54 @@ def render(_layout) expect(subject.multi_page_table_of_contents(resources, current_page, config, current_page_html).strip).to eq(expected_multi_page_table_of_contents.strip) end + + it 'builds a table of contents from a single page resources' do + resources = [] + resources.push FakeResource.new('/index.html', '

Heading one

Heading two

Heading one

Heading two

Heading one

Heading two

'); + + current_page = double("current_page", + data: double("page_frontmatter", description: "The description.", title: "The Title"), + url: "/index.html", + metadata: { locals: {} }) + + current_page_html = '

Heading one

Heading two

Heading one

Heading two

Heading one

Heading two

'; + + config = { + tech_docs: { + max_toc_heading_level: 3 + } + } + + expected_multi_page_table_of_contents = %{ + + } + + expect(subject.multi_page_table_of_contents(resources, current_page, config, current_page_html).strip).to eq(expected_multi_page_table_of_contents.strip) + end end end From cc3d4a9f628a175d22a5e48cedcf5727bc05fc6e Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Thu, 14 Jun 2018 16:23:51 +0100 Subject: [PATCH 23/36] GTD-3: Added an integration test for multipage navigation Checks for links to other page headings on the home page navigation --- spec/features/integration_spec.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/features/integration_spec.rb b/spec/features/integration_spec.rb index f88b8872..3c30e34d 100644 --- a/spec/features/integration_spec.rb +++ b/spec/features/integration_spec.rb @@ -12,6 +12,7 @@ then_there_is_a_heading then_there_is_a_source_footer then_the_page_highlighted_in_the_navigation_is("Documentation") + then_there_are_navigation_headings_from_other_pages and_there_are_proper_meta_tags and_redirects_are_working @@ -57,6 +58,10 @@ def then_the_page_highlighted_in_the_navigation_is(link_label) expect(page.find('li.active a').text).to eq(link_label) end + def then_there_are_navigation_headings_from_other_pages + expect(page).to have_css '.toc__list a', text: 'A subheader' + end + def when_i_view_a_proxied_page visit '/a-proxied-page.html' end From 0c716e70559a37a61e45228eedddd0cf85c1ef8d Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Mon, 18 Jun 2018 10:22:45 +0100 Subject: [PATCH 24/36] GTD-3: Tweaked the alignment of the toggle icons --- lib/assets/stylesheets/modules/_collapsible.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/assets/stylesheets/modules/_collapsible.scss b/lib/assets/stylesheets/modules/_collapsible.scss index c0fb3047..4b6a1f54 100644 --- a/lib/assets/stylesheets/modules/_collapsible.scss +++ b/lib/assets/stylesheets/modules/_collapsible.scss @@ -36,7 +36,7 @@ content: '+'; display: block; font-size: 30px; - line-height: 41px; + line-height: 35px; font-weight: normal; text-align: center; } From 3ff59a229815a6667c7c35598357c28d9fe1f33c Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 19 Jun 2018 10:54:07 +0100 Subject: [PATCH 25/36] GTD-3: Replaced the +- text with arrow icons based on Stephen's feedback --- lib/assets/stylesheets/modules/_collapsible.scss | 14 ++++++-------- lib/source/images/arrow-down.svg | 9 +++++++++ lib/source/images/arrow-up.svg | 9 +++++++++ 3 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 lib/source/images/arrow-down.svg create mode 100644 lib/source/images/arrow-up.svg diff --git a/lib/assets/stylesheets/modules/_collapsible.scss b/lib/assets/stylesheets/modules/_collapsible.scss index 4b6a1f54..e5ec1a55 100644 --- a/lib/assets/stylesheets/modules/_collapsible.scss +++ b/lib/assets/stylesheets/modules/_collapsible.scss @@ -32,16 +32,14 @@ top: 0; right: 30px; &::after { - text-indent: 0; - content: '+'; + content: ''; display: block; - font-size: 30px; - line-height: 35px; - font-weight: normal; - text-align: center; + background: no-repeat file-url('arrow-down.svg') center center; + background-size: 18px auto; + width: 20px; + height: 40px; } .collapsible.is-open &::after { - content: '-'; - padding-right: .1em; + background-image: file-url('arrow-up.svg'); } } diff --git a/lib/source/images/arrow-down.svg b/lib/source/images/arrow-down.svg new file mode 100644 index 00000000..1f9e98f7 --- /dev/null +++ b/lib/source/images/arrow-down.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/lib/source/images/arrow-up.svg b/lib/source/images/arrow-up.svg new file mode 100644 index 00000000..dbf56a6a --- /dev/null +++ b/lib/source/images/arrow-up.svg @@ -0,0 +1,9 @@ + + + + + + From a9fc8506d0efc78f547702c69663f87f575f7df7 Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 19 Jun 2018 11:42:32 +0100 Subject: [PATCH 26/36] GTD-3: Fix broken text toggle for screen readers --- lib/assets/javascripts/_modules/table-of-contents.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/assets/javascripts/_modules/table-of-contents.js b/lib/assets/javascripts/_modules/table-of-contents.js index d5ebef12..d960bcaa 100644 --- a/lib/assets/javascripts/_modules/table-of-contents.js +++ b/lib/assets/javascripts/_modules/table-of-contents.js @@ -82,7 +82,7 @@ $topLevelItem.toggleClass('is-open', !isOpen); $body.attr('aria-expanded', isOpen ? 'true' : 'false'); - $toggle.text(isOpen ? 'Expand ' + $heading.text() : 'Collapse ' + $heading.text()); + $toggleLabel.text(isOpen ? 'Expand ' + $heading.text() : 'Collapse ' + $heading.text()); } function openActiveHeading() { From 7619da7ba2302956aa8583c0e295bd7acc5dbdb9 Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 19 Jun 2018 11:42:49 +0100 Subject: [PATCH 27/36] GTD-3: A few spacing tweaks for mobile devices --- lib/assets/stylesheets/modules/_collapsible.scss | 2 +- lib/assets/stylesheets/modules/_toc.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/assets/stylesheets/modules/_collapsible.scss b/lib/assets/stylesheets/modules/_collapsible.scss index e5ec1a55..64b89a54 100644 --- a/lib/assets/stylesheets/modules/_collapsible.scss +++ b/lib/assets/stylesheets/modules/_collapsible.scss @@ -14,7 +14,7 @@ .collapsible__toggle { position: absolute; top: 0; - right: -30px; + right: -25px; width: 50px; height: 40px; overflow: hidden; diff --git a/lib/assets/stylesheets/modules/_toc.scss b/lib/assets/stylesheets/modules/_toc.scss index be21991e..2b2275a1 100644 --- a/lib/assets/stylesheets/modules/_toc.scss +++ b/lib/assets/stylesheets/modules/_toc.scss @@ -27,7 +27,7 @@ a:link, a:visited { display: block; - padding: 8px $gutter-half; + padding: 8px $gutter 8px $gutter-half; margin: 0 $gutter-half * -1; border-left: 5px solid transparent; From b065dd44e49d1606e06387ec5a1bb8d677f23b0b Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Tue, 19 Jun 2018 12:28:53 +0100 Subject: [PATCH 28/36] GTD-3: Add multipage_nav option Setting this to true will add headings from other pages to the sidebar navigation This does not currently disable the collapsible javascript --- docs/configuration.md | 8 ++++++++ example/config/tech-docs.yml | 3 +++ lib/source/layouts/layout.erb | 26 +++++++++++++++----------- spec/table_of_contents/helpers_spec.rb | 5 +++-- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 2df215c6..9b43ad38 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -49,6 +49,14 @@ Example: host: https://docs.cloud.service.gov.uk ``` +## `multipage_nav` + +Enable multipage navigation in the sidebar. Defaults to false; + +```yaml +multipage_nav: true +``` + ## `max_toc_heading_level` Table of contents depth – how many levels to include in the table of contents. If your ToC is too long, reduce this number and we'll only show higher-level headings. diff --git a/example/config/tech-docs.yml b/example/config/tech-docs.yml index a827814d..0df498e1 100644 --- a/example/config/tech-docs.yml +++ b/example/config/tech-docs.yml @@ -17,6 +17,9 @@ header_links: # Tracking ID from Google Analytics (e.g. UA-XXXX-Y) ga_tracking_id: +# Enable multipage navigation in the sidebar +multipage_nav: true + # Table of contents depth – how many levels to include in the table of contents. # If your ToC is too long, reduce this number and we'll only show higher-level # headings. diff --git a/lib/source/layouts/layout.erb b/lib/source/layouts/layout.erb index 7bc49f2a..788af431 100644 --- a/lib/source/layouts/layout.erb +++ b/lib/source/layouts/layout.erb @@ -5,18 +5,22 @@ wrap_layout :core do content_for(:toc_module, "in-page-navigation") content_for :sidebar do + if config[:tech_docs][:multipage_nav] + # Multipage navigation + # Only parse html files + # Only parse top level pages (index.html + it's children) + # Sorted by weight frontmatter + resources = sitemap.resources + .select { |r| + r.path.end_with?(".html") && ( r.parent.nil? || r.parent.path.include?("index.html") ) + } + .sort_by{ |r| [r.data.weight ? 0 : 1,r.data.weight || 0] } %> - # Only use html files - # Only use top level pages (index.html + it's children) - # Sorted by weight frontmatter - resources = sitemap.resources - .select { |r| - r.path.end_with?(".html") && ( r.parent.nil? || r.parent.path.include?("index.html") ) - } - .sort_by{ |r| [r.data.weight ? 0 : 1,r.data.weight || 0] } %> - - <%= multi_page_table_of_contents(resources, current_page, config, html) %> - + <%= multi_page_table_of_contents(resources, current_page, config, html) %> + <% else %> + + <%= single_page_table_of_contents(html, max_level: config[:tech_docs][:max_toc_heading_level]) %> + <% end %> <% end diff --git a/spec/table_of_contents/helpers_spec.rb b/spec/table_of_contents/helpers_spec.rb index bcd2d063..f8cc2653 100644 --- a/spec/table_of_contents/helpers_spec.rb +++ b/spec/table_of_contents/helpers_spec.rb @@ -170,8 +170,9 @@ def render(_layout) config = { tech_docs: { - max_toc_heading_level: 3 - } + max_toc_heading_level: 3, + multipage_nav: true + }, } expected_multi_page_table_of_contents = %{ From 4507fdcf95efd5df0048b10462bb6109ce813421 Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Wed, 20 Jun 2018 14:01:09 +0100 Subject: [PATCH 29/36] GTD-3: Moved resource selection logic into helper a fixed tests. In preparation for adding support for child pages in multipage navigation --- .../table_of_contents/helpers.rb | 6 ++++ lib/source/layouts/layout.erb | 15 ++-------- spec/table_of_contents/helpers_spec.rb | 30 ++++++++++++++++--- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/lib/govuk_tech_docs/table_of_contents/helpers.rb b/lib/govuk_tech_docs/table_of_contents/helpers.rb index ade27b65..cf88d833 100644 --- a/lib/govuk_tech_docs/table_of_contents/helpers.rb +++ b/lib/govuk_tech_docs/table_of_contents/helpers.rb @@ -19,6 +19,12 @@ def single_page_table_of_contents(html, url: '', max_level: nil) end def multi_page_table_of_contents(resources, current_page, config, current_page_html = nil) + # Only parse top level html files + # Sorted by weight frontmatter + resources = resources + .select { |r| r.path.end_with?(".html") && (r.parent.nil? || r.parent.path.include?("index.html")) } + .sort_by { |r| [r.data.weight ? 0 : 1, r.data.weight || 0] } + output = ''; resources.each do |resource| # Reuse the generated content for the active page diff --git a/lib/source/layouts/layout.erb b/lib/source/layouts/layout.erb index 788af431..d70e3147 100644 --- a/lib/source/layouts/layout.erb +++ b/lib/source/layouts/layout.erb @@ -5,20 +5,9 @@ wrap_layout :core do content_for(:toc_module, "in-page-navigation") content_for :sidebar do - if config[:tech_docs][:multipage_nav] - # Multipage navigation - # Only parse html files - # Only parse top level pages (index.html + it's children) - # Sorted by weight frontmatter - resources = sitemap.resources - .select { |r| - r.path.end_with?(".html") && ( r.parent.nil? || r.parent.path.include?("index.html") ) - } - .sort_by{ |r| [r.data.weight ? 0 : 1,r.data.weight || 0] } %> - - <%= multi_page_table_of_contents(resources, current_page, config, html) %> + if config[:tech_docs][:multipage_nav] %> + <%= multi_page_table_of_contents(sitemap.resources, current_page, config, html) %> <% else %> - <%= single_page_table_of_contents(html, max_level: config[:tech_docs][:max_toc_heading_level]) %> <% end %> <% diff --git a/spec/table_of_contents/helpers_spec.rb b/spec/table_of_contents/helpers_spec.rb index f8cc2653..f092b137 100644 --- a/spec/table_of_contents/helpers_spec.rb +++ b/spec/table_of_contents/helpers_spec.rb @@ -88,25 +88,47 @@ class Subject include GovukTechDocs::TableOfContents::Helpers end + class FakeData + attr_reader :weight + def initialize(weight = nil) + @weight = weight + end + end + class FakeResource attr_reader :url - def initialize(url, html) + attr_reader :data + attr_reader :parent + attr_reader :children + def initialize(url, html, weight = nil, parent = nil, children = []) @url = url @html = html + @parent = parent + @children = children + @data = FakeData.new(weight) + end + + def path + @url end def render(_layout) @html end + + def add_children(children) + @children.concat children + end end subject { Subject.new } it 'builds a table of contents from several page resources' do resources = [] - resources.push FakeResource.new('/index.html', '

Heading one

Heading two

'); - resources.push FakeResource.new('/a.html', '

Heading one

Heading two

'); - resources.push FakeResource.new('/b.html', '

Heading one

Heading two

'); + resources[0] = FakeResource.new('/index.html', '

Heading one

Heading two

', 10); + resources[1] = FakeResource.new('/a.html', '

Heading one

Heading two

', 10, resources[0]); + resources[2] = FakeResource.new('/b.html', '

Heading one

Heading two

', 20, resources[0]); + resources[0].add_children [resources[1], resources[2]] current_page = double("current_page", data: double("page_frontmatter", description: "The description.", title: "The Title"), From 12186c3c84c954fc065bca1a1deb21647cfcd66f Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Wed, 20 Jun 2018 18:42:47 +0100 Subject: [PATCH 30/36] GTD-3: Added support for nested page structures --- lib/assets/stylesheets/modules/_toc.scss | 5 --- .../table_of_contents/helpers.rb | 34 ++++++++++++++----- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/lib/assets/stylesheets/modules/_toc.scss b/lib/assets/stylesheets/modules/_toc.scss index 2b2275a1..61a7287e 100644 --- a/lib/assets/stylesheets/modules/_toc.scss +++ b/lib/assets/stylesheets/modules/_toc.scss @@ -46,11 +46,6 @@ } @include media(tablet) { - // Level 2 - > ul > li > ul { - margin-bottom: 20px; - } - // Level 3 li li li { a:link, a:visited { diff --git a/lib/govuk_tech_docs/table_of_contents/helpers.rb b/lib/govuk_tech_docs/table_of_contents/helpers.rb index cf88d833..fe2f7597 100644 --- a/lib/govuk_tech_docs/table_of_contents/helpers.rb +++ b/lib/govuk_tech_docs/table_of_contents/helpers.rb @@ -22,9 +22,16 @@ def multi_page_table_of_contents(resources, current_page, config, current_page_h # Only parse top level html files # Sorted by weight frontmatter resources = resources - .select { |r| r.path.end_with?(".html") && (r.parent.nil? || r.parent.path.include?("index.html")) } + .select { |r| r.path.end_with?(".html") && (r.parent.nil? || r.parent.url == "/") } .sort_by { |r| [r.data.weight ? 0 : 1, r.data.weight || 0] } + render_page_tree(resources, current_page, config, current_page_html) + end + + def render_page_tree(resources, current_page, config, current_page_html) + # Sort by weight frontmatter + resources = resources + .sort_by { |r| [r.data.weight ? 0 : 1, r.data.weight || 0] } output = ''; resources.each do |resource| # Reuse the generated content for the active page @@ -35,15 +42,26 @@ def multi_page_table_of_contents(resources, current_page, config, current_page_h else resource.render(layout: false) end - # Avoid redirect pages next if content.include? "http-equiv=refresh" - output << - single_page_table_of_contents( - content, - url: resource.url, - max_level: config[:tech_docs][:max_toc_heading_level] - ) + + # If this page has children, just print the title and recursively + # render the children. + # If not, print the heading structure. + # We avoid printing the children of the root index.html as it is the + # parent of every other top level file. + if resource.children.any? && resource.url != "/" + output += %{
  • #{resource.data.title}\n} + output += render_page_tree(resource.children, current_page, config, current_page_html) + output += '
' + else + output += + single_page_table_of_contents( + content, + url: resource.url, + max_level: config[:tech_docs][:max_toc_heading_level] + ) + end end output end From 01b1780ccea891d8adbe730be745eed53b84908b Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Wed, 27 Jun 2018 09:28:56 +0100 Subject: [PATCH 31/36] GTD-3: Ensure navigation text and collapsible toggle doesn't overlap --- lib/assets/stylesheets/modules/_toc.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/assets/stylesheets/modules/_toc.scss b/lib/assets/stylesheets/modules/_toc.scss index 61a7287e..ad1de4da 100644 --- a/lib/assets/stylesheets/modules/_toc.scss +++ b/lib/assets/stylesheets/modules/_toc.scss @@ -27,7 +27,7 @@ a:link, a:visited { display: block; - padding: 8px $gutter 8px $gutter-half; + padding: 8px 40px 8px $gutter-half; margin: 0 $gutter-half * -1; border-left: 5px solid transparent; From 0f4b485e00884443de1e645148dd993e9b0256dd Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Wed, 27 Jun 2018 12:57:02 +0100 Subject: [PATCH 32/36] GTD-3: Automatically expand navigation items when on their child pages --- lib/assets/javascripts/_modules/table-of-contents.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/assets/javascripts/_modules/table-of-contents.js b/lib/assets/javascripts/_modules/table-of-contents.js index d960bcaa..36bc30dd 100644 --- a/lib/assets/javascripts/_modules/table-of-contents.js +++ b/lib/assets/javascripts/_modules/table-of-contents.js @@ -86,19 +86,19 @@ } function openActiveHeading() { - var currentLocation = window.location.pathname + window.location.hash; + var currentPath = window.location.pathname; var $activeElement; for (var i = $topLevelItems.length - 1; i >= 0; i--) { var $element = $($topLevelItems[i]); var $heading = $element.find('> a'); // Check if this item href matches - if($heading.is('[href="' + currentLocation + '"]')) { + if($heading.is('[href*="' + currentPath + '"]')) { $activeElement = $element; break; } // Otherwise check the children var $children = $element.find('li > a'); - var $matchingChildren = $children.filter('[href="' + currentLocation + '"]'); + var $matchingChildren = $children.filter('[href*="' + currentPath + '"]'); if ($matchingChildren.length) { $activeElement = $element; break; From ea7c538a2b4a5d68362918b1edb05ad80b2d0eb1 Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Wed, 27 Jun 2018 13:08:25 +0100 Subject: [PATCH 33/36] GTD-3: Added an exception root page fpr the active trail check for collapsible navigation All paths contain the path of the root page: / --- lib/assets/javascripts/_modules/table-of-contents.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/assets/javascripts/_modules/table-of-contents.js b/lib/assets/javascripts/_modules/table-of-contents.js index 36bc30dd..46e20cab 100644 --- a/lib/assets/javascripts/_modules/table-of-contents.js +++ b/lib/assets/javascripts/_modules/table-of-contents.js @@ -86,19 +86,24 @@ } function openActiveHeading() { - var currentPath = window.location.pathname; var $activeElement; + var currentPath = window.location.pathname; + var isActiveTrail = '[href*="' + currentPath + '"]'; + // Add an exception for the root page, as every href includes / + if(currentPath == '/') { + isActiveTrail = '[href="' + currentPath + window.location.hash + '"]' + } for (var i = $topLevelItems.length - 1; i >= 0; i--) { var $element = $($topLevelItems[i]); var $heading = $element.find('> a'); // Check if this item href matches - if($heading.is('[href*="' + currentPath + '"]')) { + if($heading.is(isActiveTrail)) { $activeElement = $element; break; } // Otherwise check the children var $children = $element.find('li > a'); - var $matchingChildren = $children.filter('[href*="' + currentPath + '"]'); + var $matchingChildren = $children.filter(isActiveTrail); if ($matchingChildren.length) { $activeElement = $element; break; From 13e55720f6e71ee78ba4304f7d54753d05ee91c8 Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Wed, 27 Jun 2018 13:21:18 +0100 Subject: [PATCH 34/36] GTD-3: Tweak the active navigation item code to support nested pages Navigation items of pages that have sub-pages do not print fragments in their href --- lib/assets/javascripts/_modules/in-page-navigation.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/assets/javascripts/_modules/in-page-navigation.js b/lib/assets/javascripts/_modules/in-page-navigation.js index d83b2f8b..eb498ad1 100644 --- a/lib/assets/javascripts/_modules/in-page-navigation.js +++ b/lib/assets/javascripts/_modules/in-page-navigation.js @@ -71,7 +71,11 @@ function highlightActiveItemInToc(fragment) { var $activeTocItem = $tocItems.filter('[href="' + window.location.pathname + fragment + '"]'); - + // Navigation items with children don't contain fragments in their url + // Check to see if any nav items contain just the path name. + if(!$activeTocItem.get(0)) { + $activeTocItem = $tocItems.filter('[href="' + window.location.pathname + '"]'); + } if ($activeTocItem.get(0)) { $tocItems.removeClass('toc-link--in-view'); $activeTocItem.addClass('toc-link--in-view'); From 9e99df69ae9c0780de35094273b6c91b44e8a132 Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Wed, 27 Jun 2018 13:48:37 +0100 Subject: [PATCH 35/36] GTD-3: Split collapsible navigation into a seperate javascript module and cofiguration option The javascript file is still included, but it is not used --- docs/configuration.md | 8 ++ example/config/tech-docs.yml | 3 + .../_modules/collapsible-navigation.js | 93 +++++++++++++++++++ .../javascripts/_modules/table-of-contents.js | 67 ------------- lib/assets/javascripts/_start-modules.js | 1 + lib/source/layouts/core.erb | 2 +- 6 files changed, 106 insertions(+), 68 deletions(-) create mode 100644 lib/assets/javascripts/_modules/collapsible-navigation.js diff --git a/docs/configuration.md b/docs/configuration.md index 9b43ad38..59421101 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -49,6 +49,14 @@ Example: host: https://docs.cloud.service.gov.uk ``` +## `collapsible_nav` + +Enable collapsible navigation in the sidebar. Defaults to false; + +```yaml +collapsible_nav: true +``` + ## `multipage_nav` Enable multipage navigation in the sidebar. Defaults to false; diff --git a/example/config/tech-docs.yml b/example/config/tech-docs.yml index 0df498e1..62ac6b56 100644 --- a/example/config/tech-docs.yml +++ b/example/config/tech-docs.yml @@ -20,6 +20,9 @@ ga_tracking_id: # Enable multipage navigation in the sidebar multipage_nav: true +# Enable collapsible navigation in the sidebar +collapsible_nav: true + # Table of contents depth – how many levels to include in the table of contents. # If your ToC is too long, reduce this number and we'll only show higher-level # headings. diff --git a/lib/assets/javascripts/_modules/collapsible-navigation.js b/lib/assets/javascripts/_modules/collapsible-navigation.js new file mode 100644 index 00000000..d15b3fde --- /dev/null +++ b/lib/assets/javascripts/_modules/collapsible-navigation.js @@ -0,0 +1,93 @@ +(function($, Modules) { + 'use strict'; + + Modules.CollapsibleNavigation = function () { + + var $contentPane; + var $nav; + var $topLevelItems; + var $headings; + var $listings; + + var $openLink; + var $closeLink; + + this.start = function ($element) { + $contentPane = $('.app-pane__content'); + $nav = $element; + $topLevelItems = $nav.find('> ul > li'); + $headings = $topLevelItems.find('> a'); + $listings = $topLevelItems.find('> ul'); + + // Attach collapsible heading functionality,on mobile and desktop + collapsibleHeadings(); + openActiveHeading(); + $contentPane.on('scroll', _.debounce(openActiveHeading, 100, { maxWait: 100 })); + + }; + + function collapsibleHeadings() { + for (var i = $topLevelItems.length - 1; i >= 0; i--) { + var $topLevelItem = $($topLevelItems[i]); + var $heading = $topLevelItem.find('> a'); + var $listing = $topLevelItem.find('> ul'); + // Only add collapsible functionality if there are children. + if ($listing.length == 0) { + continue; + } + $topLevelItem.addClass('collapsible'); + $listing.addClass('collapsible__body') + .attr('aria-expanded', 'false'); + $heading.addClass('collapsible__heading') + .after('') + $topLevelItem.on('click', '.collapsible__toggle', function(e) { + e.preventDefault(); + var $parent = $(this).parent(); + toggleHeading($parent); + }); + } + } + + function toggleHeading($topLevelItem) { + var isOpen = $topLevelItem.hasClass('is-open'); + var $heading = $topLevelItem.find('> a'); + var $body = $topLevelItem.find('collapsible__body'); + var $toggleLabel = $topLevelItem.find('.collapsible__toggle-label'); + + $topLevelItem.toggleClass('is-open', !isOpen); + $body.attr('aria-expanded', isOpen ? 'true' : 'false'); + $toggleLabel.text(isOpen ? 'Expand ' + $heading.text() : 'Collapse ' + $heading.text()); + } + + function openActiveHeading() { + var $activeElement; + var currentPath = window.location.pathname; + var isActiveTrail = '[href*="' + currentPath + '"]'; + // Add an exception for the root page, as every href includes / + if(currentPath == '/') { + isActiveTrail = '[href="' + currentPath + window.location.hash + '"]' + } + for (var i = $topLevelItems.length - 1; i >= 0; i--) { + var $element = $($topLevelItems[i]); + var $heading = $element.find('> a'); + // Check if this item href matches + if($heading.is(isActiveTrail)) { + $activeElement = $element; + break; + } + // Otherwise check the children + var $children = $element.find('li > a'); + var $matchingChildren = $children.filter(isActiveTrail); + if ($matchingChildren.length) { + $activeElement = $element; + break; + } + } + if($activeElement && !$activeElement.hasClass('is-open')) { + toggleHeading($activeElement); + } + } + + + }; +})(jQuery, window.GOVUK.Modules); diff --git a/lib/assets/javascripts/_modules/table-of-contents.js b/lib/assets/javascripts/_modules/table-of-contents.js index 46e20cab..c5d4da37 100644 --- a/lib/assets/javascripts/_modules/table-of-contents.js +++ b/lib/assets/javascripts/_modules/table-of-contents.js @@ -29,11 +29,6 @@ fixRubberBandingInIOS(); updateAriaAttributes(); - // Attach collapsible heading functionality,on mobile and desktop - collapsibleHeadings(); - openActiveHeading(); - $contentPane.on('scroll', _.debounce(openActiveHeading, 100, { maxWait: 100 })); - // Need delegated handler for show link as sticky polyfill recreates element $openLink.on('click.toc', preventingScrolling(openNavigation)); $closeLink.on('click.toc', preventingScrolling(closeNavigation)); @@ -52,68 +47,6 @@ }); }; - function collapsibleHeadings() { - for (var i = $topLevelItems.length - 1; i >= 0; i--) { - var $topLevelItem = $($topLevelItems[i]); - var $heading = $topLevelItem.find('> a'); - var $listing = $topLevelItem.find('> ul'); - // Only add collapsible functionality if there are children. - if ($listing.length == 0) { - continue; - } - $topLevelItem.addClass('collapsible'); - $listing.addClass('collapsible__body') - .attr('aria-expanded', 'false'); - $heading.addClass('collapsible__heading') - .after('') - $topLevelItem.on('click', '.collapsible__toggle', function(e) { - e.preventDefault(); - var $parent = $(this).parent(); - toggleHeading($parent); - }); - } - } - - function toggleHeading($topLevelItem) { - var isOpen = $topLevelItem.hasClass('is-open'); - var $heading = $topLevelItem.find('> a'); - var $body = $topLevelItem.find('collapsible__body'); - var $toggleLabel = $topLevelItem.find('.collapsible__toggle-label'); - - $topLevelItem.toggleClass('is-open', !isOpen); - $body.attr('aria-expanded', isOpen ? 'true' : 'false'); - $toggleLabel.text(isOpen ? 'Expand ' + $heading.text() : 'Collapse ' + $heading.text()); - } - - function openActiveHeading() { - var $activeElement; - var currentPath = window.location.pathname; - var isActiveTrail = '[href*="' + currentPath + '"]'; - // Add an exception for the root page, as every href includes / - if(currentPath == '/') { - isActiveTrail = '[href="' + currentPath + window.location.hash + '"]' - } - for (var i = $topLevelItems.length - 1; i >= 0; i--) { - var $element = $($topLevelItems[i]); - var $heading = $element.find('> a'); - // Check if this item href matches - if($heading.is(isActiveTrail)) { - $activeElement = $element; - break; - } - // Otherwise check the children - var $children = $element.find('li > a'); - var $matchingChildren = $children.filter(isActiveTrail); - if ($matchingChildren.length) { - $activeElement = $element; - break; - } - } - if($activeElement && !$activeElement.hasClass('is-open')) { - toggleHeading($activeElement); - } - } - function fixRubberBandingInIOS() { // By default when the table of contents is at the top or bottom, // scrolling in that direction will scroll the body 'behind' the table of diff --git a/lib/assets/javascripts/_start-modules.js b/lib/assets/javascripts/_start-modules.js index f87afaf4..77ce4a47 100644 --- a/lib/assets/javascripts/_start-modules.js +++ b/lib/assets/javascripts/_start-modules.js @@ -4,6 +4,7 @@ //= require _modules/navigation //= require _modules/page-expiry //= require _modules/table-of-contents +//= require _modules/collapsible-navigation $(document).ready(function() { GOVUK.modules.start(); diff --git a/lib/source/layouts/core.erb b/lib/source/layouts/core.erb index 6085c0e3..0783b30b 100644 --- a/lib/source/layouts/core.erb +++ b/lib/source/layouts/core.erb @@ -45,7 +45,7 @@
-
From e83ef00411038a69e5140c785a4a0034da9d791e Mon Sep 17 00:00:00 2001 From: lewisnyman Date: Thu, 28 Jun 2018 14:56:41 +0100 Subject: [PATCH 36/36] GTD-3: Cleaned up whitespace and updated tests to match nested page code Pages with children don't print the fragment id in href --- .../table_of_contents/helpers.rb | 5 ++-- spec/table_of_contents/helpers_spec.rb | 26 +++++++------------ 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/lib/govuk_tech_docs/table_of_contents/helpers.rb b/lib/govuk_tech_docs/table_of_contents/helpers.rb index fe2f7597..110d18e3 100644 --- a/lib/govuk_tech_docs/table_of_contents/helpers.rb +++ b/lib/govuk_tech_docs/table_of_contents/helpers.rb @@ -44,8 +44,7 @@ def render_page_tree(resources, current_page, config, current_page_html) end # Avoid redirect pages next if content.include? "http-equiv=refresh" - - # If this page has children, just print the title and recursively + # If this page has children, just print the title and recursively # render the children. # If not, print the heading structure. # We avoid printing the children of the root index.html as it is the @@ -61,7 +60,7 @@ def render_page_tree(resources, current_page, config, current_page_html) url: resource.url, max_level: config[:tech_docs][:max_toc_heading_level] ) - end + end end output end diff --git a/spec/table_of_contents/helpers_spec.rb b/spec/table_of_contents/helpers_spec.rb index f092b137..85975f72 100644 --- a/spec/table_of_contents/helpers_spec.rb +++ b/spec/table_of_contents/helpers_spec.rb @@ -90,8 +90,10 @@ class Subject class FakeData attr_reader :weight - def initialize(weight = nil) + attr_reader :title + def initialize(weight = nil, title = nil) @weight = weight + @title = title end end @@ -100,12 +102,12 @@ class FakeResource attr_reader :data attr_reader :parent attr_reader :children - def initialize(url, html, weight = nil, parent = nil, children = []) + def initialize(url, html, weight = nil, title = nil, parent = nil, children = []) @url = url @html = html @parent = parent @children = children - @data = FakeData.new(weight) + @data = FakeData.new(weight, title) end def path @@ -125,9 +127,9 @@ def add_children(children) it 'builds a table of contents from several page resources' do resources = [] - resources[0] = FakeResource.new('/index.html', '

Heading one

Heading two

', 10); - resources[1] = FakeResource.new('/a.html', '

Heading one

Heading two

', 10, resources[0]); - resources[2] = FakeResource.new('/b.html', '

Heading one

Heading two

', 20, resources[0]); + resources[0] = FakeResource.new('/index.html', '

Heading one

Heading two

', 10, 'Index'); + resources[1] = FakeResource.new('/a.html', '

Heading one

Heading two

', 10, 'Sub page A', resources[0]); + resources[2] = FakeResource.new('/b.html', '

Heading one

Heading two

', 20, 'Sub page B', resources[0]); resources[0].add_children [resources[1], resources[2]] current_page = double("current_page", @@ -144,16 +146,7 @@ def add_children(children) } expected_multi_page_table_of_contents = %{ - + + } expect(subject.multi_page_table_of_contents(resources, current_page, config, current_page_html).strip).to eq(expected_multi_page_table_of_contents.strip)