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:
Justin Halsall
2022-05-22 03:59:42 +02:00
committed by GitHub
parent a43d4e4255
commit 1355917e1b
44 changed files with 2505 additions and 2249 deletions

View File

@@ -7,7 +7,8 @@
"bundle:es-only": "cross-env ES_ONLY=true rollup --config",
"check-types": "tsc -noEmit",
"test": "jest",
"prepublish": "npm run bundle"
"prepublish": "npm run bundle",
"lint": "yarn eslint src/**/*.ts"
},
"keywords": [
"rrweb",
@@ -32,7 +33,10 @@
"@types/jest": "^27.4.1",
"@types/nwsapi": "^2.2.2",
"@types/puppeteer": "^5.4.4",
"@typescript-eslint/eslint-plugin": "^5.23.0",
"@typescript-eslint/parser": "^5.23.0",
"compare-versions": "^4.1.3",
"eslint": "^8.15.0",
"jest": "^27.5.1",
"puppeteer": "^9.1.1",
"rollup": "^2.56.3",

View File

@@ -107,20 +107,21 @@ export function diff(
let inputDataToApply = null,
scrollDataToApply = null;
switch (newTree.RRNodeType) {
case RRNodeType.Document:
case RRNodeType.Document: {
const newRRDocument = newTree as IRRDocument;
scrollDataToApply = (newRRDocument as RRDocument).scrollData;
break;
case RRNodeType.Element:
const oldElement = (oldTree as Node) as HTMLElement;
}
case RRNodeType.Element: {
const oldElement = (oldTree ) as HTMLElement;
const newRRElement = newTree as IRRElement;
diffProps(oldElement, newRRElement, rrnodeMirror);
scrollDataToApply = (newRRElement as RRElement).scrollData;
inputDataToApply = (newRRElement as RRElement).inputData;
switch (newRRElement.tagName) {
case 'AUDIO':
case 'VIDEO':
const oldMediaElement = (oldTree as Node) as HTMLMediaElement;
case 'VIDEO': {
const oldMediaElement = (oldTree ) as HTMLMediaElement;
const newMediaRRElement = newRRElement as RRMediaElement;
if (newMediaRRElement.paused !== undefined)
newMediaRRElement.paused
@@ -133,13 +134,14 @@ export function diff(
if (newMediaRRElement.currentTime !== undefined)
oldMediaElement.currentTime = newMediaRRElement.currentTime;
break;
}
case 'CANVAS':
(newTree as RRCanvasElement).canvasMutations.forEach(
(canvasMutation) =>
replayer.applyCanvas(
canvasMutation.event,
canvasMutation.mutation,
(oldTree as Node) as HTMLCanvasElement,
(oldTree ) as HTMLCanvasElement,
),
);
break;
@@ -164,6 +166,7 @@ export function diff(
);
}
break;
}
case RRNodeType.Text:
case RRNodeType.Comment:
case RRNodeType.CDATA:
@@ -188,7 +191,7 @@ export function diff(
// IFrame element doesn't have child nodes.
if (newTree.nodeName === 'IFRAME') {
const oldContentDocument = ((oldTree as Node) as HTMLIFrameElement)
const oldContentDocument = ((oldTree ) as HTMLIFrameElement)
.contentDocument;
const newIFrameElement = newTree as RRIFrameElement;
// If the iframe is cross-origin, the contentDocument will be null.
@@ -316,10 +319,10 @@ function diffChildren(
if (
replayer.mirror.getMeta(parentNode)?.type === RRNodeType.Document &&
replayer.mirror.getMeta(newNode)?.type === RRNodeType.Element &&
((parentNode as Node) as Document).documentElement
((parentNode ) as Document).documentElement
) {
parentNode.removeChild(
((parentNode as Node) as Document).documentElement,
((parentNode ) as Document).documentElement,
);
oldChildren[oldStartIndex] = undefined;
oldStartNode = undefined;
@@ -379,7 +382,7 @@ export function createOrGetNode(
(rrNode as IRRDocumentType).systemId,
);
break;
case RRNodeType.Element:
case RRNodeType.Element: {
let tagName = (rrNode as IRRElement).tagName.toLowerCase();
tagName = SVGTagMap[tagName] || tagName;
if (sn && 'isSVG' in sn && sn?.isSVG) {
@@ -389,6 +392,7 @@ export function createOrGetNode(
);
} else node = document.createElement((rrNode as IRRElement).tagName);
break;
}
case RRNodeType.Text:
node = document.createTextNode((rrNode as IRRText).data);
break;
@@ -413,7 +417,7 @@ export function getNestedRule(
return rule;
} else {
return getNestedRule(
((rule as CSSGroupingRule).cssRules[position[1]] as CSSGroupingRule)
((rule ).cssRules[position[1]] as CSSGroupingRule)
.cssRules,
position.slice(2),
);

View File

@@ -70,7 +70,7 @@ export class RRDocument
}
get firstElementChild(): RRElement | null {
return this.documentElement as RRElement | null;
return this.documentElement;
}
appendChild(childNode: RRNode) {
@@ -87,21 +87,19 @@ export class RRDocument
getElementsByTagName(tagName: string): RRElement[] {
if (this.documentElement)
return (this.documentElement as RRElement).getElementsByTagName(tagName);
return this.documentElement.getElementsByTagName(tagName);
return [];
}
getElementsByClassName(className: string): RRElement[] {
if (this.documentElement)
return (this.documentElement as RRElement).getElementsByClassName(
className,
);
return this.documentElement.getElementsByClassName(className);
return [];
}
getElementById(elementId: string): RRElement | null {
if (this.documentElement)
return (this.documentElement as RRElement).getElementById(elementId);
return this.documentElement.getElementById(elementId);
return null;
}
@@ -217,7 +215,7 @@ export class RRElement extends BaseRRElementImpl(RRNode) {
}
getAttribute(name: string) {
let upperName = name && name.toLowerCase();
const upperName = name && name.toLowerCase();
if (upperName in this.attributes) return this.attributes[upperName];
return null;
}
@@ -231,16 +229,16 @@ export class RRElement extends BaseRRElementImpl(RRNode) {
}
get firstElementChild(): RRElement | null {
for (let child of this.childNodes)
for (const child of this.childNodes)
if (child.RRNodeType === RRNodeType.Element) return child as RRElement;
return null;
}
get nextElementSibling(): RRElement | null {
let parentNode = this.parentNode;
const parentNode = this.parentNode;
if (!parentNode) return null;
const siblings = parentNode.childNodes;
let index = siblings.indexOf(this);
const index = siblings.indexOf(this);
for (let i = index + 1; i < siblings.length; i++)
if (siblings[i] instanceof RRElement) return siblings[i] as RRElement;
return null;
@@ -327,7 +325,7 @@ export class RRStyleElement extends RRElement {
get sheet() {
if (!this._sheet) {
let result = '';
for (let child of this.childNodes)
for (const child of this.childNodes)
if (child.RRNodeType === RRNodeType.Text)
result += (child as RRText).textContent;
this._sheet = cssom.parse(result);
@@ -337,9 +335,9 @@ export class RRStyleElement extends RRElement {
}
export class RRIFrameElement extends RRElement {
width: string = '';
height: string = '';
src: string = '';
width = '';
height = '';
src = '';
contentDocument: RRDocument = new RRDocument();
contentWindow: RRWindow = new RRWindow();

View File

@@ -118,7 +118,9 @@ export interface IRRCDATASection extends IRRNode {
data: string;
}
type ConstrainedConstructor<T = {}> = new (...args: any[]) => T;
type ConstrainedConstructor<T = Record<string, unknown>> = new (
...args: any[]
) => T;
/**
* This is designed as an abstract class so it should never be instantiated.
@@ -136,7 +138,9 @@ export class BaseRRNode implements IRRNode {
public readonly nodeName: string;
public readonly RRNodeType: RRNodeType;
constructor(...args: any[]) {}
constructor(...args: any[]) {
//
}
public get firstChild(): IRRNode | null {
return this.childNodes[0] || null;
@@ -147,10 +151,10 @@ export class BaseRRNode implements IRRNode {
}
public get nextSibling(): IRRNode | null {
let parentNode = this.parentNode;
const parentNode = this.parentNode;
if (!parentNode) return null;
const siblings = parentNode.childNodes;
let index = siblings.indexOf(this);
const index = siblings.indexOf(this);
return siblings[index + 1] || null;
}
@@ -295,7 +299,9 @@ export function BaseRRDocumentImpl<
this.childNodes = [];
}
public close() {}
public close() {
//
}
/**
* Adhoc implementation for setting xhtml namespace in rebuilt.ts (rrweb-snapshot).
@@ -381,6 +387,7 @@ export function BaseRRDocumentImpl<
export function BaseRRDocumentTypeImpl<
RRNode extends ConstrainedConstructor<IRRNode>
>(RRNodeClass: RRNode) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return class BaseRRDocumentType
extends RRNodeClass
@@ -410,6 +417,7 @@ export function BaseRRDocumentTypeImpl<
export function BaseRRElementImpl<
RRNode extends ConstrainedConstructor<IRRNode>
>(RRNodeClass: RRNode) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return class BaseRRElement extends RRNodeClass implements IRRElement {
public readonly nodeType: number = NodeType.ELEMENT_NODE;
@@ -456,7 +464,7 @@ export function BaseRRElementImpl<
public get style() {
const style = (this.attributes.style
? parseCSSText(this.attributes.style as string)
? parseCSSText(this.attributes.style)
: {}) as CSSStyleDeclaration;
const hyphenateRE = /\B([A-Z])/g;
style.setProperty = (
@@ -546,7 +554,7 @@ export function BaseRRElementImpl<
toString() {
let attributeString = '';
for (let attribute in this.attributes) {
for (const attribute in this.attributes) {
attributeString += `${attribute}="${this.attributes[attribute]}" `;
}
return `${this.tagName} ${attributeString}`;
@@ -579,6 +587,7 @@ export function BaseRRMediaElementImpl<
export function BaseRRTextImpl<RRNode extends ConstrainedConstructor<IRRNode>>(
RRNodeClass: RRNode,
) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return class BaseRRText extends RRNodeClass implements IRRText {
public readonly nodeType: number = NodeType.TEXT_NODE;
@@ -608,6 +617,7 @@ export function BaseRRTextImpl<RRNode extends ConstrainedConstructor<IRRNode>>(
export function BaseRRCommentImpl<
RRNode extends ConstrainedConstructor<IRRNode>
>(RRNodeClass: RRNode) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return class BaseRRComment extends RRNodeClass implements IRRComment {
public readonly nodeType: number = NodeType.COMMENT_NODE;
@@ -637,6 +647,7 @@ export function BaseRRCommentImpl<
export function BaseRRCDATASectionImpl<
RRNode extends ConstrainedConstructor<IRRNode>
>(RRNodeClass: RRNode) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return class BaseRRCDATASection
extends RRNodeClass

View File

@@ -17,7 +17,7 @@ export function parseCSSText(cssText: string): Record<string, string> {
export function toCSSText(style: Record<string, string>): string {
const properties = [];
for (let name in style) {
for (const name in style) {
const value = style[name];
if (typeof value !== 'string') continue;
const normalizedName = hyphenate(name);

View File

@@ -226,7 +226,7 @@ export function buildFromNode(
}
break;
case NodeType.DOCUMENT_TYPE_NODE:
const documentType = (node as Node) as DocumentType;
const documentType = (node ) as DocumentType;
rrNode = rrdom.createDocumentType(
documentType.name,
documentType.publicId,
@@ -234,7 +234,7 @@ export function buildFromNode(
);
break;
case NodeType.ELEMENT_NODE:
const elementNode = (node as Node) as HTMLElement;
const elementNode = (node ) as HTMLElement;
const tagName = getValidTagName(elementNode);
rrNode = rrdom.createElement(tagName);
const rrElement = rrNode as IRRElement;
@@ -249,14 +249,14 @@ export function buildFromNode(
*/
break;
case NodeType.TEXT_NODE:
rrNode = rrdom.createTextNode(((node as Node) as Text).textContent || '');
rrNode = rrdom.createTextNode(((node ) as Text).textContent || '');
break;
case NodeType.CDATA_SECTION_NODE:
rrNode = rrdom.createCDATASection(((node as Node) as CDATASection).data);
rrNode = rrdom.createCDATASection(((node ) as CDATASection).data);
break;
case NodeType.COMMENT_NODE:
rrNode = rrdom.createComment(
((node as Node) as Comment).textContent || '',
((node ) as Comment).textContent || '',
);
break;
// if node is a shadow root
@@ -316,9 +316,9 @@ export function buildFromDom(
// if the node is a shadow dom
if (
node.nodeType === NodeType.ELEMENT_NODE &&
((node as Node) as HTMLElement).shadowRoot
((node ) as HTMLElement).shadowRoot
)
walk(((node as Node) as HTMLElement).shadowRoot!, rrNode);
walk(((node ) as HTMLElement).shadowRoot!, rrNode);
node.childNodes.forEach((childNode) => walk(childNode, rrNode));
}
}

View File

@@ -1,25 +1,22 @@
{
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2019,
"sourceType": "module"
},
"extends": ["../../.eslintrc.js"],
"rules": {
"require-jsdoc": "off",
"arrow-parens": "off",
"object-curly-spacing": "off",
"indent": "off"
},
"env": {
"es6": true,
"browser": true
"parserOptions": {
"extraFileExtensions": [".svelte"]
},
"plugins": ["svelte3", "@typescript-eslint"],
"plugins": ["svelte3"],
"overrides": [
{
"files": ["*.svelte"],
"processor": "svelte3/svelte3"
}
]
],
"settings": {
"svelte3/typescript": true
}
}

View File

@@ -6,11 +6,8 @@
"@rollup/plugin-node-resolve": "^13.2.1",
"@rollup/plugin-typescript": "^8.3.2",
"@types/offscreencanvas": "^2019.6.4",
"@typescript-eslint/eslint-plugin": "^3.7.0",
"@typescript-eslint/parser": "^3.7.0",
"eslint": "^7.5.0",
"eslint-config-google": "^0.11.0",
"eslint-plugin-svelte3": "^2.7.3",
"eslint-config-google": "^0.14.0",
"eslint-plugin-svelte3": "^4.0.0",
"postcss-easy-import": "^3.0.0",
"rollup": "^2.71.1",
"rollup-plugin-css-only": "^3.1.0",
@@ -35,7 +32,8 @@
"prepublishOnly": "yarn build",
"start": "sirv public",
"validate": "svelte-check",
"prepublish": "yarn build"
"prepublish": "yarn build",
"lint": "yarn eslint src/**/*.ts"
},
"description": "rrweb's replayer UI",
"main": "lib/index.js",

View File

@@ -186,20 +186,20 @@
};
export const triggerUpdateMeta = () => {
Promise.resolve().then(() => {
return Promise.resolve().then(() => {
meta = replayer.getMetaData();
})
}
onMount(() => {
playerState = replayer.service.state.value as typeof playerState;
speedState = replayer.speedService.state.value as typeof speedState;
playerState = replayer.service.state.value;
speedState = replayer.speedService.state.value ;
replayer.on(
'state-change',
(states: { player?: PlayerMachineState; speed?: SpeedMachineState }) => {
const { player, speed } = states;
if (player?.value && playerState !== player.value) {
playerState = player.value as typeof playerState;
playerState = player.value ;
switch (playerState) {
case 'playing':
loopTimer();
@@ -212,7 +212,7 @@
}
}
if (speed?.value && speedState !== speed.value) {
speedState = speed.value as typeof speedState;
speedState = speed.value ;
}
},
);
@@ -338,7 +338,7 @@
class="rr-progress"
class:disabled={speedState === 'skipping'}
bind:this={progress}
on:click={(event) => handleProgressClick(event)}>
on:click={handleProgressClick}>
<div
class="rr-progress__step"
bind:this={step}

View File

@@ -12,14 +12,14 @@
} from './utils';
import Controller from './Controller.svelte';
export let width: number = 1024;
export let height: number = 576;
export let width = 1024;
export let height = 576;
export let events: eventWithTime[] = [];
export let skipInactive: boolean = true;
export let autoPlay: boolean = true;
export let skipInactive = true;
export let autoPlay = true;
export let speedOption: number[] = [1, 2, 4, 8];
export let speed: number = 1;
export let showController: boolean = true;
export let speed = 1;
export let showController = true;
export let tags: Record<string, string> = {};
let replayer: Replayer;

View File

@@ -28,7 +28,7 @@ function padZero(num: number, len = 2): string {
const threshold = Math.pow(10, len - 1);
if (num < threshold) {
while (String(threshold).length > str.length) {
str = '0' + num;
str = `0${num}`;
}
}
return str;

View File

@@ -11,7 +11,8 @@
"bundle:es-only": "cross-env ES_ONLY=true rollup --config",
"dev": "yarn bundle:es-only --watch",
"typings": "tsc -d --declarationDir typings",
"prepublish": "npm run typings && npm run bundle"
"prepublish": "npm run typings && npm run bundle",
"lint": "yarn eslint src"
},
"repository": {
"type": "git",
@@ -55,7 +56,6 @@
"ts-jest": "^27.0.5",
"ts-node": "^7.0.1",
"tslib": "^1.9.3",
"tslint": "^4.5.1",
"typescript": "^3.9.7"
}
}

View File

@@ -242,7 +242,7 @@ export function parse(css: string, options: ParserOptions = {}) {
if (lines) {
lineno += lines.length;
}
let i = str.lastIndexOf('\n');
const i = str.lastIndexOf('\n');
column = i === -1 ? column + str.length : str.length - i;
}
@@ -457,7 +457,7 @@ export function parse(css: string, options: ParserOptions = {}) {
const pos = position();
// prop
let propMatch = match(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/);
const propMatch = match(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/);
if (!propMatch) {
return;
}

View File

@@ -148,7 +148,8 @@ function buildNode(
}
let value = n.attributes[name];
if (tagName === 'option' && name === 'selected' && value === false) {
// legacy fix (TODO: if `value === false` can be generated for other attrs, should we also omit those other attrs from build?)
// legacy fix (TODO: if `value === false` can be generated for other attrs,
// should we also omit those other attrs from build ?)
continue;
}
value =

View File

@@ -154,7 +154,7 @@ function getAbsoluteSrcsetString(doc: Document, attributeValue: string) {
function collectCharacters(regEx: RegExp) {
let chars: string;
let match = regEx.exec(attributeValue.substring(pos));
const match = regEx.exec(attributeValue.substring(pos));
if (match) {
chars = match[0];
pos += chars.length;
@@ -163,7 +163,7 @@ function getAbsoluteSrcsetString(doc: Document, attributeValue: string) {
return '';
}
let output = [];
const output = [];
while (true) {
collectCharacters(SRCSET_COMMAS_OR_SPACES);
if (pos >= attributeValue.length) {
@@ -182,7 +182,7 @@ function getAbsoluteSrcsetString(doc: Document, attributeValue: string) {
url = absoluteToDoc(doc, url);
let inParens = false;
while (true) {
let c = attributeValue.charAt(pos);
const c = attributeValue.charAt(pos);
if (c === '') {
output.push((url + descriptorsStr).trim());
break;
@@ -462,7 +462,7 @@ function serializeNode(
});
let cssText: string | null = null;
if (stylesheet) {
cssText = getCssRulesString(stylesheet as CSSStyleSheet);
cssText = getCssRulesString(stylesheet );
}
if (cssText) {
delete attributes.rel;

View File

@@ -1,21 +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
},
"rulesDirectory": []
}

View File

@@ -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": {

View File

@@ -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) => {

View File

@@ -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);

View File

@@ -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));
};
}

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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]);
};

View File

@@ -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;

View File

@@ -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[] =

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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

View File

@@ -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) {

View File

@@ -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),
);
}

View File

@@ -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"
]

View File

@@ -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": []
}