diff options
Diffstat (limited to 'static/js/edidor.js')
-rw-r--r-- | static/js/edidor.js | 560 |
1 files changed, 312 insertions, 248 deletions
diff --git a/static/js/edidor.js b/static/js/edidor.js index d90d647..cdd6176 100644 --- a/static/js/edidor.js +++ b/static/js/edidor.js @@ -1,275 +1,181 @@ ; (function (window, document) { - let pane - let main - let rect - document.addEventListener('DOMContentLoaded', e => { - pane = document.querySelector('.sidebar') - main = document.querySelector('.main') - rect = pane.getBoundingClientRect() - const state = { - last: false, - resizing: false, - resizable: false + const wildStyle = styleTemplate`.wild-mode .main a { + color: ${'dark'}; } - activateSidebarToggler() - activateSidebarDrag() - restoreSidebar() - tryLoadMode() - function activateSidebarDrag () { - document.body.addEventListener('mousemove', throttle(onMousemove, 50)) // eslint-disable-line - - function onMousemove (e) { - state.resizable = canResize(e.clientX) - if (state.resizing) { - resize(e.clientX) - } else if (state.last !== state.resizable && e.clientX > 10) { - switchCursor() - state.last = state.resizable - } - } - document.body.addEventListener('mousedown', e => { - if (state.resizable) { - state.resizing = true - } - }) - document.body.addEventListener('touchstart', e => { - state.resizing = canResize(e.touches[0].clientX, 10) - }) - document.body.addEventListener('touchmove', e => { - if (state.resizing) { - resize(e.touches[0].clientX) - } - }) - - document.addEventListener('keydown', e => { - if (e.ctrlKey && e.keyCode === 66) { - toggleSidebar() - } - }) - document.body.addEventListener('touchend', cancelResize) - document.body.addEventListener('mouseup', cancelResize) - - function cancelResize (e) { - if (e.target.classList.contains('sidebar-toggler')) { - return - } - state.resizing = false - let r = pane.getBoundingClientRect() - saveWidth(r.right - r.left) - } - - function switchCursor () { - if (state.resizable) { - document.body.style.cursor = 'ew-resize' - } else { - document.body.style.cursor = 'auto' - } - } - - function canResize (x, threshold = 4) { - return Math.abs(x - pane.getBoundingClientRect().right) <= threshold - } - - function resize (x) { - let newWidth = x - rect.left - if (newWidth <= 10) { - pane.classList.add('hide') - } else { - setWidth(newWidth) - } - } + .wild-mode .main .article-tags a { + background: ${'light'}; } - function activateSidebarToggler () { - const toggle = document.querySelector('.sidebar-toggler') - toggle && toggle.addEventListener('click', toggleSidebar) + .wild-mode .local-info { + background: ${'light'}; } - function setWidth (x, unit = 'px') { - pane.style.width = x + unit - main.style.marginLeft = x + unit + body.wild-mode, + .wild-mode .main { + background: ${'light'}; } - function saveWidth (x) { - if (x <= 10) { - return - } - window.localStorage.setItem('sidebar_width', x) + .wild-mode th, + .wild-mode td { + border-bottom: 1px solid ${'dark'}; } - function toggleSidebar (e) { - if (pane.classList.contains('hide')) { - pane.classList.remove('hide') - window.localStorage.setItem('is_sidebar_hide', '0') - } else { - pane.classList.add('hide') - window.localStorage.setItem('is_sidebar_hide', '1') - } + .wild-mode hr { + border: 1px solid ${'dark'}; } - function restoreSidebar () { - let x = window.localStorage.getItem('sidebar_width') - setWidth(x) - let flag = window.localStorage.getItem('is_sidebar_hide') - flag === '1' ? pane.classList.add('hide') : pane.classList.remove('hide') + .wild-mode .pagination { + background: ${'dark'}; } - - function tryLoadMode () { - let mode = window.localStorage.getItem('mode') - if (mode) { - document.body.className = '' - document.body.classList.add(mode) - } - if (mode === 'wild-mode') { - let wildEle = document.createElement('style') - wildEle.classList.add('wild-ele') - wildEle.innerText = window.localStorage.getItem('wild_style') - document.body.appendChild(wildEle) - } + .wild-mode .sidebar { + background: ${'dark'}; } - }) -})(window, document); - -(function (window, document) { - const toMode = name => { - let b = document.body - b.className = '' - b.classList.add(name) - window.localStorage.setItem('mode', name) - } - const wildStyle = styleTemplate`.wild-mode .main a { - color: ${'dark'}; - } - .wild-mode .main .article-tags a { - background: ${'light'}; - color : #000000; - } - .wild-mode .local-info { - background: ${'light'}; - color : #000000; - box-shadow: none; - } - body.wild-mode, - .wild-mode .main { - background: ${'light'}; - } - .wild-mode .main, - .wild-mode blockquote.twitter-tweet, - .wild-mode .sidebar a, - .wild-mode .taxonomy-key, - .wild-mode .main .title a { - color: #333333; - } - .wild-mode .icon { - background: #333333; - } - .wild-mode .article-meta, - .wild-mode .item-meta, - .wild-mode .footnotes { - color: #999999; - } - .wild-mode th, - .wild-mode td { - border-bottom: 1px solid ${'dark'}; - } - .wild-mode hr { - border: 1px solid ${'dark'}; - } - .wild-mode .pagination { - background: ${'dark'}; - } - .wild-mode .sidebar { - background: ${'dark'}; - } - .wild-mode pre, - .wild-mode code { - background: ${'gray'}; - } - .wild-mode .count, - .wild-mode .taxonomy-key { - color: ${'lightGray'}; - } - .wild-mode .header, - .wild-mode .footer, - .wild-mode .header .sub-menu li:hover, - .wild-mode .sidebar a:hover, - .wild-mode .logo-link { - background: ${'dark'}; + .wild-mode .count, + .wild-mode .taxonomy-key { + color: ${'lightGray'}; + } + .wild-mode .header, + .wild-mode .footer, + .wild-mode .header .sub-menu li:hover, + .wild-mode .sidebar a:hover, + .wild-mode .logo-link { + background: ${'dark'}; + } + .wild-mode .header .menu>li:hover, + .wild-mode .footer a:hover { + background: ${'light'}; + } + .wild-mode .header ul ul { + box-shadow: 0 0.1em 0.2em 0 ${'dark'}; + } + .wild-mode .header ul ul, + .wild-mode .pagination a:hover { + background: ${'dark'}; + }` + // dom helper functions ... + function qs (sel, parent = document.body) { + if (typeof parent === 'string') { + parent = document.querySelector(parent) + } + return parent.querySelector(sel) } - .wild-mode .header .menu>li:hover, - .wild-mode .footer a:hover { - background: ${'light'}; + + function elt (name, attr = {}, ...text) { + const node = document.createElement(name) + Object.keys(attr).forEach(k => { + node.setAttribute(k, attr[k]) + }) + text.forEach(t => { + if (typeof t === 'string') { + t = document.createTextNode(t) + } + node.appendChild(t) + }) + return node } - .wild-mode .header ul ul { - box-shadow: 0 0.1em 0.2em 0 ${'dark'}; + + function removeClass (dom, cls) { + if (typeof dom === 'string') { + dom = qs(dom) + } + dom.classList.remove(cls) + return dom } - .wild-mode .header ul ul, - .wild-mode .pagination a:hover { - background: ${'dark'}; + function clearClass (dom, cls) { + if (typeof dom === 'string') { + dom = qs(dom) + } + dom.className = '' + return dom } - .wild-mode .header a, - .wild-mode .footer a, - .wild-mode .footer time, - .wild-mode .pagination a { - color: #333333; + function addClass (dom, cls) { + if (typeof dom === 'string') { + dom = qs(dom) + } + dom.classList.add(cls) + return dom } - .wild-mode .header .sub-menu a { - color: #333333; + // function toggleClass (dom, cls) { // eslint-disable-line + // if (typeof dom === 'string') { + // dom = qs(dom) + // } + // dom.classList.toggle(cls) + // return dom + // } + function hasClass (dom, cls) { + if (typeof dom === 'string') { + dom = qs(dom) + } + return dom.classList.contains(cls) } - .wild-mode .footer .icon { - background-color: #333333; + function setStyle (dom, styles) { + if (typeof dom === 'string') { + dom = qs(dom) + } + + Object.keys(styles).forEach(key => { + dom.style[key] = styles[key] + }) } - .wild-mode .main h1, - .wild-mode .main h2, - .wild-mode .main h3, - .wild-mode .main h4, - .wild-mode .main h5, - .wild-mode .main h6, - .wild-mode .title { - text-shadow: none; - }` - const gen = { - dark: genDark, - light: genLight, - lightGray: genGray.bind(5), - gray: genGray + function onEvent (event, cb, limit = 0, dom = document.body) { + if (typeof dom === 'string') { + dom = qs(dom) + } + if (limit > 0) { + dom.addEventListener(event, throttle(cb, limit)) // eslint-disable-line + } else { + dom.addEventListener(event, cb) + } } + // mousemove and touchmove abstraction + function onPointerMove (cb, limit, dom = document.body) { + onEvent('mousemove', e => { + cb({ // eslint-disable-line + clientX: e.clientX, + clientY: e.clientY, + type: e.type + }) + }, limit, dom) - function applyWildStyle () { - let wildEle = document.querySelector('.wild-ele') || document.createElement('style') - let style = wildStyle().replace(/\n/gm, '') - wildEle.innerText = style - window.localStorage.setItem('wild_style', style) - document.body.appendChild(wildEle) + onEvent('touchmove', e => { + cb({ // eslint-disable-line + clientX: e.touches[0].clientX, + clientY: e.touches[0].clientY, + type: e.type + }) + }, limit, dom) } + // local storage + const ls = {} + ls.get = key => window.localStorage.getItem(key) - function styleTemplate (strings, ...keys) { - return function () { - let temp = strings.slice() - keys.forEach((key, i) => { - temp[i] += gen[key]() - }) - return temp.join('') + ls.set = (key, value) => { + if (value === null || value === undefined) { + value = '' + } else if (typeof value !== 'string') { + value = JSON.stringify(value) } + window.localStorage.setItem(key, value) + } + // color generators + const gen = { + darkCode: ['c', 'f', '6', '9'], + lightCode: ['a', 'b', 'c', 'd', 'e', 'f'] } - const dark = ['c', 'f', '6', '9'] - const light = ['a', 'b', 'c', 'd', 'e', 'f'] - - function genDark () { + gen.dark = () => { let d = '' for (let i = 0; i !== 3; i++) { - let c = dark[randomInt(0, dark.length)] + let c = gen.darkCode[randomInt(0, gen.darkCode.length)] d += c + c } return '#' + d } - - function genLight () { + gen.light = () => { let d = '' for (let i = 0; i !== 6; i++) { - d += light[randomInt(0, light.length)] + d += gen.lightCode[randomInt(0, gen.lightCode.length)] } return '#' + d } - function genGray (base = 0) { + gen.gray = (base = 0) => { let ret = '' for (let i = 0; i !== 6; i++) { if (base > 3) { @@ -280,20 +186,178 @@ } return '#' + ret } - + gen.lightGray = gen.gray.bind(5) function randomInt (min, max) { min = Math.ceil(min) max = Math.floor(max) return Math.floor(Math.random() * (max - min)) + min } - document.querySelector('.to-light-mode').addEventListener('click', e => { - toMode('light-mode') - }) - document.querySelector('.to-dark-mode').addEventListener('click', e => { - toMode('dark-mode') - }) - document.querySelector('.to-wild-mode').addEventListener('click', e => { - toMode('wild-mode') - applyWildStyle() - }) -})(window, document); + // tagged template function, make wild styles + function styleTemplate (strings, ...keys) { + return function () { + let temp = strings.slice() + keys.forEach((key, i) => { + temp[i] += gen[key]() + }) + return temp.join('').replace(/\s{2}/gm, ' ') + } + } + // utility functions end + let pane + let main + let paneLeft + let cloak + // entry + onEvent('DOMContentLoaded', e => { + pane = qs('.sidebar') + main = qs('.main') + cloak = qs('#cloak') + paneLeft = pane.getBoundingClientRect().left + tryLoadMode() + tryRestoreSidebar() + activateSidebarToggler() + activateModeSwitcher() + activateSidebarDrag() + }, 0, document) + // sidebar function dragging wrapper + function activateSidebarDrag () { + const state = { + last: false, + resizing: false, + resizable: false + } + + function switchCursor () { + if (state.resizable) { + setStyle(document.body, { cursor: 'ew-resize' }) + } else { + setStyle(document.body, { cursor: 'auto' }) + } + } + + function canResize (x, threshold = 4) { + return Math.abs(x - pane.getBoundingClientRect().right) <= threshold + } + function resize (x) { + let newWidth = x - paneLeft + if (newWidth <= 10) { + addClass(pane, 'hide') + } else { + adjustWidth(newWidth) + } + } + function cancelResize (e) { + state.resizing = false + let r = pane.getBoundingClientRect() + saveWidth(r.right - r.left) + } + + function saveWidth (x) { + if (x <= 10) { + return + } + ls.set('sidebar_width', x) + } + + onEvent('mousedown', e => { + if (state.resizable) { + state.resizing = true + } + }, 0) + onEvent('mouseup', cancelResize, 0) + onEvent('keydown', e => { + if (e.ctrlKey && e.keyCode === 66) { + toggleSidebar() + } + }, 0) + + onEvent('touchstart', e => { + state.resizing = canResize(e.touches[0].clientX, 10) + }) + onEvent('touchend', cancelResize) + onPointerMove(pointerMoveHandler, 50, qs('.middle')) + function pointerMoveHandler (e) { + state.resizable = canResize(e.clientX) + if (state.resizing) { + resize(e.clientX) + } else if (e.type === 'mousemove' && e.clientX > 10 && state.last !== state.resizable) { + switchCursor() + state.last = state.resizable + } + } + } + // sidebar dragging function end + // toggle and load sidebar width + function adjustWidth (x, unit = 'px') { + setStyle(pane, { width: x + 'px' }) + setStyle(main, { marginLeft: x + 'px' }) + } + function tryRestoreSidebar () { + let x = ls.get('sidebar_width') + adjustWidth(x) + let flag = ls.get('is_sidebar_hide') + flag === '1' ? addClass(pane, 'hide') : removeClass(pane, 'hide') + } + function activateSidebarToggler () { + onEvent('click', toggleSidebar, 0, '.sidebar-toggler') + } + + function toggleSidebar (e) { + if (hasClass(pane, 'hide')) { + removeClass(pane, 'hide') + ls.set('is_sidebar_hide', '0') + } else { + addClass(pane, 'hide') + ls.set('is_sidebar_hide', '1') + } + e.preventDefault() + e.stopPropagation() + return false + } + // style mode functions + const toMode = name => { + addClass(clearClass(document.body), name) + ls.set('mode', name) + } + function tryLoadMode () { + console.log('load mode') + let mode = ls.get('mode') + mode && toMode(mode) + if (mode === 'wild-mode') { + let wildEle = elt( + 'style', + { class: 'wild-ele' }, + ls.get('wild_style')) + document.body.appendChild(wildEle) + } + hideCloak() + } + function activateModeSwitcher () { + onEvent('click', e => { + toMode('light-mode') + }, 0, qs('.to-light-mode')) + + onEvent('click', e => { + toMode('dark-mode') + }, 0, qs('.to-dark-mode')) + + onEvent('click', e => { + toMode('wild-mode') + let wildEle = qs('.wild-ele') + const style = wildStyle() + if (wildEle) { + wildEle.innerText = style + } else { + document.body.appendChild(elt('style', { class: 'wild-ele' }, style)) + } + ls.set('wild_style', style) + }, 0, qs('.to-wild-mode')) + } + + // function showCloak () { + // removeClass(cloak, 'hide') + // } + function hideCloak () { + addClass(cloak, 'hide') + } +})(window, document) |