From 365fa91311271a86945806607574dc6ebb3996ee Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 28 Jun 2020 00:05:58 +0200 Subject: [PATCH] Add support for referencing FAQs via a has in the URL The specified FAQ entry will be expanded and the window scrolls to it automatically. Add an anchor icon on the right side of the FAQ and tutorial tiles to copy the URL directly. --- FAQ/index.html | 2 ++ _includes/faq_list.html | 17 +++++-------- _layouts/faq_list.html | 2 ++ css/faq.css | 20 ++++++++++++--- js/faq.js | 56 +++++++++++++++++++++++++++++++++++++++++ lunrjs/faq_search.js | 22 +++++++++------- 6 files changed, 96 insertions(+), 23 deletions(-) create mode 100644 js/faq.js diff --git a/FAQ/index.html b/FAQ/index.html index f9fc49cb..49b665d6 100644 --- a/FAQ/index.html +++ b/FAQ/index.html @@ -3,6 +3,8 @@ extraCSS: - "faq.css" - "faq_home.css" +extraJS: + - "faq.js" bodyID: faq bodyPage: "False" navBrandLink: "FAQ/" diff --git a/_includes/faq_list.html b/_includes/faq_list.html index 6b103859..70890acd 100644 --- a/_includes/faq_list.html +++ b/_includes/faq_list.html @@ -2,7 +2,7 @@ {%- if include.categories -%} {%- assign categories = include.categories -%} {%- else -%} - {%- assign categories = "download, player, bugs" | split: ", " -%} + {%- assign categories = "download, player, bugs, install" | split: ", " -%} {%- endif -%} {% comment %}DEFAULT VALUES WHEN NO TYPE/COLLECTION WAS PASSED{% endcomment %} @@ -54,13 +54,14 @@

{{ include.name }}

{%- if item.type == "tutorial" %} {%- endif %} -
+
- + - {{ item.title }} +
{{ item.title }}
+
{%- if item.type != "tutorial" -%}
@@ -79,11 +80,5 @@

{{ include.name }}

diff --git a/_layouts/faq_list.html b/_layouts/faq_list.html index a70cead0..0df5b01a 100644 --- a/_layouts/faq_list.html +++ b/_layouts/faq_list.html @@ -2,6 +2,8 @@ layout: default extraCSS: - "faq.css" +extraJS: + - "faq.js" bodyID: faq bodyPage: "False" navBrandLink: "FAQ/" diff --git a/css/faq.css b/css/faq.css index 467bf6fd..b07535b5 100644 --- a/css/faq.css +++ b/css/faq.css @@ -102,7 +102,7 @@ h3 > a > i.fa-chevron-left { text-align: left; color: #CD201F; font-size: 16px; - padding: 0 15px 0 0; + padding: 0; cursor: pointer; display: flex; font-weight: bold; @@ -113,7 +113,8 @@ h3 > a > i.fa-chevron-left { background: #d0cdcd; } -.tiles-container.faq-tiles .tile > .tile-head > span { +.tiles-container.faq-tiles .tile > .tile-head > .tile-type, +.tiles-container.faq-tiles .tile > .tile-head > span:first-child { padding: 7px 15px; margin-right: 15px; border-right: 1px solid #BBB; @@ -121,10 +122,23 @@ h3 > a > i.fa-chevron-left { align-items: center; } -.tiles-container.faq-tiles .tile > .tile-head > span.tutorial { +.tiles-container.faq-tiles .tile > .tile-head > .tile-type.tutorial { padding: 7px 12px 7px 11px; } +.tiles-container.faq-tiles .tile > .tile-head > .tile-title { + flex-grow: 1; +} + +.tiles-container.faq-tiles .tile > .tile-head > .tile-anchor { + padding-left: 15px; + padding-right: 15px; + margin-left: 15px; + border-left: 1px solid #BBB; + display: flex; + align-items: center; +} + .tiles-container.faq-tiles .tile > .tile-head > strong { padding: 7px 15px; width: calc(100% - 45px); diff --git a/js/faq.js b/js/faq.js new file mode 100644 index 00000000..b111ce5a --- /dev/null +++ b/js/faq.js @@ -0,0 +1,56 @@ +document.addEventListener('DOMContentLoaded', function() { + // show and jump to FAQ list elements which are referenced by the URL anchor + let url = window.location.href; + + if (url.includes('FAQ/#') || url.includes('FAQ#')) { + // we are on the FAQ main page and a FAQ should be opened + // first, display the FAQ to ensure it is there + let itemId = window.location.hash.substr(1); + showOne(itemId); + } + + if (url.includes('#') && !url.includes('FAQ/tutorials/')) { + // some other FAQ page with FAQ list elements + let itemId = window.location.hash.substr(1); + let listElement = document.getElementById(itemId); + if (listElement != null) { + // un-collapse element without animation + listElement.getElementsByClassName('tile-head')[0].classList.add('active'); + listElement.getElementsByClassName('tile-body')[0].style.display = 'block'; + + // scroll to element without having the navbar hiding it + let navbarHeight = document.getElementById("header").offsetHeight; + let elementPos = listElement.offsetTop; + let scrollPos = elementPos - navbarHeight; + // window.scrollTo(0, scrollPos); does not work for whatsoever reason.... using JQuery instead + $('html, body').animate({scrollTop: scrollPos}, 1); + } + } +}); + +function clickListener() { + $(".faq-tiles .tile > .tile-head > :not(.tile-anchor)").click(function () { + let $tile = $(this).closest('.tile'); + $tile.hasClass("active") ? $tile.find(".tile-body").slideUp() : $tile.find(".tile-body").slideDown(); + $tile.toggleClass("active"); + }); + $(".faq-tiles .tile > .tile-head > .tile-anchor").click(function (event) { + onTilesAnchorClick(event, $(this)); + }); +} + +function onTilesAnchorClick(event, tile) { + // prevent event / location change in case a tutorial was clicked + event.preventDefault(); + + // change URL in browser address abr + let anchor = tile.closest('.tile').prop('id'); + let url = window.location.href.split('#')[0] + '#' + anchor; + history.pushState({}, '', url); + + // copy the new url to the clipboard + // this is hackish, because we do not use the external (but always recommended) clipboard.js API to keep the site small + let tempSelect = $('').val(url).appendTo('body').select(); + document.execCommand('copy'); + tempSelect.remove(); +} diff --git a/lunrjs/faq_search.js b/lunrjs/faq_search.js index aa30a8eb..ba4e7f6e 100644 --- a/lunrjs/faq_search.js +++ b/lunrjs/faq_search.js @@ -4,6 +4,7 @@ window.store = { {%- assign faqs = site.faq | concat: site.tutorials %} {% for item in faqs %} "{{ item.title | slugify }}": { + "id": "{{ item.relative_path | split: "/" | last | replace: ".html", "" }}", "title": "{{ item.title | xml_escape }}", "url": "{{ item.url | xml_escape }}", "content": {{ item.content | strip_newlines | jsonify}}, @@ -67,20 +68,13 @@ function displaySearchResults(results) { clickListener(); } -function clickListener() { - $(".faq-tiles .tile > .tile-head").click(function () { - $(this).parent().hasClass("active") ? $(this).parent().find(".tile-body").slideUp() : $(this).parent().find(".tile-body").slideDown(); - $(this).parent().toggleClass("active"); - }); -} - function renderItem(item) { let ret = ""; if (item.type === 'tutorial') ret += '
'; ret += '
\n' + '
\n' - + '' + + '' + '' - + item.title + + '
' + item.title + '
' + + '' + '
'; if (item.type !== 'tutorial') ret += '
' + item.content + '
'; ret += '
'; @@ -111,6 +106,15 @@ function showAll() { clickListener(); } +function showOne(itemId) { + for (let key in window.store) { + if (window.store[key].id === itemId) { + displaySearchResults([{ref: key}]); + return; + } + } +} + $("#search-box").keydown(function (e) { if (e.which === 13 || e.keyCode === 13) { // Enter search();