Skip to content

Instantly share code, notes, and snippets.

@nortonwong
Last active June 26, 2019 18:13
Show Gist options
  • Save nortonwong/3df0ed4391799dbd5661c1c4e0cf3693 to your computer and use it in GitHub Desktop.
Save nortonwong/3df0ed4391799dbd5661c1c4e0cf3693 to your computer and use it in GitHub Desktop.
const Lambdas = {
remove: (n) => n.remove(),
append: (n) => document.body.append(n),
appendTo: (target) => (n) => target.append(n),
sum: (a, b) => a+b,
product: (a, b) => a*b,
toggleClass: cl => el => el.classList.toggle(cl),
or: (...predicates) => (n) => predicates.filter(p => p).some(p => p(n)),
};
const Utils = {
queryAll(arg1, arg2) {
const [node, selector] = arg2 ? [arg1, arg2] : [document.body, arg1];
return [...node.querySelectorAll(selector)];
},
query: (...args) => Utils.queryAll(...args)[0],
replaceIf(replaceFn) {
const nextLocation = replaceFn(location.toString());
if (nextLocation) return location = nextLocation;
},
replace: (...args) => Utils.replaceIf(str => str.replace(...args)),
matches: (...args) => location.toString().match(...args),
cases(args, ...cases) {
let [method] = cases.find(([, ...matchArgs]) => Utils.matches(...matchArgs)) || [];
if (method) return method(...args);
},
wrap(selector, prefix, suffix = prefix) { // TODO add ' ' to \s class
document.querySelectorAll(selector).forEach(e =>
e.innerHTML = e.innerHTML.replace(/(\s*)(.*\S)(\s*)/g, (match, a,b,c) => `${a}${prefix}${b}${suffix}${c}`)
);
},
escape: str =>
[...str].map(c => ({
[`&`]: `&`,
[`<`]: `&lt;`,
[`>`]: `&gt;`,
[`"`]: `&quot;`,
[`'`]: `&#039;`,
})[c] || c).join(''),
trim() {
Utils.queryAll(`p`)
.filter(p => p.innerText.match(/^\s+$/))
.forEach(Lambdas.remove);
},
only: (selector) => {
Utils.queryAll(selector)
.forEach(e => {
e.dataset[Uniq.datasetField] = true;
Lambdas.append(e);
});
Utils.queryAll(`body > :not(${Uniq.selector})`)
.forEach(Lambdas.remove);
document.normalize();
},
imgOnly: () => Utils.only(`img`),
trimSrcs() {
Utils.queryAll(`img`)
.filter(img => img.src.includes(`?`))
.forEach(img => img.src = img.src.split(`?`)[0]);
Utils.queryAll(`img`)
.forEach(img => img.title = img.src || img.title);
},
unsize: (n) => [`height`, `width`]
.forEach(attr => n.removeAttribute(attr)),
unstyle: (n) => n.style = null,
dashify: str => str.replace(/[A-Z]/g, c => `-${c.toLowerCase()}`),
styleObj: (rules) => Utils.style(
...Object.entries(rules).map(([selector, block]) => `${selector} { ${
Object.entries(block).map(([property, value]) => `${Utils.dashify(property)}: ${value}`).join(`; `)
} }`),
),
style: (...args) => {
Utils.queryAll(`style${Uniq.selector}`).forEach(Lambdas.remove);
return Utils.create(`style`, { innerText: args.join(`\n`) });
},
replacer: (...args) => () => Utils.replace(...args),
styler: (...args) => () => Utils.style(...args),
create(...args) {
const [target, type, { style, dataset, ...attrs } = {}] = (args[0] instanceof HTMLElement)
? [...args]
: [document.body, ...args];
const el = document.createElement(type);
Object.assign(el, attrs);
Object.assign(el.style, style);
Object.assign(el.dataset, dataset, { [Uniq.datasetField]: true });
target.append(el);
return el;
},
clearAdditions: () => Utils.queryAll(`${Uniq.selector}`).forEach(Lambdas.remove),
img: (...srcs) => srcs.map(src => Utils.create(`img`, { src, title: src })),
a: (...hrefs) => hrefs.map(href => Utils.create(`a`, { href, target: `_blank`, innerText: href })),
divider: (...args) => args.map(arg => Utils.create(`div`, { style: { padding: `3px` }, innerText: `-`.repeat(18) })),
list: (urls) => urls.split('\n')
._flatMap(url => {
if (!url) return Utils.divider();
return (Utils.isImgish(url) ? Utils.img : Utils.a)(url);
}),
isImgish: url => !!url.match(/\.(jpe?g|png|gif)/i),
wayback: (url=window.location) => window.location = `https://web.archive.org/web/*/${url}`,
truncate: (survivor = $) => {
while (survivor.nextSibling) {
survivor.nextSibling.remove();
}
},
isolate: (...els) => {
if (els.length == 0) els = [$0];
els.forEach(Lambdas.append);
Utils.queryAll(`*`)
.filter(n => !els.some(el => el.contains(n)))
.forEach(n => n.remove());
},
isolateTo: (...args) => Utils.isolate(...Utils.queryAll(args)),
save: () => { Object.assign(window, { Utils }) },
localStorage: (getterKey, fn, setterKey=getterKey) => {
const result = fn(JSON.parse(localStorage.getItem(getterKey)));
if (setterKey) return localStorage.setItem(setterKey, JSON.stringify(result));
},
clearTimers: () => {
(window[Uniq.timers] || []).forEach(id => clearInterval(id));
window[Uniq.timers] = [];
},
setTimer: (fn, time=1000) => {
Utils.clearTimers();
if (time) return window[Uniq.timers] = [setInterval(fn, time)];
},
setTimers: (...setTimerArgs) => {
Utils.clearTimers();
return window[Uniq.timers] = setTimerArgs
.filter(([, time]) => time)
.map(([fn, time=1000]) => setInterval(fn, time));
},
sleep: (time) => new Promise((resolve, reject) => { setInterval(resolve, time); }),
* range(start, end) {
if ([start, end].some(n => !Number.isInteger(n))) throw new TypeError(`range(${start}, ${end}) must take integers`);
const step = Math.sign(end-start);
let current = start;
yield current;
while (current != end) {
yield current += step;
}
},
* take(iterator, limit) {
let i = 0;
while (i++ < limit) {
const { value, done } = iterator.next();
if (done) return;
yield value;
}
},
table: (arr, wrap) => {
const matrix = [];
const iterator = arr[Symbol.iterator]();
let i = 0;
while (i < arr.length) {
const row = Math.floor(i / wrap);
const col = i - row*wrap;
(matrix[row] = matrix[row] || [])[col] = arr[i];
i++;
}
return matrix;
},
param: (param, base = location.toString()) => new URLSearchParams(base.split('?')[1]).get(param),
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment