diff --git a/_includes/2017/pages-list-item.html b/_includes/2017/pages-list-item.html index f3dc49723..917936c4d 100644 --- a/_includes/2017/pages-list-item.html +++ b/_includes/2017/pages-list-item.html @@ -1,4 +1,6 @@ - + {{ include.page.url | remove: '.html' | remove: '/' }} {% if include.page.layout == '2017/sheet' %} diff --git a/_layouts/2017/home.html b/_layouts/2017/home.html index f69cb4308..239154e8e 100644 --- a/_layouts/2017/home.html +++ b/_layouts/2017/home.html @@ -6,12 +6,12 @@ type: website {% include 2017/top-nav.html page=page %}
- +
-

+

Top cheatsheets

@@ -22,7 +22,7 @@ type: website {% endfor %} {% for category in site.category_names %} -

+

{{ category }}

diff --git a/_sass/2017/base/base.scss b/_sass/2017/base/base.scss index ab7104bdb..5a4bb6cb8 100644 --- a/_sass/2017/base/base.scss +++ b/_sass/2017/base/base.scss @@ -53,3 +53,7 @@ a:visited { a:hover { color: $base-b3; } + +[aria-hidden] { + display: none !important; +} diff --git a/assets/2017/script.js b/assets/2017/script.js index cca5c3ca7..4b0ad6796 100644 --- a/assets/2017/script.js +++ b/assets/2017/script.js @@ -1,3 +1,7 @@ +/* + * Wrapping + */ + $(function () { const $root = $('[data-js-main-body]') wrapify($root) @@ -16,6 +20,116 @@ $(function () { }) }) +/* + * Search + */ + +$(function () { + $('[data-js-searchable-item]').each(function () { + const $this = $(this) + const data = $this.data('js-searchable-item') + const words = permutate(data) + + $this.attr('data-search-index', words.join(' ')) + }) + + // Propagate item search indices to headers + $('[data-js-searchable-header]').each(function () { + const $this = $(this) + const $els = $this + .nextUntil('[data-js-searchable-header]') + .filter('[data-search-index]') + + const keywords = $els + .map(function () { return $(this).attr('data-search-index') }) + .get() + .join(' ') + .split(' ') + + $this.attr('data-search-index', keywords.join(' ')) + }) +}) + +$(function () { + $('[data-js-search-input]').each(function () { + const $this = $(this) + const val = $this.val() + + $this.on('input', () => { + const val = $this.val() + + if (val === '') { + Search.showAll() + } else { + Search.show(val) + } + }) + }) + + $('[data-js-search-form]').each(function () { + const $this = $(this) + + $this.on('submit', e => { + e.preventDefault() + const href = $('a[data-search-index]:visible').eq(0).attr('href') + if (href) window.location = href + }) + }) +}) + +/* + * Search + */ + +const Search = { + showAll () { + $('[data-search-index]').removeAttr('aria-hidden') + }, + + show (val) { + const keywords = val.split(' ') + const selectors = keywords + .map(k => `[data-search-index~=${JSON.stringify(k)}]`) + .join('') + + $('[data-search-index]').attr('aria-hidden', true) + $(selectors).removeAttr('aria-hidden') + } +} + +/* + * Permutator + */ + +function permutate (data) { + let words = [] + if (data.slug) { + words = words.concat(permutateString(data.slug)) + } + if (data.category) { + words = words.concat(permutateString(data.category)) + } + return words +} + +function permutateString (str) { + let words = [] + let inputs = str.toLowerCase().split(/[ \-_]/) + inputs.forEach(word => { + words = words.concat(permutateWord(word)) + }) + return words +} + +function permutateWord (str) { + let words = [] + const len = str.length + for (var i = 1; i <= len; ++i) { + words.push(str.substr(0, i)) + } + return words +} + /* * Wraps h2 sections into h2-section. * Wraps h3 sections into h3-section.