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
2026-04-01 12:00:00 +08:00
committed by GitHub
parent 4cfd9db6cf
commit 99e158bd39
44 changed files with 2505 additions and 2249 deletions

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