| import Url from 'licia/Url' |
| import contain from 'licia/contain' |
| import escapeJsStr from 'licia/escapeJsStr' |
| import isUndef from 'licia/isUndef' |
| import last from 'licia/last' |
| import map from 'licia/map' |
| import memStorage from 'licia/memStorage' |
| import toNum from 'licia/toNum' |
| import trim from 'licia/trim' |
| import html from 'licia/html' |
|
|
| |
| export function hasSafeArea() { |
| let proceed = false |
| const div = document.createElement('div') |
| if (CSS.supports('padding-bottom: env(safe-area-inset-bottom)')) { |
| div.style.paddingBottom = 'env(safe-area-inset-bottom)' |
| proceed = true |
| } else if (CSS.supports('padding-bottom: constant(safe-area-inset-bottom)')) { |
| div.style.paddingBottom = 'constant(safe-area-inset-bottom)' |
| proceed = true |
| } |
| if (proceed) { |
| document.body.appendChild(div) |
| const calculatedPadding = parseInt( |
| window.getComputedStyle(div).paddingBottom |
| ) |
| document.body.removeChild(div) |
| if (calculatedPadding > 0) { |
| return true |
| } |
| } |
| return false |
| } |
|
|
| export function escapeJsonStr(str) { |
| return escapeJsStr(str).replace(/\\'/g, "'").replace(/\t/g, '\\t') |
| } |
|
|
| export function safeStorage(type, memReplacement) { |
| if (isUndef(memReplacement)) memReplacement = true |
|
|
| let ret |
|
|
| switch (type) { |
| case 'local': |
| ret = window.localStorage |
| break |
| case 'session': |
| ret = window.sessionStorage |
| break |
| } |
|
|
| try { |
| |
| const x = 'test-localStorage-' + Date.now() |
| ret.setItem(x, x) |
| const y = ret.getItem(x) |
| ret.removeItem(x) |
| if (y !== x) throw new Error() |
| } catch { |
| if (memReplacement) return memStorage |
| return |
| } |
|
|
| return ret |
| } |
|
|
| export function getFileName(url) { |
| let ret = last(url.split('/')) |
|
|
| if (ret === '') { |
| url = new Url(url) |
| ret = url.hostname |
| } |
|
|
| return ret |
| } |
|
|
| export function pxToNum(str) { |
| return toNum(str.replace('px', '')) |
| } |
|
|
| export function isErudaEl(el) { |
| while (el) { |
| if (el.id === 'eruda') return true |
| el = el.parentNode |
| } |
|
|
| return false |
| } |
|
|
| export function isChobitsuEl(el) { |
| while (el) { |
| let className = '' |
| if (el.getAttribute) { |
| className = el.getAttribute('class') || '' |
| } |
| if (contain(className, '__chobitsu-hide__')) { |
| return true |
| } |
| el = el.parentNode |
| } |
|
|
| return false |
| } |
|
|
| export function classPrefix(str) { |
| if (/<[^>]*>/g.test(str)) { |
| try { |
| const tree = html.parse(str) |
| traverseTree(tree, (node) => { |
| if (node.attrs && node.attrs.class) { |
| node.attrs.class = processClass(node.attrs.class) |
| } |
| }) |
| return html.stringify(tree) |
| } catch { |
| return processClass(str) |
| } |
| } |
|
|
| return processClass(str) |
| } |
|
|
| function traverseTree(tree, handler) { |
| for (let i = 0, len = tree.length; i < len; i++) { |
| const node = tree[i] |
| handler(node) |
| if (node.content) { |
| traverseTree(node.content, handler) |
| } |
| } |
| } |
|
|
| function processClass(str) { |
| const prefix = 'eruda-' |
|
|
| return map(trim(str).split(/\s+/), (singleClass) => { |
| if (contain(singleClass, prefix)) { |
| return singleClass |
| } |
|
|
| return singleClass.replace(/[\w-]+/, (match) => `${prefix}${match}`) |
| }).join(' ') |
| } |
|
|
| export function eventClient(type, e) { |
| const name = type === 'x' ? 'clientX' : 'clientY' |
|
|
| if (e[name]) { |
| return e[name] |
| } |
| if (e.changedTouches) { |
| return e.changedTouches[0][name] |
| } |
|
|
| return 0 |
| } |
|
|
| export function eventPage(type, e) { |
| const name = type === 'x' ? 'pageX' : 'pageY' |
|
|
| if (e[name]) { |
| return e[name] |
| } |
| if (e.changedTouches) { |
| return e.changedTouches[0][name] |
| } |
|
|
| return 0 |
| } |
|
|