Commit c2990b58 authored by David Sveningsson's avatar David Sveningsson
Browse files

feat(event): new event config:ready

parent b44567b6
Loading
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -5,6 +5,17 @@

# Events

## `config:ready`

```typescript
{
  config: ConfigData;
  rules: { [ruleId: string]: Rule };
}
```

Emitted after after configuration is ready but before DOM is initialized.

## `dom:load`

```typescript
+7 −3
Original line number Diff line number Diff line
@@ -240,9 +240,13 @@ export class Config {
	public get(): ConfigData {
		const config = Object.assign({}, this.config);
		if (config.elements) {
			config.elements = config.elements.map((cur: string) =>
				cur.replace(this.rootDir, "<rootDir>")
			);
			config.elements = config.elements.map((cur: string | object) => {
				if (typeof cur === "string") {
					return cur.replace(this.rootDir, "<rootDir>");
				} else {
					return cur;
				}
			});
		}
		return config;
	}
+16 −6
Original line number Diff line number Diff line
@@ -37,11 +37,6 @@ class MockParser extends Parser {
				return super.parseHtml(source);
		}
	}

	/* exposed for testing */
	public trigger(event: any, data: any): void {
		return super.trigger(event, data);
	}
}

class ExposedEngine<T extends Parser> extends Engine<T> {
@@ -113,6 +108,21 @@ describe("Engine", () => {
			expect(report).toBeInvalid();
			expect(report).toHaveError("close-order", expect.any(String));
		});

		it("should generate config:ready event", () => {
			const source: Source[] = [inline("<div></div>")];
			const parser = new Parser(config);
			const spy = jest.fn();
			parser.on("config:ready", spy);
			jest.spyOn(engine, "instantiateParser").mockReturnValue(parser);
			engine.lint(source);
			expect(spy).toHaveBeenCalledTimes(1);
			expect(spy).toHaveBeenCalledWith("config:ready", {
				location: null,
				config: config.get(),
				rules: expect.anything(),
			});
		});
	});

	describe("directive", () => {
@@ -368,7 +378,7 @@ describe("Engine", () => {
				engine.requireRule = jest.fn(() => null);
				engine.loadRule("void", Severity.ERROR, {}, parser, reporter);
				const add = jest.spyOn(reporter, "add");
				parser.trigger("dom:load", { location: {} });
				parser.trigger("dom:load", { location: null });
				expect(add).toHaveBeenCalledWith(
					expect.any(Rule),
					"Definition for rule 'void' was not found",
+24 −2
Original line number Diff line number Diff line
import { Config, Severity } from "../config";
import { Location, Source } from "../context";
import { HtmlElement } from "../dom";
import { DirectiveEvent, TagCloseEvent, TagOpenEvent } from "../event";
import {
	ConfigReadyEvent,
	DirectiveEvent,
	TagCloseEvent,
	TagOpenEvent,
} from "../event";
import { InvalidTokenError, Lexer, TokenType } from "../lexer";
import { Parser } from "../parser";
import { Report, Reporter } from "../reporter";
@@ -45,11 +50,19 @@ export class Engine<T extends Parser = Parser> {
	public lint(sources: Source[]): Report {
		for (const source of sources) {
			/* create parser for source */
			const parser = new this.ParserClass(this.config);
			const parser = this.instantiateParser();

			/* setup plugins and rules */
			const { rules } = this.setupPlugins(source, this.config, parser);

			/* trigger configuration ready event */
			const event: ConfigReadyEvent = {
				location: null,
				config: this.config.get(),
				rules,
			};
			parser.trigger("config:ready", event);

			/* setup directive handling */
			parser.on("directive", (_: string, event: DirectiveEvent) => {
				this.processDirective(event, parser, rules);
@@ -154,6 +167,15 @@ export class Engine<T extends Parser = Parser> {
		}
	}

	/**
	 * Create a new parser instance with the current configuration.
	 *
	 * @hidden
	 */
	public instantiateParser(): Parser {
		return new this.ParserClass(this.config);
	}

	private processDirective(
		event: DirectiveEvent,
		parser: Parser,
+10 −0
Original line number Diff line number Diff line
import { ConfigData } from "../config";
import { Location } from "../context";
import { DOMTree, DynamicValue, HtmlElement } from "../dom";
import { Rule } from "../rule";

/**
 * @hidden
@@ -9,6 +11,14 @@ export interface Event {
	location: Location;
}

/**
 * Configuration ready event.
 */
export interface ConfigReadyEvent extends Event {
	config: ConfigData;
	rules: { [ruleId: string]: Rule };
}

/**
 * Event emitted when opening tags are encountered.
 */
Loading