-
-
-
+
-
+
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.