@nerimity/html-embed 1.2.0 → 1.2.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/dist/index.js CHANGED
@@ -210,7 +210,16 @@ function htmlToJson(html) {
210
210
  }
211
211
  function validateHtmlStructure(html) {
212
212
  let isMalformed = false;
213
+ const voidElements = ["img", "br", "hr", "input", "meta", "link"];
213
214
  const parser = new htmlparser2.Parser({
215
+ onopentag(name) {
216
+ if (voidElements.includes(name.toLowerCase())) {
217
+ const tagClosing = html.substring(parser.startIndex, html.indexOf(">", parser.startIndex) + 1);
218
+ if (!tagClosing.endsWith("/>")) {
219
+ throw new Error(`The <${name}> tag must be self-closed with a slash (e.g., <${name} />).`);
220
+ }
221
+ }
222
+ },
214
223
  onerror(error) {
215
224
  isMalformed = true;
216
225
  },
@@ -222,8 +231,9 @@ function validateHtmlStructure(html) {
222
231
  }
223
232
  const openTags = (html.match(/<[a-zA-Z0-9]+/g) || []).length;
224
233
  const closeTags = (html.match(/<\/[a-zA-Z0-9]+/g) || []).length;
234
+ const voidTagsFound = (html.match(/<(img|br|hr|input|meta|link)/g) || []).length;
225
235
  const expectedCloseTags = openTags - (html.match(/<(img|br|hr)/g) || []).length;
226
- if (expectedCloseTags !== closeTags) {
236
+ if (openTags - voidTagsFound !== closeTags) {
227
237
  throw new Error("Mismatched or unclosed HTML tags.");
228
238
  }
229
239
  }
package/example.js CHANGED
@@ -4,16 +4,8 @@ const { htmlToJson } = require("./dist");
4
4
 
5
5
  // throw error because invalid css
6
6
  console.log(htmlToJson(`
7
- <div class="owo">
8
- test
9
- <a href="https://google.com">test</a>
10
- </div>
7
+ <dIv class="owo" style="owo: lol"; onclick="Lol">
8
+ <br />
9
+ </dIv>
11
10
 
12
-
13
- <style>
14
- }
15
- .owo {
16
- color: red;
17
- }
18
- </style>
19
11
  `))
package/package.json CHANGED
@@ -1,24 +1,24 @@
1
- {
2
- "name": "@nerimity/html-embed",
3
- "version": "1.2.0",
4
- "description": "",
5
- "main": "dist/index.js",
6
- "scripts": {
7
- "build": "tsc",
8
- "example": "tsc & node example.js"
9
- },
10
- "keywords": [],
11
- "author": "",
12
- "license": "ISC",
13
- "devDependencies": {
14
- "@types/css": "^0.0.37",
15
- "@types/node": "^22.10.10",
16
- "typescript": "^5.5.2"
17
- },
18
- "dependencies": {
19
- "css": "^3.0.0",
20
- "csstree-validator": "^4.0.1",
21
- "htm": "^3.1.0",
22
- "htmlparser2": "^10.0.0"
23
- }
24
- }
1
+ {
2
+ "name": "@nerimity/html-embed",
3
+ "version": "1.2.1",
4
+ "description": "",
5
+ "main": "dist/index.js",
6
+ "scripts": {
7
+ "build": "tsc",
8
+ "example": "tsc & node example.js"
9
+ },
10
+ "keywords": [],
11
+ "author": "",
12
+ "license": "ISC",
13
+ "devDependencies": {
14
+ "@types/css": "^0.0.37",
15
+ "@types/node": "^22.10.10",
16
+ "typescript": "^5.5.2"
17
+ },
18
+ "dependencies": {
19
+ "css": "^3.0.0",
20
+ "csstree-validator": "^4.0.1",
21
+ "htm": "^3.1.0",
22
+ "htmlparser2": "^10.0.0"
23
+ }
24
+ }
package/src/index.ts CHANGED
@@ -182,8 +182,18 @@ export function htmlToJson(html: string) {
182
182
 
183
183
  function validateHtmlStructure(html: string) {
184
184
  let isMalformed = false;
185
+ const voidElements = ["img", "br", "hr", "input", "meta", "link"];
185
186
  const parser = new htmlparser2.Parser(
186
187
  {
188
+ onopentag(name) {
189
+ if (voidElements.includes(name.toLowerCase())) {
190
+ const tagClosing = html.substring(parser.startIndex, html.indexOf(">", parser.startIndex) + 1);
191
+
192
+ if (!tagClosing.endsWith("/>")) {
193
+ throw new Error(`The <${name}> tag must be self-closed with a slash (e.g., <${name} />).`);
194
+ }
195
+ }
196
+ },
187
197
  onerror(error) {
188
198
  isMalformed = true;
189
199
  },
@@ -200,11 +210,12 @@ function validateHtmlStructure(html: string) {
200
210
 
201
211
  const openTags = (html.match(/<[a-zA-Z0-9]+/g) || []).length;
202
212
  const closeTags = (html.match(/<\/[a-zA-Z0-9]+/g) || []).length;
203
-
213
+ const voidTagsFound = (html.match(/<(img|br|hr|input|meta|link)/g) || []).length;
214
+
204
215
  const expectedCloseTags =
205
216
  openTags - (html.match(/<(img|br|hr)/g) || []).length;
206
217
 
207
- if (expectedCloseTags !== closeTags) {
218
+ if (openTags - voidTagsFound !== closeTags) {
208
219
  throw new Error("Mismatched or unclosed HTML tags.");
209
220
  }
210
221
  }