Refactor more behaviors
This commit is contained in:
parent
b837738adf
commit
ede8f1c999
|
@ -0,0 +1,21 @@
|
|||
import closest from 'dom101/closest'
|
||||
import remove from 'dom101/remove'
|
||||
import on from 'dom101/on'
|
||||
import { getData } from '../helpers/data'
|
||||
import onmount from 'onmount'
|
||||
|
||||
/**
|
||||
* Dismiss button
|
||||
*/
|
||||
|
||||
onmount('[data-js-dismiss]', function () {
|
||||
const parent = closest(this, '[data-js-dismissable]')
|
||||
const dismissable = getData(parent, 'js-dismissable')
|
||||
const id = dismissable && dismissable.id || ''
|
||||
|
||||
on(this, 'click', e => {
|
||||
Dismiss.setDismissed(id)
|
||||
e.preventDefault()
|
||||
if (parent) remove(parent)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,17 @@
|
|||
import onmount from 'onmount'
|
||||
import remove from 'dom101/remove'
|
||||
import removeClass from 'dom101/remove-class'
|
||||
|
||||
import { getData } from '../helpers/data'
|
||||
import { isDismissed } from '../helpers/dismiss'
|
||||
import { isPreview } from '../helpers/preview'
|
||||
|
||||
onmount('[data-js-dismissable]', function () {
|
||||
const id = getData(this, 'js-dismissable').id || ''
|
||||
|
||||
if (isPreview() || isDismissed(id)) {
|
||||
remove(this)
|
||||
} else {
|
||||
removeClass(this, '-hide')
|
||||
}
|
||||
})
|
|
@ -0,0 +1,17 @@
|
|||
import onmount from 'onmount'
|
||||
import injectDisqus from '../helpers/inject_disqus'
|
||||
|
||||
/**
|
||||
* Injects Disqus onto the page.
|
||||
*/
|
||||
|
||||
onmount('[data-js-disqus]', function () {
|
||||
const data = JSON.parse(this.getAttribute('data-js-disqus'))
|
||||
|
||||
window.disqus_config = function () {
|
||||
this.page.url = data.url
|
||||
this.page.identifier = data.identifier
|
||||
}
|
||||
|
||||
injectDisqus(data.host)
|
||||
})
|
|
@ -3,12 +3,14 @@ import ready from 'dom101/ready'
|
|||
import remove from 'dom101/remove'
|
||||
import onmount from 'onmount'
|
||||
|
||||
import { isPreview } from '../helpers/preview'
|
||||
|
||||
/*
|
||||
* Behavior: Things to remove when preview mode is on
|
||||
*/
|
||||
|
||||
onmount('[data-js-no-preview]', function (b) {
|
||||
if (~window.location.search.indexOf('preview=1')) {
|
||||
if (isPreview()) {
|
||||
remove(this)
|
||||
}
|
||||
})
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
import $ from 'jquery'
|
||||
import onmount from 'onmount'
|
||||
import permutate from '../helpers/permutate'
|
||||
|
||||
onmount('[data-js-searchable-item]', function () {
|
||||
const $this = $(this)
|
||||
const data = $this.data('js-searchable-item')
|
||||
const words = permutate(data)
|
||||
|
||||
$this.attr('data-search-index', words.join(' '))
|
||||
})
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* Stores and retrieves data from an element. Works like jQuery.data().
|
||||
*/
|
||||
|
||||
export function data (el, key, val) {
|
||||
if (typeof val !== 'undefined') {
|
||||
return getData(el, key)
|
||||
} else {
|
||||
return setData(el, key, val)
|
||||
}
|
||||
}
|
||||
|
||||
export function getData (el, key) {
|
||||
const str = el.getAttribute('data-' + key)
|
||||
return JSON.parse(str || '{}')
|
||||
}
|
||||
|
||||
export function setData (el, key, val) {
|
||||
el.setAttribute('data-' + key, JSON.stringify(val))
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import * as Store from './store'
|
||||
|
||||
/**
|
||||
* Dismisses an announcement.
|
||||
*
|
||||
* @example
|
||||
* setDismissed('2017-09-02-happy-birthday')
|
||||
*/
|
||||
|
||||
export function setDismissed (id) {
|
||||
Store.update('dismissed', function (data) {
|
||||
data[id] = true
|
||||
return data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an announcement has been dismissed before.
|
||||
*
|
||||
* @example
|
||||
* setDismissed('2017-09-02-happy-birthday')
|
||||
* isDismissed('2017-09-02-happy-birthday') => true
|
||||
*/
|
||||
|
||||
export function isDismissed (id) {
|
||||
const data = Store.fetch('dismissed')
|
||||
return data && data[id]
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* Injects disqus's scripts into the page.
|
||||
*
|
||||
* @example
|
||||
* injectDisqus('devhints.disqus.com')
|
||||
*/
|
||||
|
||||
export default function injectDisqus (host) {
|
||||
var d = document, s = d.createElement('script')
|
||||
s.src = 'https://' + host + '/embed.js'
|
||||
s.setAttribute('data-timestamp', +new Date())
|
||||
;(d.head || d.body).appendChild(s)
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* Permutates a searcheable item.
|
||||
*
|
||||
* permutate({
|
||||
* slug: 'hello-world',
|
||||
* category: 'greetings'
|
||||
* })
|
||||
*/
|
||||
|
||||
export default 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
|
||||
}
|
||||
|
||||
/*
|
||||
* Permutates strings.
|
||||
*
|
||||
* @example
|
||||
* permutateString('hi joe')
|
||||
* => ['h', 'hi', 'j', 'jo', 'joe']
|
||||
*/
|
||||
|
||||
export function permutateString (str) {
|
||||
let words = []
|
||||
let inputs = splitwords(str)
|
||||
|
||||
inputs.forEach(word => {
|
||||
words = words.concat(permutateWord(word))
|
||||
})
|
||||
|
||||
return words
|
||||
}
|
||||
|
||||
/**
|
||||
* Permutates a word.
|
||||
*
|
||||
* @example
|
||||
* permutateWord('hello')
|
||||
* => ['h', 'he', 'hel', 'hell', 'hello']
|
||||
*/
|
||||
|
||||
export function permutateWord (str) {
|
||||
let words = []
|
||||
const len = str.length
|
||||
for (var i = 1; i <= len; ++i) {
|
||||
words.push(str.substr(0, i))
|
||||
}
|
||||
return words
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for splitting to words.
|
||||
*
|
||||
* @example
|
||||
* splitWords('Hello, world!')
|
||||
* => ['hello', 'world']
|
||||
*/
|
||||
|
||||
export function splitwords (str) {
|
||||
const words = str.toLowerCase()
|
||||
.split(/[ \/\-_]/)
|
||||
.filter(k => k && k.length !== 0)
|
||||
|
||||
return words
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/**
|
||||
* Checks if we're in preview mode (?preview=1).
|
||||
*/
|
||||
|
||||
export function isPreview () {
|
||||
return window.location.search.indexOf('preview=1') !== -1
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* Updates a local storage key. If it doesn't exist, it defaults to an empty
|
||||
* object.
|
||||
*
|
||||
* @example
|
||||
* update('dismissed', (data) => {
|
||||
* data.lol = true
|
||||
* return data
|
||||
* })
|
||||
*/
|
||||
|
||||
export function update (key, fn) {
|
||||
if (!window.localStorage) return
|
||||
let data = JSON.parse(window.localStorage[key] || '{}')
|
||||
data = fn(data)
|
||||
window.localStorage[key] = JSON.stringify(data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a local storage key.
|
||||
*
|
||||
* @example
|
||||
* const data = fetch('dismissed')
|
||||
*/
|
||||
|
||||
export function fetch (key) {
|
||||
if (!window.localStorage) return
|
||||
return JSON.parse(window.localStorage[key] || '{}')
|
||||
}
|
|
@ -3,14 +3,6 @@
|
|||
*/
|
||||
|
||||
$(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)
|
||||
|
@ -65,100 +57,6 @@ $(function () {
|
|||
})
|
||||
})
|
||||
|
||||
/*
|
||||
* Behavior: Disqus
|
||||
*/
|
||||
|
||||
$(function () {
|
||||
$('[data-js-disqus]').each(function () {
|
||||
const $this = $(this)
|
||||
const data = $this.data('js-disqus')
|
||||
|
||||
window.disqus_config = function () {
|
||||
this.page.url = data.url
|
||||
this.page.identifier = data.identifier
|
||||
}
|
||||
|
||||
injectDisqus(data.host)
|
||||
})
|
||||
})
|
||||
|
||||
/*
|
||||
* Behavior: dismiss button
|
||||
*/
|
||||
|
||||
$(function () {
|
||||
$('[data-js-dismiss]').each(function () {
|
||||
var $button = $(this)
|
||||
var $parent = $button.closest('[data-js-dismissable]')
|
||||
var id = $parent.data('js-dismissable').id || ''
|
||||
|
||||
$button.on('click', function (e) {
|
||||
Dismiss.setDismissed(id)
|
||||
e.preventDefault()
|
||||
$parent.remove()
|
||||
})
|
||||
})
|
||||
|
||||
$('[data-js-dismissable]').each(function () {
|
||||
var $this = $(this)
|
||||
var id = $this.data('js-dismissable').id || ''
|
||||
const isDismissed = Dismiss.isDismissed(id)
|
||||
if (isDismissed || window.location.search.indexOf('preview') !== -1) {
|
||||
$this.remove()
|
||||
} else {
|
||||
$this.removeClass('-hide')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
/*
|
||||
* Helper: dismissed
|
||||
*/
|
||||
|
||||
const Dismiss = {
|
||||
setDismissed: function (id) {
|
||||
Store.update('dismissed', function (data) {
|
||||
data[id] = true
|
||||
return data
|
||||
})
|
||||
},
|
||||
|
||||
isDismissed: function (id) {
|
||||
const data = Store.fetch('dismissed')
|
||||
return data && data[id]
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple LocalStorage shim
|
||||
*/
|
||||
|
||||
const Store = {
|
||||
update: function (key, fn) {
|
||||
if (!window.localStorage) return
|
||||
let data = JSON.parse(window.localStorage[key] || '{}')
|
||||
data = fn(data)
|
||||
window.localStorage[key] = JSON.stringify(data)
|
||||
},
|
||||
|
||||
fetch: function (key) {
|
||||
if (!window.localStorage) return
|
||||
return JSON.parse(window.localStorage[key] || '{}')
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper: injects disqus
|
||||
*/
|
||||
|
||||
function injectDisqus (host) {
|
||||
var d = document, s = d.createElement('script')
|
||||
s.src = 'https://' + host + '/embed.js'
|
||||
s.setAttribute('data-timestamp', +new Date())
|
||||
;(d.head || d.body).appendChild(s)
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper for splitting to words
|
||||
*/
|
||||
|
@ -194,40 +92,6 @@ const Search = {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 = splitwords(str)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper: minimal qs implementation
|
||||
|
|
Loading…
Reference in New Issue