obsohtml 1.9.9 → 1.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/dependabot.yml +2 -0
- package/CHANGELOG.md +18 -0
- package/README.md +32 -27
- package/SECURITY.md +1 -1
- package/bin/obsohtml.js +9 -39
- package/bin/obsohtml.test.js +90 -0
- package/package.json +17 -7
- package/src/index.d.ts +7 -0
- package/src/index.js +46 -0
- package/src/index.test.ts +25 -0
- package/tsconfig.json +16 -0
package/.github/dependabot.yml
CHANGED
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
As of version 1.10.0, all notable changes to ObsoHTML are documented in this file, which is (mostly) AI-generated and (always) human-edited. Dependency updates may or may not be called out specifically.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [1.10.1] - 2026-05-11
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Fixed false positives where obsolete attribute names (e.g., `scrolling`, `background`, `border`) appeared as text inside quoted attribute values (e.g., `content="Infinite scrolling"`)
|
|
12
|
+
|
|
13
|
+
## [1.10.0] - 2026-04-11
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Added programmatic API: `checkMarkup(html)` returns `{ elements, attributes }` arrays for use in other tools; `obsoleteElements` and `obsoleteAttributes` are now exported directly
|
|
18
|
+
- Added TypeScript declaration file (`src/index.d.ts`)
|
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# ObsoHTML, the Obsolete HTML Checker
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/obsohtml) [](https://github.com/j9t/obsohtml/actions) [](https://socket.dev/npm/package/obsohtml)
|
|
3
|
+
[](https://www.npmjs.com/package/obsohtml) [](https://github.com/j9t/obsohtml/actions) [](https://socket.dev/npm/package/obsohtml) [](https://github.com/j9t/obsohtml?sponsor=1)
|
|
4
4
|
|
|
5
|
-
ObsoHTML is a Node.js
|
|
5
|
+
ObsoHTML is a Node.js tool designed to scan HTML, PHP, Nunjucks, Twig, JavaScript, and TypeScript files for obsolete and proprietary HTML elements and attributes. It helps you identify and update deprecated HTML code to be sure to use web standards.
|
|
6
6
|
|
|
7
7
|
ObsoHTML has inherent limitations and may not find all obsolete elements and attributes. If you run into a problem, please [file an issue](https://github.com/j9t/obsohtml/issues).
|
|
8
8
|
|
|
9
9
|
## Usage
|
|
10
10
|
|
|
11
|
-
### 1.
|
|
11
|
+
### 1. Via CLI
|
|
12
12
|
|
|
13
13
|
#### Installation
|
|
14
14
|
|
|
@@ -18,11 +18,13 @@ npm i obsohtml
|
|
|
18
18
|
|
|
19
19
|
(To install ObsoHTML globally, use the `-g` flag, as in `npm i -g obsohtml`.)
|
|
20
20
|
|
|
21
|
+
To use ObsoHTML without installing, run it via `npx obsohtml`. To use it as a standalone script, [download or fork the source repository](https://github.com/j9t/obsohtml) and run `node bin/obsohtml.js` directly—the same options apply.
|
|
22
|
+
|
|
21
23
|
#### Execution
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
ObsoHTML accepts a folder or file path as a command line option, which can be specified in both short form (`-f`) and long form (`--folder`). The path can be either absolute or relative.
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
ObsoHTML can be run in “verbose” mode by appending `-v` or `--verbose` to the command. This will show information about files and directories that were skipped.
|
|
26
28
|
|
|
27
29
|
##### Example Commands
|
|
28
30
|
|
|
@@ -44,37 +46,32 @@ Specify a folder using a relative path:
|
|
|
44
46
|
npx obsohtml -f ../path/to/folder
|
|
45
47
|
```
|
|
46
48
|
|
|
47
|
-
### 2.
|
|
49
|
+
### 2. Programmatic API
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
ObsoHTML can be imported as a module to check HTML strings in your own tooling:
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
```js
|
|
54
|
+
import { checkMarkup, obsoleteElements, obsoleteAttributes } from 'obsohtml';
|
|
52
55
|
|
|
53
|
-
|
|
56
|
+
const { elements, attributes } = checkMarkup('<center>Hello</center>');
|
|
57
|
+
// elements: ['center']
|
|
58
|
+
// attributes: []
|
|
59
|
+
```
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
#### `checkMarkup(html)`
|
|
56
62
|
|
|
57
|
-
|
|
63
|
+
Checks an HTML string for obsolete and proprietary elements and attributes.
|
|
58
64
|
|
|
59
|
-
|
|
65
|
+
* **Parameter**: `html` (string)—the HTML content to check
|
|
66
|
+
* **Returns**: `{ elements: string[], attributes: string[] }`—arrays of found obsolete element and attribute names
|
|
60
67
|
|
|
61
|
-
|
|
68
|
+
#### `obsoleteElements`
|
|
62
69
|
|
|
63
|
-
|
|
64
|
-
node bin/obsohtml.js
|
|
65
|
-
```
|
|
70
|
+
Array of obsolete or proprietary HTML element names checked by ObsoHTML.
|
|
66
71
|
|
|
67
|
-
|
|
72
|
+
#### `obsoleteAttributes`
|
|
68
73
|
|
|
69
|
-
|
|
70
|
-
node bin/obsohtml.js -f /path/to/folder
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
Specify a folder using a relative path:
|
|
74
|
-
|
|
75
|
-
```console
|
|
76
|
-
node bin/obsohtml.js -f ../path/to/folder
|
|
77
|
-
```
|
|
74
|
+
Array of obsolete or proprietary HTML attribute names checked by ObsoHTML.
|
|
78
75
|
|
|
79
76
|
## Output
|
|
80
77
|
|
|
@@ -88,4 +85,12 @@ This started as an experiment, in which I used AI to produce this little HTML qu
|
|
|
88
85
|
|
|
89
86
|
## Acknowledgments
|
|
90
87
|
|
|
91
|
-
Thanks to [@mattbrundage](https://github.com/mattbrundage), [@FabianBeiner](https://github.com/FabianBeiner), and [@AndrewMac](https://github.com/AndrewMac) for helping to make ObsoHTML better!
|
|
88
|
+
Thanks to [@mattbrundage](https://github.com/mattbrundage), [@FabianBeiner](https://github.com/FabianBeiner), and [@AndrewMac](https://github.com/AndrewMac) for helping to make ObsoHTML better!
|
|
89
|
+
|
|
90
|
+
***
|
|
91
|
+
|
|
92
|
+
You might like some of my other work:
|
|
93
|
+
|
|
94
|
+
* Optimization tools: [HTML Minifier Next](https://github.com/j9t/html-minifier-next) · ObsoHTML · [Image Guard](https://github.com/j9t/image-guard) · [Compressor.js Next](https://github.com/j9t/compressorjs-next) · [.htaccess Punk](https://github.com/j9t/htaccess-punk)
|
|
95
|
+
* Defense tools: [IA Defensa](https://iadefensa.com/solutions/)
|
|
96
|
+
* Resources for quality web development: [Articles](https://meiert.com/topics/development/) · [Books](https://meiert.com/topics/books/) (including [_On Web Development_](https://meiert.com/blog/on-web-development-2/)) · [News](https://frontenddogma.com/) · [Terminology](https://webglossary.info/)
|
package/SECURITY.md
CHANGED
|
@@ -6,4 +6,4 @@ Only the latest and therefore current version of ObsoHTML is supported. It’s a
|
|
|
6
6
|
|
|
7
7
|
## Reporting a Vulnerability
|
|
8
8
|
|
|
9
|
-
To report a vulnerability, please [
|
|
9
|
+
To report a vulnerability, please use [GitHub’s private security advisories](https://github.com/j9t/obsohtml/security/advisories/new) or email info@meiert.com directly. Do not report vulnerabilities via public issues.
|
package/bin/obsohtml.js
CHANGED
|
@@ -5,32 +5,10 @@ import fs from 'node:fs';
|
|
|
5
5
|
import os from 'node:os';
|
|
6
6
|
import path from 'node:path';
|
|
7
7
|
import { styleText } from 'node:util';
|
|
8
|
+
import { checkMarkup } from '../src/index.js';
|
|
8
9
|
|
|
9
10
|
const program = new Command();
|
|
10
11
|
|
|
11
|
-
// List of obsolete or proprietary HTML elements
|
|
12
|
-
const obsoleteElements = [
|
|
13
|
-
'acronym', 'applet', 'basefont', 'bgsound', 'big', 'blink', 'center', 'command', 'content', 'dir', 'element', 'font', 'frame', 'frameset', 'image', 'isindex', 'keygen', 'listing', 'marquee', 'menuitem', 'multicol', 'nextid', 'nobr', 'noembed', 'noframes', 'param', 'plaintext', 'rb', 'rtc', 'shadow', 'spacer', 'strike', 'tt', 'xmp'
|
|
14
|
-
];
|
|
15
|
-
|
|
16
|
-
// List of obsolete or proprietary HTML attributes
|
|
17
|
-
const obsoleteAttributes = [
|
|
18
|
-
'align', 'background', 'bgcolor', 'border', 'frameborder', 'hspace', 'marginheight', 'marginwidth', 'noshade', 'nowrap', 'scrolling', 'valign', 'vspace'
|
|
19
|
-
];
|
|
20
|
-
|
|
21
|
-
// Pre-compile regexes once at startup
|
|
22
|
-
const elementRegexes = obsoleteElements.map(element => ({
|
|
23
|
-
element,
|
|
24
|
-
regex: new RegExp(`<\\s*${element}\\b`, 'i'),
|
|
25
|
-
}));
|
|
26
|
-
|
|
27
|
-
const attributeRegexes = obsoleteAttributes.map(attribute => ({
|
|
28
|
-
attribute,
|
|
29
|
-
// Matches the attribute preceded by whitespace anywhere in a tag, without
|
|
30
|
-
// requiring it to be the last attribute before the closing bracket.
|
|
31
|
-
regex: new RegExp(`<[^>]*\\s${attribute}\\b(\\s*=\\s*(?:"[^"]*"|'[^']*'|[^"'\\s>]+))?`, 'i'),
|
|
32
|
-
}));
|
|
33
|
-
|
|
34
12
|
// Directories to skip during traversal
|
|
35
13
|
const EXCLUDED_DIRS = new Set(['node_modules', '.git', 'dist', 'build', 'vendor']);
|
|
36
14
|
|
|
@@ -42,24 +20,16 @@ let foundObsolete = false;
|
|
|
42
20
|
|
|
43
21
|
// Function to find obsolete elements and attributes in a file
|
|
44
22
|
function findObsolete(filePath) {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
foundObsolete = true;
|
|
51
|
-
const message = styleText('blue', `Found obsolete element ${styleText('bold', `'${element}'`)} in ${filePath}`);
|
|
52
|
-
console.log(message);
|
|
53
|
-
}
|
|
23
|
+
const { elements, attributes } = checkMarkup(fs.readFileSync(filePath, 'utf8'));
|
|
24
|
+
|
|
25
|
+
for (const element of elements) {
|
|
26
|
+
foundObsolete = true;
|
|
27
|
+
console.log(styleText('blue', `Found obsolete element ${styleText('bold', `'${element}'`)} in ${filePath}`));
|
|
54
28
|
}
|
|
55
29
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
foundObsolete = true;
|
|
60
|
-
const message = styleText('green', `Found obsolete attribute ${styleText('bold', `'${attribute}'`)} in ${filePath}`);
|
|
61
|
-
console.log(message);
|
|
62
|
-
}
|
|
30
|
+
for (const attribute of attributes) {
|
|
31
|
+
foundObsolete = true;
|
|
32
|
+
console.log(styleText('green', `Found obsolete attribute ${styleText('bold', `'${attribute}'`)} in ${filePath}`));
|
|
63
33
|
}
|
|
64
34
|
}
|
|
65
35
|
|
package/bin/obsohtml.test.js
CHANGED
|
@@ -5,6 +5,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
5
5
|
import { describe, test, before, after } from 'node:test';
|
|
6
6
|
import assert from 'node:assert';
|
|
7
7
|
import { stripVTControlCharacters } from 'node:util';
|
|
8
|
+
import { checkMarkup, obsoleteElements, obsoleteAttributes } from '../src/index.js';
|
|
8
9
|
|
|
9
10
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
11
|
const scriptPath = path.join(__dirname, 'obsohtml.js');
|
|
@@ -120,4 +121,93 @@ describe('ObsoHTML', () => {
|
|
|
120
121
|
const { stderr } = run(['-f', path.join(tempDir, 'nonexistent'), '-v']);
|
|
121
122
|
assert.ok(stderr.includes('Skipping non-existent directory'));
|
|
122
123
|
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe('`obsoleteElements`', () => {
|
|
127
|
+
test('Export as a non-empty array of strings', () => {
|
|
128
|
+
assert.ok(Array.isArray(obsoleteElements));
|
|
129
|
+
assert.ok(obsoleteElements.length > 0);
|
|
130
|
+
assert.ok(obsoleteElements.every(e => typeof e === 'string'));
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe('`obsoleteAttributes`', () => {
|
|
135
|
+
test('Export as a non-empty array of strings', () => {
|
|
136
|
+
assert.ok(Array.isArray(obsoleteAttributes));
|
|
137
|
+
assert.ok(obsoleteAttributes.length > 0);
|
|
138
|
+
assert.ok(obsoleteAttributes.every(a => typeof a === 'string'));
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
describe('`checkMarkup`', () => {
|
|
143
|
+
test('Return empty arrays for clean HTML', () => {
|
|
144
|
+
const result = checkMarkup('<p>Hello <strong>world</strong></p>');
|
|
145
|
+
assert.deepEqual(result, { elements: [], attributes: [] });
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test('Return empty arrays for an empty string', () => {
|
|
149
|
+
const result = checkMarkup('');
|
|
150
|
+
assert.deepEqual(result, { elements: [], attributes: [] });
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test('Throw a TypeError for non-string input', () => {
|
|
154
|
+
assert.throws(() => checkMarkup(null), TypeError);
|
|
155
|
+
assert.throws(() => checkMarkup(42), TypeError);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test('Detect an obsolete element', () => {
|
|
159
|
+
const { elements, attributes } = checkMarkup('<center>Hello</center>');
|
|
160
|
+
assert.ok(elements.includes('center'));
|
|
161
|
+
assert.deepEqual(attributes, []);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test('Detect an obsolete attribute', () => {
|
|
165
|
+
const { elements, attributes } = checkMarkup('<img src="x.jpg" align="left">');
|
|
166
|
+
assert.deepEqual(elements, []);
|
|
167
|
+
assert.ok(attributes.includes('align'));
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
test('Detect multiple obsolete elements in one string', () => {
|
|
171
|
+
const { elements } = checkMarkup('<marquee><blink>Hello</blink></marquee>');
|
|
172
|
+
assert.ok(elements.includes('marquee'));
|
|
173
|
+
assert.ok(elements.includes('blink'));
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test('Detect multiple obsolete attributes in one string', () => {
|
|
177
|
+
const { attributes } = checkMarkup('<table border="1" bgcolor="#fff"><tr valign="top"></tr></table>');
|
|
178
|
+
assert.ok(attributes.includes('border'));
|
|
179
|
+
assert.ok(attributes.includes('bgcolor'));
|
|
180
|
+
assert.ok(attributes.includes('valign'));
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test('Detect both obsolete elements and attributes in one string', () => {
|
|
184
|
+
const { elements, attributes } = checkMarkup('<center><img align="left"></center>');
|
|
185
|
+
assert.ok(elements.includes('center'));
|
|
186
|
+
assert.ok(attributes.includes('align'));
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test('Detect obsolete elements case-insensitively', () => {
|
|
190
|
+
const { elements } = checkMarkup('<CENTER>Hello</CENTER>');
|
|
191
|
+
assert.ok(elements.includes('center'));
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test('Do not detect partial tag name matches', () => {
|
|
195
|
+
const { elements } = checkMarkup('<centers>Hello</centers>');
|
|
196
|
+
assert.deepEqual(elements, []);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test('Do not flag an obsolete attribute name appearing inside a quoted attribute value', () => {
|
|
200
|
+
// “scrolling” inside `content="…"`, “background” inside `content="…"`, and
|
|
201
|
+
// “border” inside `alt="…"` are all text—not actual HTML attributes
|
|
202
|
+
const cases = [
|
|
203
|
+
'<meta property="og:title" content="Infinite scrolling on the web">',
|
|
204
|
+
'<meta content="Busyness and Background Noise on Websites">',
|
|
205
|
+
'<img alt="A graphic indicating a border between regions.">',
|
|
206
|
+
"<img alt='A graphic indicating a border between regions.'>",
|
|
207
|
+
];
|
|
208
|
+
for (const html of cases) {
|
|
209
|
+
const { attributes } = checkMarkup(html);
|
|
210
|
+
assert.deepEqual(attributes, [], `Expected no attributes for: ${html}`);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
123
213
|
});
|
package/package.json
CHANGED
|
@@ -7,6 +7,18 @@
|
|
|
7
7
|
"commander": "^14.0.0"
|
|
8
8
|
},
|
|
9
9
|
"description": "HTML checker for obsolete and proprietary elements and attributes",
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"@eslint/js": "^10.0.0",
|
|
12
|
+
"eslint": "^10.3.0",
|
|
13
|
+
"globals": "^17.6.0",
|
|
14
|
+
"typescript": "^6.0.3"
|
|
15
|
+
},
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./src/index.d.ts",
|
|
19
|
+
"default": "./src/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
10
22
|
"funding": "https://github.com/j9t/obsohtml?sponsor=1",
|
|
11
23
|
"homepage": "https://github.com/j9t/obsohtml",
|
|
12
24
|
"keywords": [
|
|
@@ -16,22 +28,20 @@
|
|
|
16
28
|
"semantics"
|
|
17
29
|
],
|
|
18
30
|
"license": "MIT",
|
|
31
|
+
"main": "src/index.js",
|
|
19
32
|
"name": "obsohtml",
|
|
20
33
|
"repository": {
|
|
21
34
|
"type": "git",
|
|
22
35
|
"url": "git+https://github.com/j9t/obsohtml.git"
|
|
23
36
|
},
|
|
24
|
-
"devDependencies": {
|
|
25
|
-
"@eslint/js": "^10.0.0",
|
|
26
|
-
"eslint": "^10.0.0",
|
|
27
|
-
"globals": "^17.0.0"
|
|
28
|
-
},
|
|
29
37
|
"scripts": {
|
|
30
38
|
"lint": "eslint .",
|
|
31
39
|
"lint:fix": "eslint . --fix",
|
|
32
40
|
"start": "node ./bin/obsohtml.js",
|
|
33
|
-
"test": "node --test bin/obsohtml.test.js"
|
|
41
|
+
"test": "npm run test:types && node --test bin/obsohtml.test.js",
|
|
42
|
+
"test:types": "tsc"
|
|
34
43
|
},
|
|
35
44
|
"type": "module",
|
|
36
|
-
"
|
|
45
|
+
"types": "src/index.d.ts",
|
|
46
|
+
"version": "1.10.1"
|
|
37
47
|
}
|
package/src/index.d.ts
ADDED
package/src/index.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Obsolete or proprietary HTML elements
|
|
2
|
+
export const obsoleteElements = Object.freeze([
|
|
3
|
+
'acronym', 'applet', 'basefont', 'bgsound', 'big', 'blink', 'center', 'command', 'content', 'dir', 'element', 'font', 'frame', 'frameset', 'image', 'isindex', 'keygen', 'listing', 'marquee', 'menuitem', 'multicol', 'nextid', 'nobr', 'noembed', 'noframes', 'param', 'plaintext', 'rb', 'rtc', 'shadow', 'spacer', 'strike', 'tt', 'xmp'
|
|
4
|
+
]);
|
|
5
|
+
|
|
6
|
+
// Obsolete or proprietary HTML attributes
|
|
7
|
+
export const obsoleteAttributes = Object.freeze([
|
|
8
|
+
'align', 'background', 'bgcolor', 'border', 'frameborder', 'hspace', 'marginheight', 'marginwidth', 'noshade', 'nowrap', 'scrolling', 'valign', 'vspace'
|
|
9
|
+
]);
|
|
10
|
+
|
|
11
|
+
// Pre-compiled regexes for performance
|
|
12
|
+
const elementRegexes = new Map(
|
|
13
|
+
obsoleteElements.map(element => [element, new RegExp(`<\\s*${element}\\b`, 'i')])
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const attributeRegexes = new Map(
|
|
17
|
+
obsoleteAttributes.map(attribute => [
|
|
18
|
+
attribute,
|
|
19
|
+
// Matches the attribute preceded by whitespace anywhere in a tag, without
|
|
20
|
+
// requiring it to be the last attribute before the closing bracket
|
|
21
|
+
new RegExp(`<(?:[^>"']|"[^"]*"|'[^']*')*\\s${attribute}\\b(\\s*=\\s*(?:"[^"]*"|'[^']*'|[^"'\\s>]+))?`, 'i'),
|
|
22
|
+
])
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Check an HTML string for obsolete and proprietary elements and attributes.
|
|
27
|
+
*
|
|
28
|
+
* @param {string} html
|
|
29
|
+
* @returns {{ elements: string[], attributes: string[] }}
|
|
30
|
+
*/
|
|
31
|
+
export function checkMarkup(html) {
|
|
32
|
+
if (typeof html !== 'string') throw new TypeError('`html` must be a string');
|
|
33
|
+
|
|
34
|
+
const elements = [];
|
|
35
|
+
const attributes = [];
|
|
36
|
+
|
|
37
|
+
for (const [element, regex] of elementRegexes) {
|
|
38
|
+
if (regex.test(html)) elements.push(element);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
for (const [attribute, regex] of attributeRegexes) {
|
|
42
|
+
if (regex.test(html)) attributes.push(attribute);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return { elements, attributes };
|
|
46
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript type definition tests
|
|
3
|
+
*
|
|
4
|
+
* This file is compiled by TypeScript during testing to verify that the
|
|
5
|
+
* declaration file is valid and types are correctly exported and usable.
|
|
6
|
+
*
|
|
7
|
+
* This file is not executed—it only needs to type-check successfully.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { checkMarkup, obsoleteElements, obsoleteAttributes } from './index.js';
|
|
11
|
+
|
|
12
|
+
// Exported arrays are readonly string arrays
|
|
13
|
+
const els: readonly string[] = obsoleteElements;
|
|
14
|
+
const attrs: readonly string[] = obsoleteAttributes;
|
|
15
|
+
|
|
16
|
+
// `checkMarkup` accepts a string and returns the correct shape
|
|
17
|
+
const result: { elements: string[]; attributes: string[] } = checkMarkup('<center>test</center>');
|
|
18
|
+
|
|
19
|
+
// `checkMarkup` rejects non-string input
|
|
20
|
+
// @ts-expect-error
|
|
21
|
+
checkMarkup(null);
|
|
22
|
+
// @ts-expect-error
|
|
23
|
+
checkMarkup(42);
|
|
24
|
+
|
|
25
|
+
export { els, attrs, result };
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"include": [
|
|
3
|
+
"src/index.test.ts"
|
|
4
|
+
],
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"module": "nodenext",
|
|
7
|
+
"target": "esnext",
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"verbatimModuleSyntax": true,
|
|
12
|
+
"isolatedModules": true,
|
|
13
|
+
"moduleDetection": "force",
|
|
14
|
+
"forceConsistentCasingInFileNames": true
|
|
15
|
+
}
|
|
16
|
+
}
|