Skip to content

Instantly share code, notes, and snippets.

View THEtheChad's full-sized avatar

Chad Elliott THEtheChad

View GitHub Profile
type Narrow<T> =
| (T extends Function ? T : never)
| (T extends string | number | bigint | boolean ? T : never)
| (T extends [] ? [] : never)
| {
[K in keyof T]: Narrow<T[K]>;
};
function narrow<T extends object>(input: Narrow<T>){
return input
const offsetBase = document.createElement('div');
offsetBase.style.cssText = 'position:absolute;left:0;top:0';
document.body.appendChild(offsetBase);
export default function getWindowPosition(node: Element) {
const boundingRect = node.getBoundingClientRect();
const baseRect = offsetBase.getBoundingClientRect();
const left = boundingRect.left - baseRect.left;
const top = boundingRect.top - baseRect.top;
export default function getScrollParent(node?: Node | null) {
if (!(node instanceof HTMLElement)) return null;
if (typeof window.getComputedStyle !== 'function') return null;
const overflowY = window.getComputedStyle(node).overflowY || 'visible';
const isScrollable = /^(visible|hidden)/.test(overflowY);
if (isScrollable && node.scrollHeight >= node.clientHeight) {
return node;
}
// inspired by https://gist.github.com/creationix/1821394
// from Tim Caswell
import { EventEmitter } from 'events';
interface ParserEvents {
StartObject: () => void;
EndObject: () => void;
StartArray: () => void;
EndArray: () => void;
@THEtheChad
THEtheChad / addEvent.js
Created May 15, 2019 15:05
Cross browser event listener.
function removeHandler(){
this.element.removeEventListener(this.event, this.handler)
}
function detachHandler(){
this.element.detachEvent('on' + this.event, this.handler)
}
function addEvent(ele, evt, fn){
if(ele.addEventListener){
(function (w) {
var uuid = 'capture_xxxxxxxx_xxxx_4xxx_yxxx_xxxxxxxxxxxx'.replace(
/[xy]/g,
function (c) {
var r = (Math.random() * 16) | 0,
v = c == 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
}
);
@THEtheChad
THEtheChad / intercept.js
Last active December 10, 2018 20:35
Intercept XHR requests for tracking ajax events.
(function(open){
var targetURL = new RegExp('http://google.com');
XMLHttpRequest.prototype.open = function(){
this.addEventListener('readystatechange', function(){
if(this.readyState !== 4) return;
if(this.status < 200 || this.status >= 300) return;
if(!targetURL.test(this.responseURL)) return;
// SUCCESS
@THEtheChad
THEtheChad / prependParams.js
Created July 13, 2018 20:35
Function for forwarding query parameters for the purpose of analytics and attribution tracking.
function prependParams(){
var params = document.location.search;
if(!params) return;
params = params + '&';
var nodeList = document.getElementsByTagName('a');
var anchors = Array.prototype.slice.call(nodeList);
var l = anchors.length;
var q = /\?/;
function locate(target, value, path = null){
if(target instanceof RegExp){
if(target.test(value)) return path
}
else{
if(value === target) return path
}
if(Array.isArray(value)){
return value.reduce((memo, v, i) =>
@THEtheChad
THEtheChad / byReference.js
Last active December 31, 2017 03:43
Best overall shuffling algorithm (browser tests only)[https://jsperf.com/array-shuffle-comparator/9] #toolbox
// **WARNING**
// in place (by reference) reordering
// http://stackoverflow.com/a/2450976/1037948
function knuthfisheryates2(arr) {
var temp, j, i = arr.length;
while (--i) {
j = ~~(Math.random() * (i + 1));
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;