...
 
Commits (12)
build/
node_modules/
public/assets/
......@@ -7,9 +7,6 @@
"@html-validate",
"plugin:array-func/recommended",
"plugin:node/recommended-module",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:import/typescript",
"plugin:security/recommended",
"plugin:sonarjs/recommended"
],
......
# html-validate changelog
# [2.16.0](https://gitlab.com/html-validate/html-validate/compare/v2.15.0...v2.16.0) (2020-02-12)
### Bug Fixes
- **cli:** fix typo when using `--init` with vuejs ([6eee478](https://gitlab.com/html-validate/html-validate/commit/6eee47872e164b16e4152f309ab5971019222ff9))
- **dom:** `querySelector` and friends return empty when selector is empty ([6a871de](https://gitlab.com/html-validate/html-validate/commit/6a871de7bb240507693d266b37c6e4f9228b7e5e))
- **schema:** add title and description to most properties ([a7cea78](https://gitlab.com/html-validate/html-validate/commit/a7cea78ed39643e5808cfd08243f492a235200e7))
- **schema:** handle `$schema` in config and elements ([a4f9054](https://gitlab.com/html-validate/html-validate/commit/a4f90541c74070f30d033827789336ad27063b3a))
- add missing `jest.js` and `jest.d.ts` ([8b767c2](https://gitlab.com/html-validate/html-validate/commit/8b767c2032297b8534c7feac98414fc4d90c5bd2))
### Features
- add import `html-validate/jest` as a shortcut to the jest matchers ([4ccf6ed](https://gitlab.com/html-validate/html-validate/commit/4ccf6ed6b1da47d44bb256db4156edbdbb1ddf4e))
- expose `NodeClosed`, `TextNode`, `Plugin` and `Parser` ([f344527](https://gitlab.com/html-validate/html-validate/commit/f3445274d4e713e2c851bd524ebb429da9408abb))
# [2.15.0](https://gitlab.com/html-validate/html-validate/compare/v2.14.0...v2.15.0) (2020-02-09)
### Features
......
const path = require("canonical-path");
const Package = require("dgeni").Package;
const packagePath = __dirname;
module.exports = new Package("html-validate-docs", [
......
/* eslint-disable @typescript-eslint/no-empty-function */
const path = require("canonical-path");
const packagePath = __dirname;
const Package = require("dgeni").Package;
......
......@@ -67,6 +67,7 @@ module.exports = function parseValidatesProcessor(
function readElements(fileInfo, filename) {
if (!filename) return filename;
const dir = path.dirname(fileInfo.filePath);
/* eslint-disable-next-line import/no-dynamic-require */
return require(`${dir}/${filename}`);
}
......
const chalk = require("chalk");
const HtmlValidate = require("../../../../build/htmlvalidate").default;
const codeframe = require("../../../../build/formatters/codeframe");
const chalk = require("chalk");
module.exports = function generateValidationResultsProcessor(log, validateMap) {
return {
......
const path = require("canonical-path");
const packagePath = __dirname;
const Package = require("dgeni").Package;
......
......@@ -7,10 +7,10 @@ title: Usage with Jest
`html-validate` comes with Jest support built-in.
In you test import `matchers`:
In you test import `html-validate/jest`:
```js
import "html-validate/build/matchers";
import "html-validate/jest";
```
This makes all the custom matchers available.
......@@ -50,6 +50,8 @@ If you need to override this (perhaps because the test-case isn't in the same fo
expect("<p></i>").toHTMLValidate(null, "path/to/my-file.html");
```
This can also be used to apply transformations to the markup.
Additionally, the `root` configuration property can be used to skip loading from `.htmlvalidate.json` but remember to actually include the rules you need:
```js
......
/* eslint-disable-next-line import/export, import/no-unresolved */
export * from "./build/matchers";
module.exports = require("./build/matchers");
{
"name": "html-validate",
"version": "2.15.0",
"version": "2.16.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
......@@ -1973,15 +1973,16 @@
}
},
"@html-validate/eslint-config": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@html-validate/eslint-config/-/eslint-config-1.0.9.tgz",
"integrity": "sha512-5SzmdQLGPgHJEVz2/IdCFWDwovISCdLG5PovYaXfLKQzWLSCXZktIhIJABHh53Z2FxVRI0EKl9ed2Rd1Z7pZQQ==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@html-validate/eslint-config/-/eslint-config-1.1.0.tgz",
"integrity": "sha512-H8ujPMr3n6U9XKGgJnSzH6CsXSLvu5LAOypGxXSX4Tj/hoSHg+cJRLwzoVSypkngxsINx7C5GMNOCP8ypcjR1g==",
"dev": true,
"requires": {
"@typescript-eslint/eslint-plugin": "^2.12.0",
"@typescript-eslint/parser": "^2.12.0",
"eslint-config-prettier": "^6.7.0",
"eslint-config-sidvind": "^1.3.2",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-jest": "^23.1.1",
"eslint-plugin-prettier": "^3.1.2"
}
......@@ -4180,12 +4181,12 @@
"dev": true
},
"@typescript-eslint/eslint-plugin": {
"version": "2.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.18.0.tgz",
"integrity": "sha512-kuO8WQjV+RCZvAXVRJfXWiJ8iYEtfHlKgcqqqXg9uUkIolEHuUaMmm8/lcO4xwCOtaw6mY0gStn2Lg4/eUXXYQ==",
"version": "2.19.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.19.2.tgz",
"integrity": "sha512-HX2qOq2GOV04HNrmKnTpSIpHjfl7iwdXe3u/Nvt+/cpmdvzYvY0NHSiTkYN257jHnq4OM/yo+OsFgati+7LqJA==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "2.18.0",
"@typescript-eslint/experimental-utils": "2.19.2",
"eslint-utils": "^1.4.3",
"functional-red-black-tree": "^1.0.1",
"regexpp": "^3.0.0",
......@@ -4193,20 +4194,20 @@
},
"dependencies": {
"@typescript-eslint/experimental-utils": {
"version": "2.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.18.0.tgz",
"integrity": "sha512-J6MopKPHuJYmQUkANLip7g9I82ZLe1naCbxZZW3O2sIxTiq/9YYoOELEKY7oPg0hJ0V/AQ225h2z0Yp+RRMXhw==",
"version": "2.19.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.19.2.tgz",
"integrity": "sha512-B88QuwT1wMJR750YvTJBNjMZwmiPpbmKYLm1yI7PCc3x0NariqPwqaPsoJRwU9DmUi0cd9dkhz1IqEnwfD+P1A==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.3",
"@typescript-eslint/typescript-estree": "2.18.0",
"@typescript-eslint/typescript-estree": "2.19.2",
"eslint-scope": "^5.0.0"
}
},
"@typescript-eslint/typescript-estree": {
"version": "2.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.18.0.tgz",
"integrity": "sha512-gVHylf7FDb8VSi2ypFuEL3hOtoC4HkZZ5dOjXvVjoyKdRrvXAOPSzpNRnKMfaUUEiSLP8UF9j9X9EDLxC0lfZg==",
"version": "2.19.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.19.2.tgz",
"integrity": "sha512-Xu/qa0MDk6upQWqE4Qy2X16Xg8Vi32tQS2PR0AvnT/ZYS4YGDvtn2MStOh5y8Zy2mg4NuL06KUHlvCh95j9C6Q==",
"dev": true,
"requires": {
"debug": "^4.1.1",
......@@ -4310,32 +4311,32 @@
}
},
"@typescript-eslint/parser": {
"version": "2.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.18.0.tgz",
"integrity": "sha512-SJJPxFMEYEWkM6pGfcnjLU+NJIPo+Ko1QrCBL+i0+zV30ggLD90huEmMMhKLHBpESWy9lVEeWlQibweNQzyc+A==",
"version": "2.19.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.19.2.tgz",
"integrity": "sha512-8uwnYGKqX9wWHGPGdLB9sk9+12sjcdqEEYKGgbS8A0IvYX59h01o8os5qXUHMq2na8vpDRaV0suTLM7S8wraTA==",
"dev": true,
"requires": {
"@types/eslint-visitor-keys": "^1.0.0",
"@typescript-eslint/experimental-utils": "2.18.0",
"@typescript-eslint/typescript-estree": "2.18.0",
"@typescript-eslint/experimental-utils": "2.19.2",
"@typescript-eslint/typescript-estree": "2.19.2",
"eslint-visitor-keys": "^1.1.0"
},
"dependencies": {
"@typescript-eslint/experimental-utils": {
"version": "2.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.18.0.tgz",
"integrity": "sha512-J6MopKPHuJYmQUkANLip7g9I82ZLe1naCbxZZW3O2sIxTiq/9YYoOELEKY7oPg0hJ0V/AQ225h2z0Yp+RRMXhw==",
"version": "2.19.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.19.2.tgz",
"integrity": "sha512-B88QuwT1wMJR750YvTJBNjMZwmiPpbmKYLm1yI7PCc3x0NariqPwqaPsoJRwU9DmUi0cd9dkhz1IqEnwfD+P1A==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.3",
"@typescript-eslint/typescript-estree": "2.18.0",
"@typescript-eslint/typescript-estree": "2.19.2",
"eslint-scope": "^5.0.0"
}
},
"@typescript-eslint/typescript-estree": {
"version": "2.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.18.0.tgz",
"integrity": "sha512-gVHylf7FDb8VSi2ypFuEL3hOtoC4HkZZ5dOjXvVjoyKdRrvXAOPSzpNRnKMfaUUEiSLP8UF9j9X9EDLxC0lfZg==",
"version": "2.19.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.19.2.tgz",
"integrity": "sha512-Xu/qa0MDk6upQWqE4Qy2X16Xg8Vi32tQS2PR0AvnT/ZYS4YGDvtn2MStOh5y8Zy2mg4NuL06KUHlvCh95j9C6Q==",
"dev": true,
"requires": {
"debug": "^4.1.1",
......@@ -8221,6 +8222,12 @@
"resolved": "https://registry.npmjs.org/espree/-/espree-2.2.5.tgz",
"integrity": "sha1-32kbkxCIlAKuspzAZnCMVmkLhUs=",
"dev": true
},
"marked": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz",
"integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==",
"dev": true
}
}
},
......@@ -15821,9 +15828,9 @@
}
},
"marked": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz",
"integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==",
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.8.0.tgz",
"integrity": "sha512-MyUe+T/Pw4TZufHkzAfDj6HarCBWia2y27/bhuYkTaiUnfDYFnCP3KUN+9oM7Wi6JA2rymtVYbQu3spE0GCmxQ==",
"dev": true
},
"marked-terminal": {
......
{
"name": "html-validate",
"version": "2.15.0",
"version": "2.16.0",
"description": "html linter",
"keywords": [
"html",
......@@ -29,6 +29,7 @@
"bin",
"build",
"elements",
"jest.{js,d.ts}",
"!*.snap",
"!*.spec.d.ts",
"!*.spec.js",
......@@ -43,8 +44,8 @@
"compatibility": "scripts/compatibility.sh",
"commitlint": "commitlint",
"debug": "node --inspect ./node_modules/.bin/jest --runInBand --watch --no-coverage",
"eslint": "eslint *.js '{docs,elements,src}/**/*.{js,ts}'",
"eslint:fix": "eslint --fix *.js '{docs,elements,src}/**/*.{js,ts}'",
"eslint": "eslint --ext js,ts .",
"eslint:fix": "eslint --ext js,ts . --fix",
"htmlvalidate": "./bin/html-validate.js",
"lint": "npm run eslint && npm run tslint",
"prettier:check": "prettier '**/*.{ts,js,json,md,scss}' --list-different",
......@@ -98,7 +99,7 @@
"@babel/preset-env": "7.8.4",
"@commitlint/cli": "8.3.5",
"@html-validate/commitlint-config": "1.0.1",
"@html-validate/eslint-config": "1.0.9",
"@html-validate/eslint-config": "1.1.0",
"@html-validate/prettier-config": "1.0.0",
"@html-validate/semantic-release-config": "1.0.8",
"@types/babel__code-frame": "7.0.1",
......@@ -118,8 +119,6 @@
"dgeni-front-matter": "1.0.2",
"dgeni-packages": "0.28.2",
"eslint-plugin-array-func": "3.1.3",
"eslint-plugin-import": "2.20.1",
"eslint-plugin-jest": "23.7.0",
"eslint-plugin-node": "11.0.0",
"eslint-plugin-security": "1.4.0",
"eslint-plugin-sonarjs": "0.5.0",
......@@ -140,11 +139,13 @@
"jquery": "3.4.1",
"lint-staged": "10.0.7",
"load-grunt-tasks": "5.1.0",
"marked": "0.8.0",
"minimatch": "3.0.4",
"prettier": "1.19.1",
"sass": "1.25.0",
"semantic-release": "17.0.2",
"serve-static": "1.14.1",
"stringmap": "0.2.2",
"strip-ansi": "6.0.0",
"ts-jest": "25.2.0",
"tslint": "5.20.1",
......
import path from "path";
let mockDirectory: string[] = [];
function setMockDirectories(directories: string[]): void {
......
......@@ -22,7 +22,7 @@ exports[`should generate configuration for combined 1`] = `
],
\\"extends\\": [
\\"html-validate:recommended\\",
\\"html-valudate-vue:recommended\\"
\\"html-validate-vue:recommended\\"
],
\\"transform\\": {
\\"^.*\\\\\\\\.js$\\": \\"html-validate-angular/js\\",
......@@ -68,7 +68,7 @@ exports[`should generate configuration for vuejs 1`] = `
],
\\"extends\\": [
\\"html-validate:recommended\\",
\\"html-valudate-vue:recommended\\"
\\"html-validate-vue:recommended\\"
],
\\"plugins\\": [
\\"html-validate-vue\\"
......
import fs from "fs";
import glob from "glob";
import path from "path";
import glob from "glob";
const DEFAULT_EXTENSIONS = ["html"];
......
......@@ -28,6 +28,7 @@ export function getFormatter(formatters: string): (report: Report) => string {
const fn: WrappedFormatter[] = formatters.split(",").map(cur => {
const [name, dst] = cur.split("=", 2);
const moduleName = name.replace(/[^a-z]+/g, "");
/* eslint-disable-next-line import/no-dynamic-require */
const formatter = require(`../formatters/${moduleName}`);
return wrap(formatter, dst);
});
......
/* eslint-disable no-console, no-process-exit, sonarjs/no-duplicate-string */
import path from "path";
import chalk from "chalk";
import minimist from "minimist";
import { TokenDump } from "../engine";
import { SchemaValidationError } from "../error";
import { UserError } from "../error/user-error";
import { Report, Reporter, Result } from "../reporter";
import { eventFormatter } from "./json";
const pkg = require("../../package.json");
import chalk from "chalk";
import minimist from "minimist";
import path from "path";
import { CLI } from "./cli";
const pkg = require("../../package.json");
enum Mode {
LINT,
INIT,
......
import { CLI } from "./cli";
export default CLI;
import deepmerge from "deepmerge";
import fs from "fs";
import deepmerge from "deepmerge";
import inquirer from "inquirer";
import { ConfigData } from "../config";
......@@ -22,7 +22,7 @@ const frameworkConfig: Record<string, ConfigData> = {
},
[Frameworks.vuejs]: {
plugins: ["html-validate-vue"],
extends: ["html-valudate-vue:recommended"],
extends: ["html-validate-vue:recommended"],
transform: {
"^.*\\.vue$": "html-validate-vue",
},
......
import fs from "fs";
import glob from "glob";
import path from "path";
import { Config, ConfigData, ConfigLoader, RuleConfig } from ".";
import glob from "glob";
import HtmlValidate from "../htmlvalidate";
import { Config, ConfigData, ConfigLoader, RuleConfig } from ".";
declare module "./config-data" {
interface ConfigData {
......
import Ajv from "ajv";
import deepmerge from "deepmerge";
import fs from "fs";
import path from "path";
import Ajv from "ajv";
import deepmerge from "deepmerge";
import { Source } from "../context";
import { NestedError, SchemaValidationError } from "../error";
import { MetaTable } from "../meta";
......@@ -30,10 +30,12 @@ interface LoadedPlugin extends Plugin {
const recommended = require("./recommended");
const document = require("./document");
let rootDirCache: string = null;
const ajv = new Ajv({ jsonPointers: true });
ajv.addMetaSchema(require("ajv/lib/refs/json-schema-draft-06.json"));
const validator = ajv.compile(schema);
function overwriteMerge<T>(a: T[], b: T[]): T[] {
......@@ -280,7 +282,7 @@ export class Config {
/* assume it is loadable with require() */
try {
// eslint-disable-next-line security/detect-non-literal-require
// eslint-disable-next-line security/detect-non-literal-require, import/no-dynamic-require
metaTable.loadFromObject(require(entry));
} catch (err) {
throw new ConfigError(
......@@ -351,7 +353,7 @@ export class Config {
private loadPlugins(plugins: string[]): LoadedPlugin[] {
return plugins.map((moduleName: string) => {
try {
// eslint-disable-next-line security/detect-non-literal-require
// eslint-disable-next-line security/detect-non-literal-require, import/no-dynamic-require
const plugin = require(moduleName.replace(
"<rootDir>",
this.rootDir
......@@ -616,7 +618,7 @@ export class Config {
/* expand <rootDir> */
const moduleName = name.replace("<rootDir>", this.rootDir);
// eslint-disable-next-line security/detect-non-literal-require
// eslint-disable-next-line security/detect-non-literal-require, import/no-dynamic-require
const fn = require(moduleName);
/* sanity check */
......
import { Attribute, DOMTree, HtmlElement, NodeClosed, NodeType } from ".";
import { Config } from "../config";
import { Location, Source } from "../context";
import { Token, TokenType } from "../lexer";
......@@ -6,6 +5,7 @@ import { MetaData, MetaElement, MetaTable } from "../meta";
import { Parser } from "../parser";
import { processAttribute } from "../transform/mocks/attribute";
import { DynamicValue } from "./dynamic-value";
import { Attribute, DOMTree, HtmlElement, NodeClosed, NodeType } from ".";
interface LocationSpec {
column: number;
......@@ -609,6 +609,11 @@ describe("HtmlElement", () => {
const el = root.querySelector("foobar");
expect(el).toBeNull();
});
it("should return null if selector is empty", () => {
const el = root.querySelector("");
expect(el).toBeNull();
});
});
describe("querySelectorAll()", () => {
......@@ -636,6 +641,11 @@ describe("HtmlElement", () => {
const el = root.querySelectorAll("missing");
expect(el).toEqual([]);
});
it("should return [] if selector is empty", () => {
const el = root.querySelectorAll("");
expect(el).toEqual([]);
});
});
describe("visitDepthFirst()", () => {
......
......@@ -426,6 +426,9 @@ export class HtmlElement extends DOMNode {
private *querySelectorImpl(
selectorList: string
): IterableIterator<HtmlElement> {
if (!selectorList) {
return;
}
for (const selector of selectorList.split(/,\s*/)) {
const pattern = new Selector(selector);
yield* pattern.match(this);
......
import { firstChild } from "./first-child";
import { HtmlElement } from "../htmlelement";
import { firstChild } from "./first-child";
it("should return true if element is first child", () => {
expect.assertions(2);
......
import { lastChild } from "./last-child";
import { HtmlElement } from "../htmlelement";
import { lastChild } from "./last-child";
it("should return true if element is last child", () => {
expect.assertions(2);
......
......@@ -419,6 +419,7 @@ export class Engine<T extends Parser = Parser> {
} catch (err) {
return null;
}
/* eslint-disable-next-line import/no-dynamic-require */
const Class = require(moduleName);
return new Class(options);
}
......
import betterAjvErrors from "@sidvind/better-ajv-errors";
import Ajv from "ajv";
import { UserError } from "../error/user-error";
import { UserError } from "./user-error";
function getSummary(schema: any, obj: any, errors: Ajv.ErrorObject[]): string {
const output = betterAjvErrors(schema, obj, errors, {
......
import { FormatterModule } from ".";
import { Message, Result } from "../reporter";
import { FormatterModule } from ".";
const entities: { [key: string]: string } = {
">": "&gt;",
......
import { Result } from "../reporter";
/* force colors on when running stylish tests */
const defaultColor = process.env.FORCE_COLOR;
process.env.FORCE_COLOR = "1";
......@@ -7,8 +9,6 @@ import formatter from "./codeframe";
/* restore color, need only to be set when importing library */
process.env.FORCE_COLOR = defaultColor;
import { Result } from "../reporter";
const source = `<div id="foo"
class="bar"
name="baz">
......
import { codeFrameColumns } from "@babel/code-frame";
import chalk = require("chalk");
import path from "path";
import { FormatterModule } from ".";
import { codeFrameColumns } from "@babel/code-frame";
import { Message, Result } from "../reporter";
import { FormatterModule } from ".";
import chalk = require("chalk");
interface SourcePoint {
line: number;
......
import { FormatterModule } from ".";
import { Result } from "../reporter";
import { FormatterModule } from ".";
export default function jsonFormatter(results: Result[]): string {
return JSON.stringify(results);
......
import { Result } from "../reporter";
/* force colors on when running stylish tests */
const defaultColor = process.env.FORCE_COLOR;
process.env.FORCE_COLOR = "1";
......@@ -7,8 +9,6 @@ import formatter from "./stylish";
/* restore color, need only to be set when importing library */
process.env.FORCE_COLOR = defaultColor;
import { Result } from "../reporter";
describe("stylish formatter", () => {
it("should generate plaintext", () => {
const results: Result[] = [
......
import { FormatterModule } from ".";
const stylish = require("eslint/lib/cli-engine/formatters/stylish");
export default stylish;
declare const module: FormatterModule;
......
import { FormatterModule } from ".";
import { Result } from "../reporter";
import { FormatterModule } from ".";
export default function textFormatter(results: Result[]): string {
let output = "";
......
import path from "path";
import { Config, ConfigData, ConfigLoader } from "./config";
import { Source } from "./context";
import { SourceHooks } from "./context/source";
......@@ -5,7 +6,6 @@ import { Engine, EventDump, TokenDump } from "./engine";
import { Parser } from "./parser";
import { Report, Reporter } from "./reporter";
import { RuleDocumentation } from "./rule";
import path from "path";
/**
* Primary API for using HTML-validate.
......
......@@ -2,6 +2,7 @@ import { Severity } from "./config";
import { Token, TokenType } from "./lexer";
import "./matchers";
import { Report, Reporter } from "./reporter";
import stripAnsi = require("strip-ansi");
let reportOk: Report;
......
......@@ -32,7 +32,8 @@ jest.mock(
import { Config } from "../config";
import { UserError } from "../error/user-error";
import { Parser } from "../parser";
import { MetaData, MetaTable } from "./";
import { MetaDataTable } from "./element";
import { MetaData, MetaTable } from ".";
class ConfigMock extends Config {
public constructor(metaTable: MetaTable) {
......@@ -75,6 +76,19 @@ describe("MetaTable", () => {
);
});
it("should ignore $schema property", () => {
expect.assertions(2);
const table = new MetaTable();
table.loadFromObject(({
$schema: "https://example.net/schema.json",
foo: {
flow: true,
},
} as unknown) as MetaDataTable);
expect(table.getMetaFor("foo")).toBeDefined();
expect(table.getMetaFor("$schema")).toBeNull();
});
describe("getMetaFor", () => {
let table: MetaTable;
......
import fs from "fs";
import Ajv from "ajv";
import deepmerge from "deepmerge";
import fs from "fs";
import jsonMergePatch from "json-merge-patch";
import { HtmlElement } from "../dom";
import { SchemaValidationError, UserError } from "../error";
......@@ -92,6 +92,7 @@ export class MetaTable {
}
for (const key of Object.keys(obj)) {
if (key === "$schema") continue;
this.addEntry(key, obj[key]);
}
}
......
import { Config } from "../config";
import { Attribute, DynamicValue, HtmlElement } from "../dom";
import { Parser } from "../parser";
import { MetaData, MetaTable, Validator } from "./";
import { MetaData, MetaTable, Validator } from ".";
class ConfigMock extends Config {
public constructor(metaTable: MetaTable) {
......
......@@ -4,6 +4,7 @@ import { AttributeEvent, ElementReadyEvent } from "../event";
import { Rule, RuleDocumentation, ruleDocumentationUrl } from "../rule";
const entities = require("../../elements/entities.json");
const regexp = /&([a-z0-9]+|#x?[0-9a-f]+);/gi;
class UnknownCharReference extends Rule<string> {
......
......@@ -6,6 +6,10 @@
"type": "object",
"additionalProperties": false,
"properties": {
"$schema": {
"type": "string"
},
"root": {
"type": "boolean",
"title": "Mark as root configuration",
......
......@@ -4,47 +4,143 @@
"version": "1.0",
"type": "object",
"properties": {
"$schema": {
"type": "string"
}
},
"patternProperties": {
"^.*$": {
"type": "object",
"properties": {
"inherit": { "type": "string" },
"inherit": {
"title": "Inherit from another element",
"description": "Most properties from the parent element will be copied onto this one",
"type": "string"
},
"embedded": { "$ref": "#/definitions/contentCategory" },
"flow": { "$ref": "#/definitions/contentCategory" },
"heading": { "$ref": "#/definitions/contentCategory" },
"interactive": { "$ref": "#/definitions/contentCategory" },
"metadata": { "$ref": "#/definitions/contentCategory" },
"phrasing": { "$ref": "#/definitions/contentCategory" },
"sectioning": { "$ref": "#/definitions/contentCategory" },
"embedded": {
"title": "Mark this element as belonging in the embedded content category",
"$ref": "#/definitions/contentCategory"
},
"flow": {
"title": "Mark this element as belonging in the flow content category",
"$ref": "#/definitions/contentCategory"
},
"heading": {
"title": "Mark this element as belonging in the heading content category",
"$ref": "#/definitions/contentCategory"
},
"interactive": {
"title": "Mark this element as belonging in the interactive content category",
"$ref": "#/definitions/contentCategory"
},
"metadata": {
"title": "Mark this element as belonging in the metadata content category",
"$ref": "#/definitions/contentCategory"
},
"phrasing": {
"title": "Mark this element as belonging in the phrasing content category",
"$ref": "#/definitions/contentCategory"
},
"sectioning": {
"title": "Mark this element as belonging in the sectioning content category",
"$ref": "#/definitions/contentCategory"
},
"deprecated": {
"title": "Mark element as deprecated",
"description": "Deprecated elements should not be used. If a message is provided it will be included in the error",
"anyOf": [{ "type": "boolean" }, { "type": "string" }]
},
"foreign": { "type": "boolean" },
"void": { "type": "boolean" },
"transparent": { "type": "boolean" },
"implicitClosed": { "type": "array", "items": { "type": "string" } },
"scriptSupporting": { "type": "boolean" },
"form": { "type": "boolean" },
"foreign": {
"title": "Mark element as foreign",
"description": "Foreign elements are elements which have a start and end tag but is otherwize not parsed",
"type": "boolean"
},
"void": {
"title": "Mark element as void",
"description": "Void elements are elements which cannot have content and thus must not use an end tag",
"type": "boolean"
},
"transparent": {
"title": "Mark element as transparent",
"description": "Transparent elements follows the same content model as its parent, i.e. the content must be allowed in the parent.",
"type": "boolean"
},
"implicitClosed": {
"title": "List of elements which implicitly closes this element",
"description": "Some elements are automatically closed when another start tag occurs",
"type": "array",
"items": { "type": "string" }
},
"scriptSupporting": {
"title": "Mark element as script-supporting",
"description": "Script-supporting elements are elements which can be inserted where othersise not permitted to assist in templating",
"type": "boolean"
},
"form": {
"title": "Mark element as a submittable form element",
"type": "boolean"
},
"deprecatedAttributes": {
"title": "List of deprecated attributes",
"type": "array",
"items": { "type": "string" }
},
"requiredAttributes": {
"title": "List of required attributes",
"type": "array",
"items": { "type": "string" }
},
"attributes": { "$ref": "#/definitions/PermittedAttribute" },
"permittedContent": { "$ref": "#/definitions/Permitted" },
"permittedDescendants": { "$ref": "#/definitions/Permitted" },
"permittedOrder": { "$ref": "#/definitions/PermittedOrder" },
"requiredAncestors": { "$ref": "#/definitions/RequiredAncestors" },
"requiredContent": { "$ref": "#/definitions/RequiredContent" }
"attributes": {
"title": "List of known attributes and allowed values",
"$ref": "#/definitions/PermittedAttribute"
},
"permittedContent": {
"title": "List of elements or categories allowed as content in this element",
"$ref": "#/definitions/Permitted"
},
"permittedDescendants": {
"title": "List of elements or categories allowed as descendants in this element",
"$ref": "#/definitions/Permitted"
},
"permittedOrder": {
"title": "Required order of child elements",
"$ref": "#/definitions/PermittedOrder"
},
"requiredAncestors": {
"title": "List of required ancestor elements",
"$ref": "#/definitions/RequiredAncestors"
},
"requiredContent": {
"title": "List of required content elements",
"$ref": "#/definitions/RequiredContent"
}
},
"additionalProperties": false
"additionalProperties": true
}
},
......
......@@ -4,11 +4,14 @@ export { default as HtmlValidate } from "./htmlvalidate";
export { AttributeData } from "./parser";
export { CLI } from "./cli/cli";
export { Config, ConfigData, ConfigLoader, Severity } from "./config";
export { DynamicValue, HtmlElement } from "./dom";
export { DynamicValue, HtmlElement, NodeClosed, TextNode } from "./dom";
export { Rule, RuleDocumentation } from "./rule";
export { Source, Location, ProcessElementContext } from "./context";
export { Report, Reporter, Message, Result } from "./reporter";
export { Transformer, TemplateExtractor } from "./transform";
export { Plugin } from "./plugin";
export { Parser } from "./parser";
const pkg = require("../package.json");
export const version = pkg.version;
import fs from "fs";
// imported only for type declarations via @types/estree
// eslint-disable-next-line import/no-unresolved
import ESTree from "estree";
import fs from "fs";
import { Source } from "../context";
const espree = require("espree");
......
import fs from "fs";
import { TransformContext } from ".";
import { Source } from "../context";
import { transformFile, transformSource, transformString } from "./test-utils";
import { TransformContext } from ".";
jest.mock("fs");
......
import fs from "fs";
import { TransformContext, Transformer } from ".";
import { Source } from "../context";
import { TransformContext, Transformer } from ".";
/**
* Helper function to call a transformer function in test-cases.
......
......@@ -24,6 +24,7 @@
"check-open-brace"
]
},
"ordered-imports": false,
"unified-signatures": false
},
"rulesDirectory": []
......