Skip to content

Commit

Permalink
refactor: Be stricter about imports (#485)
Browse files Browse the repository at this point in the history
  • Loading branch information
fb55 committed Apr 10, 2022
1 parent cf0770f commit 8e22fe4
Show file tree
Hide file tree
Showing 47 changed files with 321 additions and 292 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.json
Expand Up @@ -47,6 +47,8 @@
"@typescript-eslint/no-non-null-assertion": "warn",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/explicit-function-return-type": "error",
"@typescript-eslint/no-duplicate-imports": "error",
"@typescript-eslint/consistent-type-imports": "error",

"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
}
Expand Down
2 changes: 1 addition & 1 deletion bench/memory/sax-parser.js
@@ -1,7 +1,7 @@
import { readFile } from 'node:fs/promises';
import format from 'human-format';
import memwatch from '@airbnb/node-memwatch';
import { SAXParser } from 'parse5-sax-parser/dist/index.js';
import { SAXParser } from '../../packages/parse5-sax-parser/dist/index.js';
import { finished } from 'parse5-test-utils/dist/common.js';

main();
Expand Down
18 changes: 13 additions & 5 deletions packages/parse5-html-rewriting-stream/lib/index.ts
@@ -1,7 +1,14 @@
import { html, type Token } from 'parse5';
import {
SAXParser,
type EndTag,
type StartTag,
type Doctype,
type Text,
type Comment,
type SaxToken,
} from 'parse5-sax-parser';
import { escapeText, escapeAttribute } from 'entities';
import type { Location } from 'parse5/dist/common/token.js';
import { SAXParser, EndTag, StartTag, Doctype, Text, Comment, SaxToken } from 'parse5-sax-parser';
import { hasUnescapedText } from 'parse5/dist/serializer/index.js';

/**
* Streaming [SAX](https://en.wikipedia.org/wiki/Simple_API_for_XML)-style HTML rewriter.
Expand Down Expand Up @@ -65,7 +72,7 @@ export class RewritingStream extends SAXParser {
return '';
}

private _getRawHtml(location: Location): string {
private _getRawHtml(location: Token.Location): string {
const { droppedBufferSize, html } = this.tokenizer.preprocessor;
const start = location.startOffset - droppedBufferSize;
const end = location.endOffset - droppedBufferSize;
Expand Down Expand Up @@ -130,7 +137,8 @@ export class RewritingStream extends SAXParser {
/** Emits a serialized text token into the output stream. */
public emitText({ text }: Text): void {
this.push(
!this.parserFeedbackSimulator.inForeignContent && hasUnescapedText(this.tokenizer.lastStartTagName, true)
!this.parserFeedbackSimulator.inForeignContent &&
html.hasUnescapedText(this.tokenizer.lastStartTagName, true)
? text
: escapeText(text)
);
Expand Down
4 changes: 3 additions & 1 deletion packages/parse5-html-rewriting-stream/package.json
Expand Up @@ -18,7 +18,9 @@
],
"license": "MIT",
"main": "dist/index.js",
"exports": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"exports": "./dist/index.js",
"dependencies": {
"entities": "^4.2.0",
"parse5": "^6.0.1",
Expand Down
Expand Up @@ -2,8 +2,12 @@ import * as assert from 'node:assert';
import { outdent } from 'outdent';
import { RewritingStream } from '../lib/index.js';
import { loadSAXParserTestData } from 'parse5-test-utils/utils/load-sax-parser-test-data.js';
import { getStringDiffMsg, writeChunkedToStream, WritableStreamStub } from 'parse5-test-utils/utils/common.js';
import { finished } from 'parse5-test-utils/utils/common.js';
import {
finished,
getStringDiffMsg,
writeChunkedToStream,
WritableStreamStub,
} from 'parse5-test-utils/utils/common.js';

const srcHtml = outdent`
<!DOCTYPE html "">
Expand Down
62 changes: 43 additions & 19 deletions packages/parse5-htmlparser2-tree-adapter/lib/index.ts
@@ -1,10 +1,7 @@
import * as doctype from 'parse5/dist/common/doctype.js';
import { DOCUMENT_MODE, NAMESPACES as NS } from 'parse5/dist/common/html.js';
import type { Attribute, ElementLocation } from 'parse5/dist/common/token.js';
import type { TreeAdapter, TreeAdapterTypeMap } from 'parse5/dist/tree-adapters/interface.js';
import { type TreeAdapterTypeMap, type TreeAdapter, type Token, html } from 'parse5';
import {
Node,
NodeWithChildren,
type Node,
type NodeWithChildren,
Element,
Document,
ProcessingInstruction,
Expand Down Expand Up @@ -33,6 +30,33 @@ function createTextNode(value: string): Text {
return new Text(value);
}

function enquoteDoctypeId(id: string): string {
const quote = id.includes('"') ? "'" : '"';

return quote + id + quote;
}

/** @internal */
export function serializeDoctypeContent(name: string, publicId: string, systemId: string): string {
let str = '!DOCTYPE ';

if (name) {
str += name;
}

if (publicId) {
str += ` PUBLIC ${enquoteDoctypeId(publicId)}`;
} else if (systemId) {
str += ' SYSTEM';
}

if (systemId) {
str += ` ${enquoteDoctypeId(systemId)}`;
}

return str;
}

export const adapter: TreeAdapter<Htmlparser2TreeAdapterMap> = {
// Re-exports from domhandler
isCommentNode: isComment,
Expand All @@ -42,15 +66,15 @@ export const adapter: TreeAdapter<Htmlparser2TreeAdapterMap> = {
//Node construction
createDocument(): Document {
const node = new Document([]);
node['x-mode'] = DOCUMENT_MODE.NO_QUIRKS;
node['x-mode'] = html.DOCUMENT_MODE.NO_QUIRKS;
return node;
},

createDocumentFragment(): Document {
return new Document([]);
},

createElement(tagName: string, namespaceURI: NS, attrs: Attribute[]): Element {
createElement(tagName: string, namespaceURI: html.NS, attrs: Token.Attribute[]): Element {
const attribs = Object.create(null);
const attribsNamespace = Object.create(null);
const attribsPrefix = Object.create(null);
Expand Down Expand Up @@ -112,7 +136,7 @@ export const adapter: TreeAdapter<Htmlparser2TreeAdapterMap> = {
},

setDocumentType(document: Document, name: string, publicId: string, systemId: string): void {
const data = doctype.serializeContent(name, publicId, systemId);
const data = serializeDoctypeContent(name, publicId, systemId);
let doctypeNode = document.children.find(
(node): node is ProcessingInstruction => isDirective(node) && node.name === '!doctype'
);
Expand All @@ -129,12 +153,12 @@ export const adapter: TreeAdapter<Htmlparser2TreeAdapterMap> = {
doctypeNode['x-systemId'] = systemId ?? undefined;
},

setDocumentMode(document: Document, mode: DOCUMENT_MODE): void {
setDocumentMode(document: Document, mode: html.DOCUMENT_MODE): void {
document['x-mode'] = mode;
},

getDocumentMode(document: Document): DOCUMENT_MODE {
return document['x-mode'] as DOCUMENT_MODE;
getDocumentMode(document: Document): html.DOCUMENT_MODE {
return document['x-mode'] as html.DOCUMENT_MODE;
},

detachNode(node: Node): void {
Expand Down Expand Up @@ -178,7 +202,7 @@ export const adapter: TreeAdapter<Htmlparser2TreeAdapterMap> = {
}
},

adoptAttributes(recipient: Element, attrs: Attribute[]): void {
adoptAttributes(recipient: Element, attrs: Token.Attribute[]): void {
for (let i = 0; i < attrs.length; i++) {
const attrName = attrs[i].name;

Expand All @@ -203,7 +227,7 @@ export const adapter: TreeAdapter<Htmlparser2TreeAdapterMap> = {
return node.parent;
},

getAttrList(element: Element): Attribute[] {
getAttrList(element: Element): Token.Attribute[] {
return element.attributes;
},

Expand All @@ -212,8 +236,8 @@ export const adapter: TreeAdapter<Htmlparser2TreeAdapterMap> = {
return element.name;
},

getNamespaceURI(element: Element): NS {
return element.namespace as NS;
getNamespaceURI(element: Element): html.NS {
return element.namespace as html.NS;
},

getTextNodeContent(textNode: Text): string {
Expand Down Expand Up @@ -243,7 +267,7 @@ export const adapter: TreeAdapter<Htmlparser2TreeAdapterMap> = {
},

// Source code location
setNodeSourceCodeLocation(node: Node, location: ElementLocation | null): void {
setNodeSourceCodeLocation(node: Node, location: Token.ElementLocation | null): void {
if (location) {
node.startIndex = location.startOffset;
node.endIndex = location.endOffset;
Expand All @@ -252,11 +276,11 @@ export const adapter: TreeAdapter<Htmlparser2TreeAdapterMap> = {
node.sourceCodeLocation = location;
},

getNodeSourceCodeLocation(node: Node): ElementLocation | null | undefined {
getNodeSourceCodeLocation(node: Node): Token.ElementLocation | null | undefined {
return node.sourceCodeLocation;
},

updateNodeSourceCodeLocation(node: Node, endLocation: ElementLocation): void {
updateNodeSourceCodeLocation(node: Node, endLocation: Token.ElementLocation): void {
if (endLocation.endOffset != null) node.endIndex = endLocation.endOffset;

node.sourceCodeLocation = {
Expand Down
3 changes: 3 additions & 0 deletions packages/parse5-htmlparser2-tree-adapter/package.json
Expand Up @@ -15,6 +15,9 @@
],
"license": "MIT",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"exports": "./dist/index.js",
"dependencies": {
"domhandler": "^4.3.1",
"parse5": "^6.0.1"
Expand Down
4 changes: 1 addition & 3 deletions packages/parse5-parser-stream/lib/index.ts
@@ -1,7 +1,5 @@
import { Writable } from 'node:stream';
import { Parser, ParserOptions } from 'parse5/dist/parser/index.js';
import type { TreeAdapterTypeMap } from 'parse5/dist/tree-adapters/interface.js';
import type { DefaultTreeAdapterMap } from 'parse5/dist/tree-adapters/default.js';
import { Parser, type ParserOptions, type TreeAdapterTypeMap, type DefaultTreeAdapterMap } from 'parse5';

/* eslint-disable unicorn/consistent-function-scoping -- The rule seems to be broken here. */

Expand Down
3 changes: 3 additions & 0 deletions packages/parse5-parser-stream/package.json
Expand Up @@ -15,6 +15,9 @@
],
"license": "MIT",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"exports": "./dist/index.js",
"dependencies": {
"parse5": "^6.0.1"
},
Expand Down
3 changes: 1 addition & 2 deletions packages/parse5-parser-stream/test/scripting.test.ts
@@ -1,8 +1,7 @@
import { ParserStream } from '../lib/index.js';
import { generateParsingTests } from 'parse5-test-utils/utils/generate-parsing-tests.js';
import { makeChunks, generateTestsForEachTreeAdapter } from 'parse5-test-utils/utils/common.js';
import { makeChunks, generateTestsForEachTreeAdapter, finished } from 'parse5-test-utils/utils/common.js';
import { runInNewContext } from 'node:vm';
import { finished } from 'parse5-test-utils/utils/common.js';

function pause(): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, 5));
Expand Down
3 changes: 1 addition & 2 deletions packages/parse5-parser-stream/test/utils/parse-chunked.ts
@@ -1,5 +1,4 @@
import type { ParserOptions } from 'parse5';
import type { TreeAdapterTypeMap } from 'parse5/dist/tree-adapters/interface.js';
import type { ParserOptions, TreeAdapterTypeMap } from 'parse5';
import { ParserStream } from '../../lib/index.js';
import { makeChunks } from 'parse5-test-utils/utils/common.js';

Expand Down
6 changes: 3 additions & 3 deletions packages/parse5-plain-text-conversion-stream/lib/index.ts
@@ -1,7 +1,7 @@
import type { ParserOptions } from 'parse5';
import { type ParserOptions, type TreeAdapterTypeMap, html } from 'parse5';
import { ParserStream } from 'parse5-parser-stream';
import { TAG_ID as $, TAG_NAMES as TN } from 'parse5/dist/common/html.js';
import type { TreeAdapterTypeMap } from 'parse5/dist/tree-adapters/interface.js';

const { TAG_ID: $, TAG_NAMES: TN } = html;

/**
* Converts plain text files into HTML document as required by [HTML specification](https://html.spec.whatwg.org/#read-text).
Expand Down
3 changes: 3 additions & 0 deletions packages/parse5-plain-text-conversion-stream/package.json
Expand Up @@ -18,6 +18,9 @@
],
"license": "MIT",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"exports": "./dist/index.js",
"dependencies": {
"parse5": "^6.0.1",
"parse5-parser-stream": "^6.0.1"
Expand Down
@@ -1,5 +1,5 @@
import * as assert from 'node:assert';
import * as parse5 from 'parse5';
import { serialize } from 'parse5';
import { PlainTextConversionStream } from '../lib/index.js';
import { generateTestsForEachTreeAdapter } from 'parse5-test-utils/utils/common.js';

Expand All @@ -12,7 +12,7 @@ generateTestsForEachTreeAdapter('plain-test-conversion-stream', (treeAdapter) =>
converter.write('\u0000');
converter.end('<html><head><body>');

const result = parse5.serialize(converter.document, { treeAdapter });
const result = serialize(converter.document, { treeAdapter });

assert.strictEqual(
result,
Expand Down
28 changes: 10 additions & 18 deletions packages/parse5-sax-parser/lib/index.ts
@@ -1,13 +1,5 @@
import { Transform } from 'node:stream';
import type { Tokenizer, TokenHandler } from 'parse5/dist/tokenizer/index.js';
import type {
Attribute,
Location,
TagToken,
CommentToken,
DoctypeToken,
CharacterToken,
} from 'parse5/dist/common/token.js';
import type { Tokenizer, TokenHandler, Token } from 'parse5';
import { DevNullStream } from './dev-null-stream.js';
import { ParserFeedbackSimulator } from './parser-feedback-simulator.js';

Expand Down Expand Up @@ -135,7 +127,7 @@ export class SAXParser extends Transform implements TokenHandler {
}

/** @internal */
onCharacter({ chars, location }: CharacterToken): void {
onCharacter({ chars, location }: Token.CharacterToken): void {
if (this.pendingText === null) {
this.pendingText = { text: chars, sourceCodeLocation: location };
} else {
Expand All @@ -158,12 +150,12 @@ export class SAXParser extends Transform implements TokenHandler {
}

/** @internal */
onWhitespaceCharacter(token: CharacterToken): void {
onWhitespaceCharacter(token: Token.CharacterToken): void {
this.onCharacter(token);
}

/** @internal */
onNullCharacter(token: CharacterToken): void {
onNullCharacter(token: Token.CharacterToken): void {
this.onCharacter(token);
}

Expand All @@ -174,7 +166,7 @@ export class SAXParser extends Transform implements TokenHandler {
}

/** @internal */
onStartTag(token: TagToken): void {
onStartTag(token: Token.TagToken): void {
this._emitPendingText();

const startTag: StartTag = {
Expand All @@ -187,7 +179,7 @@ export class SAXParser extends Transform implements TokenHandler {
}

/** @internal */
onEndTag(token: TagToken): void {
onEndTag(token: Token.TagToken): void {
this._emitPendingText();

const endTag: EndTag = {
Expand All @@ -198,7 +190,7 @@ export class SAXParser extends Transform implements TokenHandler {
}

/** @internal */
onDoctype(token: DoctypeToken): void {
onDoctype(token: Token.DoctypeToken): void {
this._emitPendingText();

const doctype: Doctype = {
Expand All @@ -211,7 +203,7 @@ export class SAXParser extends Transform implements TokenHandler {
}

/** @internal */
onComment(token: CommentToken): void {
onComment(token: Token.CommentToken): void {
this._emitPendingText();

const comment: Comment = {
Expand Down Expand Up @@ -245,14 +237,14 @@ export class SAXParser extends Transform implements TokenHandler {

export interface SaxToken {
/** Source code location info. Available if location info is enabled via {@link SAXParserOptions}. */
sourceCodeLocation?: Location | null;
sourceCodeLocation?: Token.Location | null;
}

export interface StartTag extends SaxToken {
/** Tag name */
tagName: string;
/** List of attributes */
attrs: Attribute[];
attrs: Token.Attribute[];
/** Indicates if the tag is self-closing */
selfClosing: boolean;
}
Expand Down

0 comments on commit 8e22fe4

Please sign in to comment.