Skip to content

Add new HTML parser options #136

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [v0.2.23] - 2025-04-08

## [v0.2.24] - 2025-04-17

### Added
- Add parser for web component/shadow DOM

### Changed
- `createTrustedHTMLTemplate` now throws if not given a `TrustedTypePolicy`

### Added
- Add `createTrustedHTMLTemplate()` to create trusted HTML generating tagged templates

Expand Down
3 changes: 2 additions & 1 deletion core.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ export {

export {
text, createStyleSheet, createCSSParser, css, lightCSS, darkCSS ,
styleSheetToFile, styleSheetToLink, createHTMLParser, html, doc,
styleSheetToFile, styleSheetToLink, createHTMLParser, html, doc, trustedHTML,
htmlUnsafe, docUnsafe, htmlToFile, createTrustedHTMLTemplate, xml, svg, json, math, url,
createShadowParser, shadow, el,
} from './parsers.js';

export {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aegisjsproject/core",
"version": "0.2.23",
"version": "0.2.24",
"description": "A fast, secure, modern, light-weight, and simple JS library for creating web components and more!",
"keywords": [
"aegis",
Expand Down
5 changes: 4 additions & 1 deletion parsers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ export {
createStyleSheet, createCSSParser, css, lightCSS,
darkCSS, styleSheetToFile, styleSheetToLink,
} from './parsers/css.js';
export { createHTMLParser, html, doc, htmlUnsafe, docUnsafe, htmlToFile, createTrustedHTMLTemplate } from './parsers/html.js';
export {
createHTMLParser, html, doc, htmlUnsafe, docUnsafe, htmlToFile,
createTrustedHTMLTemplate, trustedHTML, createShadowParser, shadow, el,
} from './parsers/html.js';
export { xml } from './parsers/xml.js';
export { svg } from './parsers/svg.js';
export { json } from './parsers/json.js';
Expand Down
50 changes: 48 additions & 2 deletions parsers/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,57 @@ const sanitizer = Object.freeze({

export const html = createHTMLParser(sanitizer, { mapper: stringify });

export const el = (...args) => html.apply(null, args)?.firstElementChild;

export function createShadowParser({
tagName = 'div',
mode = 'open',
clonable = true,
serializable = true,
delegatesFocus = false,
slotAssignment = 'named',
sanitizer: sanitizerConfig = sanitizer,
exportParts,
} = {}) {
const parser = createHTMLParser(sanitizerConfig, { mapper: stringify });

if (Array.isArray(exportParts)) {
exportParts = exportParts.join(', ');
} else if (typeof exportParts === 'object') {
exportParts = Object.entries(exportParts).map(([k, v]) => `${k}: ${v}`).join(', ');
}

return (...args) => {
const host = document.createElement(tagName);
const shadowRoot = host.attachShadow({ mode, clonable, serializable, delegatesFocus, slotAssignment });

shadowRoot.append(parser.apply(parser, args));

if (typeof exportParts === 'string') {
host.setAttribute('exportparts', exportParts);
}

return host;
};
}

export const shadow = createShadowParser();

export function createTrustedHTMLTemplate(policy) {
if (isTrustPolicy(policy)) {
return (...args) => policy.createHTML(String.raw.apply(null, args));
return (strings, ...values) => policy.createHTML(String.raw(strings, ...values.map(stringify)));
} else {
throw new TypeError('Not a Trusted Types Policy.');
}
}

export function trustedHTML(strings, ...values) {
if (isTrustPolicy(trustedTypes?.defaultPolicy)) {
return trustedTypes.defaultPolicy.createHTML(String.raw(strings, ...values.map(stringify)));
} else if (! ('trustedTypes' in globalThis)) {
throw new Error('Trusted Types is not supported.');
} else {
return String.raw;
throw new TypeError('No default Trusted Types Policy is available.');
}
}

Expand Down
Loading