Chore: Add issue/pr template and general housekeeping tools and docs (#900)
* Add linting * Add issue templates and docs * Add root eslint config and remove tslint * Autofix lint issues
This commit is contained in:
@@ -14,7 +14,8 @@
|
||||
"bundle": "rollup --config",
|
||||
"typings": "tsc -d --declarationDir typings",
|
||||
"check-types": "tsc -noEmit",
|
||||
"prepublish": "npm run typings && npm run bundle"
|
||||
"prepublish": "npm run typings && npm run bundle",
|
||||
"lint": "yarn eslint src"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -70,7 +71,6 @@
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-node": "^10.7.0",
|
||||
"tslib": "^2.3.1",
|
||||
"tslint": "^6.1.3",
|
||||
"typescript": "^4.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* tslint:disable: no-console */
|
||||
/* eslint:disable: no-console */
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
@@ -13,11 +13,11 @@ function getCode() {
|
||||
return fs.readFileSync(bundlePath, 'utf8');
|
||||
}
|
||||
|
||||
(async () => {
|
||||
void (async () => {
|
||||
const code = getCode();
|
||||
let events = [];
|
||||
|
||||
start();
|
||||
await start();
|
||||
|
||||
const fakeGoto = async (page, url) => {
|
||||
const intercept = async (request) => {
|
||||
|
||||
@@ -22,14 +22,14 @@ function pathToSelector(node: HTMLElement): string | '' {
|
||||
break;
|
||||
}
|
||||
name = name.toLowerCase();
|
||||
let parent = node.parentElement;
|
||||
const parent = node.parentElement;
|
||||
|
||||
let domSiblings = [];
|
||||
const domSiblings = [];
|
||||
|
||||
if (parent.children && parent.children.length > 0) {
|
||||
// tslint:disable-next-line:prefer-for-of
|
||||
for (let i = 0; i < parent.children.length; i++) {
|
||||
let sibling = parent.children[i];
|
||||
const sibling = parent.children[i];
|
||||
if (sibling.localName && sibling.localName.toLowerCase) {
|
||||
if (sibling.localName.toLowerCase() === name) {
|
||||
domSiblings.push(sibling);
|
||||
|
||||
@@ -123,8 +123,8 @@ const moveKey = (id: number, parentId: number) => `${id}@${parentId}`;
|
||||
* controls behaviour of a MutationObserver
|
||||
*/
|
||||
export default class MutationBuffer {
|
||||
private frozen: boolean = false;
|
||||
private locked: boolean = false;
|
||||
private frozen = false;
|
||||
private locked = false;
|
||||
|
||||
private texts: textCursor[] = [];
|
||||
private attributes: attributeCursor[] = [];
|
||||
@@ -597,7 +597,7 @@ export default class MutationBuffer {
|
||||
// if this node is blocked `serializeNode` will turn it into a placeholder element
|
||||
// but we have to remove it's children otherwise they will be added as placeholders too
|
||||
if (!isBlocked(n, this.blockClass))
|
||||
(n as Node).childNodes.forEach((childN) => this.genAdds(childN));
|
||||
(n ).childNodes.forEach((childN) => this.genAdds(childN));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -549,8 +549,8 @@ function initStyleSheetObserver(
|
||||
|
||||
Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
|
||||
unmodifiedFunctions[typeKey] = {
|
||||
insertRule: (type as GroupingCSSRuleTypes).prototype.insertRule,
|
||||
deleteRule: (type as GroupingCSSRuleTypes).prototype.deleteRule,
|
||||
insertRule: (type ).prototype.insertRule,
|
||||
deleteRule: (type ).prototype.deleteRule,
|
||||
};
|
||||
|
||||
type.prototype.insertRule = function (rule: string, index?: number) {
|
||||
|
||||
@@ -30,8 +30,8 @@ export class CanvasManager {
|
||||
|
||||
private mutationCb: canvasMutationCallback;
|
||||
private resetObservers?: listenerHandler;
|
||||
private frozen: boolean = false;
|
||||
private locked: boolean = false;
|
||||
private frozen = false;
|
||||
private locked = false;
|
||||
|
||||
public reset() {
|
||||
this.pendingCanvasMutations.clear();
|
||||
|
||||
@@ -19,7 +19,7 @@ export default function initCanvasContextObserver(
|
||||
) {
|
||||
if (!isBlocked(this, blockClass)) {
|
||||
if (!('__context' in this))
|
||||
(this as ICanvas).__context = contextType;
|
||||
(this ).__context = contextType;
|
||||
}
|
||||
return original.apply(this, [contextType, ...args]);
|
||||
};
|
||||
|
||||
@@ -31,8 +31,8 @@ function patchGLPrototype(
|
||||
return function (this: typeof prototype, ...args: Array<unknown>) {
|
||||
const result = original.apply(this, args);
|
||||
saveWebGLVar(result, win, prototype);
|
||||
if (!isBlocked(this.canvas as HTMLCanvasElement, blockClass)) {
|
||||
const id = mirror.getId(this.canvas as HTMLCanvasElement);
|
||||
if (!isBlocked(this.canvas , blockClass)) {
|
||||
const id = mirror.getId(this.canvas );
|
||||
|
||||
const recordArgs = serializeArgs([...args], win, prototype);
|
||||
const mutation: canvasMutationWithType = {
|
||||
@@ -41,7 +41,7 @@ function patchGLPrototype(
|
||||
args: recordArgs,
|
||||
};
|
||||
// TODO: this could potentially also be an OffscreenCanvas as well as HTMLCanvasElement
|
||||
cb(this.canvas as HTMLCanvasElement, mutation);
|
||||
cb(this.canvas , mutation);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -24,7 +24,7 @@ export default async function canvasMutation({
|
||||
errorHandler: Replayer['warnCanvasMutationFailed'];
|
||||
}): Promise<void> {
|
||||
try {
|
||||
let precomputedMutation: canvasMutationParam =
|
||||
const precomputedMutation: canvasMutationParam =
|
||||
canvasEventMap.get(event) || mutation;
|
||||
|
||||
const commands: canvasMutationCommand[] =
|
||||
|
||||
@@ -12,7 +12,7 @@ function getContext(
|
||||
try {
|
||||
if (type === CanvasContext.WebGL) {
|
||||
return (target.getContext('webgl')! ||
|
||||
target.getContext('experimental-webgl')) as WebGLRenderingContext;
|
||||
target.getContext('experimental-webgl'));
|
||||
}
|
||||
return target.getContext('webgl2')!;
|
||||
} catch (e) {
|
||||
|
||||
@@ -350,7 +350,7 @@ export class Replayer {
|
||||
this.speedService.send({
|
||||
type: 'SET_SPEED',
|
||||
payload: {
|
||||
speed: config.speed!,
|
||||
speed: config.speed,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -478,7 +478,7 @@ export class Replayer {
|
||||
private setupDom() {
|
||||
this.wrapper = document.createElement('div');
|
||||
this.wrapper.classList.add('replayer-wrapper');
|
||||
this.config.root!.appendChild(this.wrapper);
|
||||
this.config.root.appendChild(this.wrapper);
|
||||
|
||||
this.mouse = document.createElement('div');
|
||||
this.mouse.classList.add('replayer-mouse');
|
||||
@@ -600,7 +600,7 @@ export class Replayer {
|
||||
}
|
||||
if (this.config.skipInactive && !this.nextUserInteractionEvent) {
|
||||
for (const _event of this.service.state.context.events) {
|
||||
if (_event.timestamp! <= event.timestamp!) {
|
||||
if (_event.timestamp <= event.timestamp) {
|
||||
continue;
|
||||
}
|
||||
if (this.isUserInteraction(_event)) {
|
||||
@@ -643,7 +643,7 @@ export class Replayer {
|
||||
this.service.send({ type: 'CAST_EVENT', payload: { event } });
|
||||
|
||||
// events are kept sorted by timestamp, check if this is the last event
|
||||
let last_index = this.service.state.context.events.length - 1;
|
||||
const last_index = this.service.state.context.events.length - 1;
|
||||
if (event === this.service.state.context.events[last_index]) {
|
||||
const finish = () => {
|
||||
if (last_index < this.service.state.context.events.length - 1) {
|
||||
@@ -675,7 +675,7 @@ export class Replayer {
|
||||
|
||||
private rebuildFullSnapshot(
|
||||
event: fullSnapshotEvent & { timestamp: number },
|
||||
isSync: boolean = false,
|
||||
isSync = false,
|
||||
) {
|
||||
if (!this.iframe.contentDocument) {
|
||||
return console.warn('Looks like your replayer has been destroyed.');
|
||||
@@ -731,7 +731,7 @@ export class Replayer {
|
||||
);
|
||||
}
|
||||
if (this.usingVirtualDom) {
|
||||
const styleEl = this.virtualDom.createElement('style') as RRStyleElement;
|
||||
const styleEl = this.virtualDom.createElement('style') ;
|
||||
this.virtualDom.mirror.add(
|
||||
styleEl,
|
||||
getDefaultSN(styleEl, this.virtualDom.unserializedId),
|
||||
@@ -752,7 +752,7 @@ export class Replayer {
|
||||
head as HTMLHeadElement,
|
||||
);
|
||||
for (let idx = 0; idx < injectStylesRules.length; idx++) {
|
||||
(styleEl.sheet! as CSSStyleSheet).insertRule(
|
||||
(styleEl.sheet! ).insertRule(
|
||||
injectStylesRules[idx],
|
||||
idx,
|
||||
);
|
||||
@@ -1210,7 +1210,7 @@ export class Replayer {
|
||||
if (!target) {
|
||||
return this.debugNodeNotFound(d, d.id);
|
||||
}
|
||||
const styleSheet = ((target as Node) as HTMLStyleElement).sheet!;
|
||||
const styleSheet = ((target ) as HTMLStyleElement).sheet!;
|
||||
d.adds?.forEach(({ rule, index: nestedIndex }) => {
|
||||
try {
|
||||
if (Array.isArray(nestedIndex)) {
|
||||
@@ -1383,7 +1383,7 @@ export class Replayer {
|
||||
type TNode = typeof mirror extends Mirror ? Node : RRNode;
|
||||
|
||||
d.removes.forEach((mutation) => {
|
||||
let target = mirror.getNode(mutation.id);
|
||||
const target = mirror.getNode(mutation.id);
|
||||
if (!target) {
|
||||
if (d.removes.find((r) => r.id === mutation.parentId)) {
|
||||
// no need to warn, parent was already removed
|
||||
@@ -1612,7 +1612,7 @@ export class Replayer {
|
||||
appendNode(mutation);
|
||||
});
|
||||
|
||||
let startTime = Date.now();
|
||||
const startTime = Date.now();
|
||||
while (queue.length) {
|
||||
// transform queue to resolve tree
|
||||
const resolveTrees = queueToResolveTrees(queue);
|
||||
@@ -1625,7 +1625,7 @@ export class Replayer {
|
||||
break;
|
||||
}
|
||||
for (const tree of resolveTrees) {
|
||||
let parent = mirror.getNode(tree.value.parentId);
|
||||
const parent = mirror.getNode(tree.value.parentId);
|
||||
if (!parent) {
|
||||
this.debug(
|
||||
'Drop resolve tree since there is no parent for the root node.',
|
||||
@@ -1644,7 +1644,7 @@ export class Replayer {
|
||||
}
|
||||
|
||||
uniqueTextMutations(d.texts).forEach((mutation) => {
|
||||
let target = mirror.getNode(mutation.id);
|
||||
const target = mirror.getNode(mutation.id);
|
||||
if (!target) {
|
||||
if (d.removes.find((r) => r.id === mutation.id)) {
|
||||
// no need to warn, element was already removed
|
||||
@@ -1664,7 +1664,7 @@ export class Replayer {
|
||||
}
|
||||
});
|
||||
d.attributes.forEach((mutation) => {
|
||||
let target = mirror.getNode(mutation.id);
|
||||
const target = mirror.getNode(mutation.id);
|
||||
if (!target) {
|
||||
if (d.removes.find((r) => r.id === mutation.id)) {
|
||||
// no need to warn, element was already removed
|
||||
@@ -1692,9 +1692,9 @@ export class Replayer {
|
||||
}
|
||||
}
|
||||
} else if (attributeName === 'style') {
|
||||
let styleValues = value as styleAttributeValue;
|
||||
const styleValues = value ;
|
||||
const targetEl = target as HTMLElement | RRElement;
|
||||
for (var s in styleValues) {
|
||||
for (const s in styleValues) {
|
||||
if (styleValues[s] === false) {
|
||||
targetEl.style.removeProperty(s);
|
||||
} else if (styleValues[s] instanceof Array) {
|
||||
@@ -1772,7 +1772,7 @@ export class Replayer {
|
||||
const previousInMap = previousId && map[previousId];
|
||||
const nextInMap = nextId && map[nextId];
|
||||
if (previousInMap) {
|
||||
const { node, mutation } = previousInMap as missingNode;
|
||||
const { node, mutation } = previousInMap ;
|
||||
parent.insertBefore(node as Node & RRNode, target as Node & RRNode);
|
||||
delete map[mutation.node.id];
|
||||
delete this.legacy_missingNodeRetryMap[mutation.node.id];
|
||||
@@ -1781,7 +1781,7 @@ export class Replayer {
|
||||
}
|
||||
}
|
||||
if (nextInMap) {
|
||||
const { node, mutation } = nextInMap as missingNode;
|
||||
const { node, mutation } = nextInMap ;
|
||||
parent.insertBefore(
|
||||
node as Node & RRNode,
|
||||
target.nextSibling as Node & RRNode,
|
||||
|
||||
@@ -248,7 +248,7 @@ export function createPlayerService(
|
||||
let insertionIndex = -1;
|
||||
let start = 0;
|
||||
while (start <= end) {
|
||||
let mid = Math.floor((start + end) / 2);
|
||||
const mid = Math.floor((start + end) / 2);
|
||||
if (events[mid].timestamp <= event.timestamp) {
|
||||
start = mid + 1;
|
||||
} else {
|
||||
|
||||
@@ -15,11 +15,11 @@ export function polyfill(w: Window = window, d = document) {
|
||||
}
|
||||
|
||||
// globals
|
||||
var Element = w.HTMLElement || w.Element;
|
||||
var SCROLL_TIME = 468;
|
||||
const Element = w.HTMLElement || w.Element;
|
||||
const SCROLL_TIME = 468;
|
||||
|
||||
// object gathering original scroll methods
|
||||
var original = {
|
||||
const original = {
|
||||
scroll: w.scroll || w.scrollTo,
|
||||
scrollBy: w.scrollBy,
|
||||
elementScroll: Element.prototype.scroll || scrollElement,
|
||||
@@ -27,7 +27,7 @@ export function polyfill(w: Window = window, d = document) {
|
||||
};
|
||||
|
||||
// define timing method
|
||||
var now =
|
||||
const now =
|
||||
w.performance && w.performance.now
|
||||
? w.performance.now.bind(w.performance)
|
||||
: Date.now;
|
||||
@@ -39,7 +39,7 @@ export function polyfill(w: Window = window, d = document) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
function isMicrosoftBrowser(userAgent) {
|
||||
var userAgentPatterns = ['MSIE ', 'Trident/', 'Edge/'];
|
||||
const userAgentPatterns = ['MSIE ', 'Trident/', 'Edge/'];
|
||||
|
||||
return new RegExp(userAgentPatterns.join('|')).test(userAgent);
|
||||
}
|
||||
@@ -49,7 +49,7 @@ export function polyfill(w: Window = window, d = document) {
|
||||
* rounding up scrollHeight and scrollWidth causing false positives
|
||||
* on hasScrollableSpace
|
||||
*/
|
||||
var ROUNDING_TOLERANCE = isMicrosoftBrowser(w.navigator.userAgent) ? 1 : 0;
|
||||
const ROUNDING_TOLERANCE = isMicrosoftBrowser(w.navigator.userAgent) ? 1 : 0;
|
||||
|
||||
/**
|
||||
* changes scroll position inside an element
|
||||
@@ -130,7 +130,7 @@ export function polyfill(w: Window = window, d = document) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
function canOverflow(el, axis) {
|
||||
var overflowValue = w.getComputedStyle(el, null)['overflow' + axis];
|
||||
const overflowValue = w.getComputedStyle(el, null)['overflow' + axis];
|
||||
|
||||
return overflowValue === 'auto' || overflowValue === 'scroll';
|
||||
}
|
||||
@@ -143,8 +143,8 @@ export function polyfill(w: Window = window, d = document) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
function isScrollable(el) {
|
||||
var isScrollableY = hasScrollableSpace(el, 'Y') && canOverflow(el, 'Y');
|
||||
var isScrollableX = hasScrollableSpace(el, 'X') && canOverflow(el, 'X');
|
||||
const isScrollableY = hasScrollableSpace(el, 'Y') && canOverflow(el, 'Y');
|
||||
const isScrollableX = hasScrollableSpace(el, 'X') && canOverflow(el, 'X');
|
||||
|
||||
return isScrollableY || isScrollableX;
|
||||
}
|
||||
@@ -170,11 +170,11 @@ export function polyfill(w: Window = window, d = document) {
|
||||
* @returns {undefined}
|
||||
*/
|
||||
function step(context) {
|
||||
var time = now();
|
||||
var value;
|
||||
var currentX;
|
||||
var currentY;
|
||||
var elapsed = (time - context.startTime) / SCROLL_TIME;
|
||||
const time = now();
|
||||
let value;
|
||||
let currentX;
|
||||
let currentY;
|
||||
let elapsed = (time - context.startTime) / SCROLL_TIME;
|
||||
|
||||
// avoid elapsed times higher than one
|
||||
elapsed = elapsed > 1 ? 1 : elapsed;
|
||||
@@ -202,11 +202,11 @@ export function polyfill(w: Window = window, d = document) {
|
||||
* @returns {undefined}
|
||||
*/
|
||||
function smoothScroll(el, x, y) {
|
||||
var scrollable;
|
||||
var startX;
|
||||
var startY;
|
||||
var method;
|
||||
var startTime = now();
|
||||
let scrollable;
|
||||
let startX;
|
||||
let startY;
|
||||
let method;
|
||||
const startTime = now();
|
||||
|
||||
// define scroll context
|
||||
if (el === d.body) {
|
||||
@@ -342,8 +342,8 @@ export function polyfill(w: Window = window, d = document) {
|
||||
return;
|
||||
}
|
||||
|
||||
var left = arguments[0].left;
|
||||
var top = arguments[0].top;
|
||||
const left = arguments[0].left;
|
||||
const top = arguments[0].top;
|
||||
|
||||
// LET THE SMOOTHNESS BEGIN!
|
||||
smoothScroll.call(
|
||||
@@ -396,9 +396,9 @@ export function polyfill(w: Window = window, d = document) {
|
||||
}
|
||||
|
||||
// LET THE SMOOTHNESS BEGIN!
|
||||
var scrollableParent = findScrollableParent(this);
|
||||
var parentRects = scrollableParent.getBoundingClientRect();
|
||||
var clientRects = this.getBoundingClientRect();
|
||||
const scrollableParent = findScrollableParent(this);
|
||||
const parentRects = scrollableParent.getBoundingClientRect();
|
||||
const clientRects = this.getBoundingClientRect();
|
||||
|
||||
if (scrollableParent !== d.body) {
|
||||
// reveal element inside parent
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
} from '../types';
|
||||
|
||||
export class Timer {
|
||||
public timeOffset: number = 0;
|
||||
public timeOffset = 0;
|
||||
public speed: number;
|
||||
|
||||
private actions: actionWithDelay[];
|
||||
@@ -83,7 +83,7 @@ export class Timer {
|
||||
let start = 0;
|
||||
let end = this.actions.length - 1;
|
||||
while (start <= end) {
|
||||
let mid = Math.floor((start + end) / 2);
|
||||
const mid = Math.floor((start + end) / 2);
|
||||
if (this.actions[mid].delay < action.delay) {
|
||||
start = mid + 1;
|
||||
} else if (this.actions[mid].delay > action.delay) {
|
||||
|
||||
@@ -70,15 +70,14 @@ export function throttle<T>(
|
||||
) {
|
||||
let timeout: ReturnType<typeof setTimeout> | null = null;
|
||||
let previous = 0;
|
||||
// tslint:disable-next-line: only-arrow-functions
|
||||
return function (arg: T) {
|
||||
let now = Date.now();
|
||||
const now = Date.now();
|
||||
if (!previous && options.leading === false) {
|
||||
previous = now;
|
||||
}
|
||||
let remaining = wait - (now - previous);
|
||||
let context = this;
|
||||
let args = arguments;
|
||||
const remaining = wait - (now - previous);
|
||||
const context = this;
|
||||
const args = arguments;
|
||||
if (remaining <= 0 || remaining > wait) {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
@@ -398,8 +397,7 @@ export function getNestedRule(
|
||||
return rule;
|
||||
} else {
|
||||
return getNestedRule(
|
||||
((rule as CSSGroupingRule).cssRules[position[1]] as CSSGroupingRule)
|
||||
.cssRules,
|
||||
(rule.cssRules[position[1]] as CSSGroupingRule).cssRules,
|
||||
position.slice(2),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"exclude": ["test"],
|
||||
"include": [
|
||||
"src",
|
||||
"scripts",
|
||||
"node_modules/@types/css-font-loading-module/index.d.ts",
|
||||
"node_modules/@types/jest-image-snapshot/index.d.ts"
|
||||
]
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": ["tslint:recommended"],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"no-any": true,
|
||||
"quotemark": [true, "single"],
|
||||
"ordered-imports": false,
|
||||
"object-literal-sort-keys": false,
|
||||
"no-unused-variable": true,
|
||||
"object-literal-key-quotes": false,
|
||||
"variable-name": [
|
||||
true,
|
||||
"ban-keywords",
|
||||
"check-format",
|
||||
"allow-leading-underscore"
|
||||
],
|
||||
"arrow-parens": false,
|
||||
"only-arrow-functions": false,
|
||||
"max-line-length": false,
|
||||
"no-empty": false,
|
||||
"max-classes-per-file": false,
|
||||
"semicolon": false,
|
||||
"trailing-comma": false,
|
||||
"curly": false,
|
||||
"no-namespace": false,
|
||||
"interface-name": false,
|
||||
"forin": false
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
||||
Reference in New Issue
Block a user