Skip to content

Instantly share code, notes, and snippets.

View OliverJAsh's full-sized avatar

Oliver Joseph Ash OliverJAsh

View GitHub Profile
@OliverJAsh
OliverJAsh / index.js
Last active October 19, 2017 17:45
Hide likes from Twitter Lite timeline
"use strict";
// https://github.com/gcanti/fp-ts/blob/eec336fada51bf34f7e68592fe1dc348ca5ef873/src/function.ts#L127
const pipe = (...fns) => (seed) => fns.reduce((val, fn) => fn(val), seed);
const isNotUndefined = (maybeT) => maybeT !== undefined;
const mapMaybe = (f, maybeT) => isNotUndefined(maybeT) ? f(maybeT) : maybeT;
const normalizeMaybe = (nullMaybe) => nullMaybe === null ? undefined : nullMaybe;
const forEachMaybe = (f, maybeT) => {
if (isNotUndefined(maybeT))
f(maybeT);
};
@OliverJAsh
OliverJAsh / foo.js
Created August 31, 2017 12:10
Debug responsive images
// On resize and img load events, logs:
// - `currentSrc` width (selected from `srcset`)
// - element width
// - parsed size value (selected from `sizes`)
// - a boolean indicating if the parsed size matches the element width
{
// There seem to be issues with `HTMLImageElement.natural{Width,Height}`, so we have to rely on this
// instead.
@OliverJAsh
OliverJAsh / foo.ts
Last active August 30, 2017 10:01
Cancellable fetch
type CancellableFetchResult = { aborted: true } | { aborted: false; responseText: string };
export type CancellableFetchReturn = {
completePromise: Promise<CancellableFetchResult>;
abort: Function;
};
// Returns a promise API and the original XHR for abortion.
export const cancellableFetch = (
url: string,
options: RequestInit = {},
@OliverJAsh
OliverJAsh / foo.md
Last active August 29, 2017 09:28
Unsplash image layout

Solution: http://jsbin.com/melewe/3/edit?html,css,js,output

The requirements are:

  1. Reserve space for the image whilst it loads.
  2. Contain image (including padding) in viewport (fill width or height, whichever is smallest), whilst only taking up necessary space.
  3. Minimum height
  4. Responsive images

For 1 we can use the padding-bottom trick.

@OliverJAsh
OliverJAsh / foo.md
Last active May 31, 2021 07:25
JavaScript function declarations vs. expressions
@OliverJAsh
OliverJAsh / foo.ts
Created June 16, 2017 23:15
TypeScript: function object parameter with defaults
{
type All = { foo: string, bar: string };
type Requireds = Pick<All, 'foo'>;
type Defaults = Pick<All, 'bar'>;
// Our function expects all required fields and any overrides for fields with defaults.
type Args = Requireds & Partial<Defaults>;
const defaults: Defaults = { bar: 'bar' };
const fn = (args: Args) => {
const all: All = { ...defaults, ...args };
@OliverJAsh
OliverJAsh / foo.js
Created May 31, 2017 11:24
Get total image size from HAR file
const fs = require('fs');
const harPath = `${__dirname}/my-site.har`;
const harString = fs.readFileSync(harPath, 'utf-8');
const harParsed = JSON.parse(harString);
const { entries } = harParsed.log;
const isImageEntry = entry => entry.request.url.startsWith('https://images.unsplash.com/photo-');
@OliverJAsh
OliverJAsh / foo.md
Created May 15, 2017 10:42
What are some pros/cons to using iterables (sagas) and observables in Redux?

What are some pros/cons to using iterables (sagas) and observables in Redux?

Iterables (Sagas)

Pros

  • Most popular solution, so probably better community support.
  • Testing: very easy to mock side effects using "call" effect.

Cons

  • Lack of operators (retry, take, etc.).

Observables

@OliverJAsh
OliverJAsh / foo.js
Created May 3, 2017 12:37
Find all usages of an image URL in the DOM (background image or img src)
const findImageUsages = url => {
const allNodes = Array.from(document.querySelectorAll('*'));
return allNodes
.map(node => {
const backgroundImageUrl = window.getComputedStyle(node).backgroundImage
// Remove `url()` or `url("")` wrapper
.slice(4, -1)
.replace(/"/g, '');
const hasMatchingBackgroundImageUrl = backgroundImageUrl === url;
@OliverJAsh
OliverJAsh / foo.js
Last active October 22, 2021 09:45
Async iterators with map, skipWhile, and takeUntil
class FunctifiedAsync {
constructor(iterable) {
this.iterable = iterable;
}
async *[Symbol.asyncIterator]() {
for await (const value of this.iterable) {
yield value;
}
}