Add support for attribute decoding, via a proxy(this should really be
fixed upstream).
Showing
3 changed files
with
50 additions
and
2 deletions
| 1 | import nodeUtil from 'util' | 1 | import nodeUtil from 'util' |
| 2 | import TTLCache from '@isaacs/ttlcache' | 2 | import TTLCache from '@isaacs/ttlcache' |
| 3 | import { decode } from 'html-entities' | ||
| 3 | 4 | ||
| 4 | import type { NodeType } from 'ultrahtml' | 5 | import type { NodeType } from 'ultrahtml' |
| 5 | import { | 6 | import { |
| ... | @@ -306,12 +307,42 @@ export const createMatcher = (selector: string): Matcher => { | ... | @@ -306,12 +307,42 @@ export const createMatcher = (selector: string): Matcher => { |
| 306 | return newMatcherCreater() | 307 | return newMatcherCreater() |
| 307 | } | 308 | } |
| 308 | 309 | ||
| 310 | const nodeProxyHandler = { | ||
| 311 | get(target, prop, receiver) { | ||
| 312 | const { _proxy } = target | ||
| 313 | if (prop in _proxy) return _proxy[ prop ] | ||
| 314 | const { [ prop ]: origValue } = target | ||
| 315 | if (!origValue) return origValue | ||
| 316 | switch (prop) { | ||
| 317 | case 'attributes': | ||
| 318 | return _proxy[ prop ] = (origValue ? Object.fromEntries(Object.entries(origValue).map(([ key, value ]) => { | ||
| 319 | return [ key, decode(value) ] | ||
| 320 | })) : origValue) | ||
| 321 | return newValue | ||
| 322 | case 'parent': | ||
| 323 | return _proxy[ prop ] = proxyNode(origValue) | ||
| 324 | case 'children': | ||
| 325 | return _proxy[ prop ] = origValue.map((child) => proxyNode(child)) | ||
| 326 | default: | ||
| 327 | return origValue | ||
| 328 | } | ||
| 329 | } | ||
| 330 | } | ||
| 331 | |||
| 332 | const proxyNode = (node) => { | ||
| 333 | const { _proxy: { proxy } = {} } = node | ||
| 334 | if (proxy) return proxy | ||
| 335 | const newProxy = new Proxy(node, nodeProxyHandler) | ||
| 336 | node._proxy = { proxy: newProxy } | ||
| 337 | return newProxy | ||
| 338 | } | ||
| 339 | |||
| 309 | export const parseHtml = (html: string): NodeType => { | 340 | export const parseHtml = (html: string): NodeType => { |
| 310 | const cached = parsedHtmlCache.get(html) | 341 | const cached = parsedHtmlCache.get(html) |
| 311 | if (cached) return cached | 342 | if (cached) return proxyNode(cached) |
| 312 | const doc = ultraParse(html) | 343 | const doc = ultraParse(html) |
| 313 | parsedHtmlCache.set(html, doc) | 344 | parsedHtmlCache.set(html, doc) |
| 314 | return doc | 345 | return proxyNode(doc) |
| 315 | } | 346 | } |
| 316 | 347 | ||
| 317 | export const findNode = (doc: NodeType, selector: string): NodeType => { | 348 | export const findNode = (doc: NodeType, selector: string): NodeType => { | ... | ... |
| ... | @@ -8,6 +8,7 @@ | ... | @@ -8,6 +8,7 @@ |
| 8 | "dependencies": { | 8 | "dependencies": { |
| 9 | "@isaacs/ttlcache": "^1.4.1", | 9 | "@isaacs/ttlcache": "^1.4.1", |
| 10 | "@reduxjs/toolkit": "^2.2.5", | 10 | "@reduxjs/toolkit": "^2.2.5", |
| 11 | "html-entities": "^2.5.2", | ||
| 11 | "parsel-js": "^1.1.2", | 12 | "parsel-js": "^1.1.2", |
| 12 | "ultrahtml": "^1.5.3" | 13 | "ultrahtml": "^1.5.3" |
| 13 | }, | 14 | }, |
| ... | @@ -3200,6 +3201,21 @@ | ... | @@ -3200,6 +3201,21 @@ |
| 3200 | "url": "https://opencollective.com/unified" | 3201 | "url": "https://opencollective.com/unified" |
| 3201 | } | 3202 | } |
| 3202 | }, | 3203 | }, |
| 3204 | "node_modules/html-entities": { | ||
| 3205 | "version": "2.5.2", | ||
| 3206 | "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", | ||
| 3207 | "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", | ||
| 3208 | "funding": [ | ||
| 3209 | { | ||
| 3210 | "type": "github", | ||
| 3211 | "url": "https://github.com/sponsors/mdevils" | ||
| 3212 | }, | ||
| 3213 | { | ||
| 3214 | "type": "patreon", | ||
| 3215 | "url": "https://patreon.com/mdevils" | ||
| 3216 | } | ||
| 3217 | ] | ||
| 3218 | }, | ||
| 3203 | "node_modules/html-escaper": { | 3219 | "node_modules/html-escaper": { |
| 3204 | "version": "3.0.3", | 3220 | "version": "3.0.3", |
| 3205 | "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", | 3221 | "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", | ... | ... |
| ... | @@ -12,6 +12,7 @@ | ... | @@ -12,6 +12,7 @@ |
| 12 | "dependencies": { | 12 | "dependencies": { |
| 13 | "@isaacs/ttlcache": "^1.4.1", | 13 | "@isaacs/ttlcache": "^1.4.1", |
| 14 | "@reduxjs/toolkit": "^2.2.5", | 14 | "@reduxjs/toolkit": "^2.2.5", |
| 15 | "html-entities": "^2.5.2", | ||
| 15 | "parsel-js": "^1.1.2", | 16 | "parsel-js": "^1.1.2", |
| 16 | "ultrahtml": "^1.5.3" | 17 | "ultrahtml": "^1.5.3" |
| 17 | }, | 18 | }, | ... | ... |
-
Please register or sign in to post a comment