@visulima/html 0.0.1 → 1.0.0-alpha.2

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.
@@ -0,0 +1,422 @@
1
+ import { Properties } from 'csstype';
2
+ export { Properties as CSSProperties } from 'csstype';
3
+ export { default as sanitizeHtml } from 'sanitize-html';
4
+
5
+ type FlexibleCSSProperties$1 = {
6
+ [K in keyof Properties]?: Properties[K] | string | number | null | undefined;
7
+ };
8
+ declare function css(strings: TemplateStringsArray, ...values: unknown[]): string;
9
+ declare function css(value: string | FlexibleCSSProperties$1 | Properties, escape?: boolean): string;
10
+
11
+ declare const escapeHtml: (value: unknown, isAttribute?: boolean) => string;
12
+
13
+ declare function html(strings: TemplateStringsArray, ...values: unknown[]): string;
14
+ declare function html(value: string, escape?: boolean): string;
15
+
16
+ /**
17
+ * Escapes a string for direct interpolation into an external
18
+ * CSS style sheet, within a `<style>` element, or in a selector.
19
+ *
20
+ * Uses identical logic to
21
+ * [`CSS.escape`](https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape_static)
22
+ * in browsers.
23
+ *
24
+ * @param str The string to escape.
25
+ * @returns The escaped string.
26
+ *
27
+ * @example Usage
28
+ * ```ts
29
+ * import { escapeCss } from "@std/html/unstable-escape-css";
30
+ * import { assertEquals } from "@std/assert";
31
+ *
32
+ * // Invalid in a CSS selector, even though it's a valid HTML ID
33
+ * const elementId = "123";
34
+ * // Unsafe for interpolation
35
+ * const contentInput = `<!-- '" --></style>`;
36
+ *
37
+ * const selector = `#${escapeCss(elementId)}`;
38
+ * const content = `"${escapeCss(contentInput)}"`;
39
+ *
40
+ * // Usable as a CSS selector
41
+ * assertEquals(selector, String.raw`#\31 23`);
42
+ * // Safe for interpolation
43
+ * assertEquals(content, String.raw`"\<\!--\ \'\"\ --\>\<\/style\>"`);
44
+ *
45
+ * // Usage
46
+ * `<style>
47
+ * ${selector}::after {
48
+ * content: ${content};
49
+ * }
50
+ * </style>`;
51
+ * ```
52
+ */ declare function escapeCss(str: string): string;
53
+
54
+ /** Options for {@linkcode escapeJs} */ type EscapeJsOptions = {
55
+ /**
56
+ * The number of spaces or tab to use for indentation in the output.
57
+ * If not specified, no extra whitespace is added.
58
+ */ space?: number | "\t";
59
+ };
60
+ /**
61
+ * Escapes a JavaScript object or other data for safe interpolation inside a `<script>` tag.
62
+ *
63
+ * The data must be JSON-serializable (plain object, array, string, number (excluding `NaN`/infinities), boolean, or null).
64
+ *
65
+ * The output is fully JSON-compatible, with additional escaping of sequences that can be problematic within `<script>` tags.
66
+ *
67
+ * @param data The data to escape.
68
+ * @param options Options for escaping.
69
+ * @returns The escaped string.
70
+ *
71
+ * @example Escaping a string
72
+ * ```ts
73
+ * import { escapeJs } from "@std/html/unstable-escape-js";
74
+ * import { assertEquals } from "@std/assert";
75
+ * const input = "\u2028\u2029</script>";
76
+ * assertEquals(escapeJs(input), '"\\u2028\\u2029\\u003c/script>"');
77
+ * ```
78
+ *
79
+ * @example Escaping an object
80
+ * ```ts
81
+ * import { escapeJs } from "@std/html/unstable-escape-js";
82
+ * import { assertEquals } from "@std/assert";
83
+ * const input = {
84
+ * "<SCRIPT>": "</script>",
85
+ * "<!--": "\u2028\u2029<>",
86
+ * };
87
+ * assertEquals(
88
+ * escapeJs(input),
89
+ * '{"\\u003cSCRIPT>":"\\u003c/script>","\\u003c!--":"\\u2028\\u2029<>"}',
90
+ * );
91
+ * ```
92
+ *
93
+ * @example Interpolating arbitrary data in a script tag
94
+ * ```ts no-assert ignore
95
+ * // might be nested arbitrarily deeply
96
+ * declare const data: string | number | Record<string, string> | Record<string, Record<string, string>>;
97
+ * const scriptHtml = `<script>window.handleData(${escapeJs(data)})</script>`;
98
+ * ```
99
+ *
100
+ * @example Interpolating into a JSON script (e.g. importmap)
101
+ * ```ts no-assert ignore
102
+ * const importMap = { imports: { zod: 'https://esm.sh/v131/zod@3.21.4' } };
103
+ * const importMapHtml = `<script type="importmap">${escapeJs(importMap)}</script>`;
104
+ * ```
105
+ */ declare function escapeJs(data: unknown, options?: EscapeJsOptions): string;
106
+
107
+ /**
108
+ * Returns whether the given string is a valid custom element name, as per the
109
+ * requirements defined in
110
+ * {@link https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name}.
111
+ *
112
+ * @experimental **UNSTABLE**: New API, yet to be vetted.
113
+ *
114
+ * The element name must not be any of the following:
115
+ * - `annotation-xml`
116
+ * - `color-profile`
117
+ * - `font-face`
118
+ * - `font-face-src`
119
+ * - `font-face-uri`
120
+ * - `font-face-format`
121
+ * - `font-face-name`
122
+ * - `missing-glyph`
123
+ *
124
+ * @example Usage
125
+ *
126
+ * Using a valid custom element name
127
+ *
128
+ * ```ts
129
+ * import { isValidCustomElementName } from "@std/html/unstable-is-valid-custom-element-name";
130
+ * import { assertEquals } from "@std/assert";
131
+ *
132
+ * assertEquals(isValidCustomElementName("custom-element"), true);
133
+ * assertEquals(isValidCustomElementName("font-face"), false);
134
+ * assertEquals(isValidCustomElementName("custom-element@"), false);
135
+ * ```
136
+ *
137
+ * @param elementName The element name to be validate
138
+ * @returns `true` if the element name is valid, `false` otherwise.
139
+ */ declare function isValidCustomElementName(elementName: string): boolean;
140
+
141
+ type Level = 'xml' | 'html4' | 'html5' | 'all';
142
+ interface CommonOptions {
143
+ level?: Level;
144
+ }
145
+ type EncodeMode = 'specialChars' | 'nonAscii' | 'nonAsciiPrintable' | 'nonAsciiPrintableOnly' | 'extensive';
146
+ interface EncodeOptions extends CommonOptions {
147
+ mode?: EncodeMode;
148
+ numeric?: 'decimal' | 'hexadecimal';
149
+ }
150
+ type DecodeScope = 'strict' | 'body' | 'attribute';
151
+ interface DecodeOptions extends CommonOptions {
152
+ scope?: DecodeScope;
153
+ }
154
+ /** Encodes all the necessary (specified by `level`) characters in the text */
155
+ declare function encode(text: string | undefined | null, { mode, numeric, level }?: EncodeOptions): string;
156
+ /** Decodes a single entity */
157
+ declare function decodeEntity(entity: string | undefined | null, { level }?: CommonOptions): string;
158
+ /** Decodes all entities in the text */
159
+ declare function decode(text: string | undefined | null, { level, scope }?: DecodeOptions): string;
160
+
161
+ type HtmlTags =
162
+ | 'a'
163
+ | 'abbr'
164
+ | 'address'
165
+ | 'area'
166
+ | 'article'
167
+ | 'aside'
168
+ | 'audio'
169
+ | 'b'
170
+ | 'base'
171
+ | 'bdi'
172
+ | 'bdo'
173
+ | 'blockquote'
174
+ | 'body'
175
+ | 'br'
176
+ | 'button'
177
+ | 'canvas'
178
+ | 'caption'
179
+ | 'cite'
180
+ | 'code'
181
+ | 'col'
182
+ | 'colgroup'
183
+ | 'data'
184
+ | 'datalist'
185
+ | 'dd'
186
+ | 'del'
187
+ | 'details'
188
+ | 'dfn'
189
+ | 'dialog'
190
+ | 'div'
191
+ | 'dl'
192
+ | 'dt'
193
+ | 'em'
194
+ | 'embed'
195
+ | 'fieldset'
196
+ | 'figcaption'
197
+ | 'figure'
198
+ | 'footer'
199
+ | 'form'
200
+ | 'h1'
201
+ | 'h2'
202
+ | 'h3'
203
+ | 'h4'
204
+ | 'h5'
205
+ | 'h6'
206
+ | 'head'
207
+ | 'header'
208
+ | 'hgroup'
209
+ | 'hr'
210
+ | 'html'
211
+ | 'i'
212
+ | 'iframe'
213
+ | 'img'
214
+ | 'input'
215
+ | 'ins'
216
+ | 'kbd'
217
+ | 'label'
218
+ | 'legend'
219
+ | 'li'
220
+ | 'link'
221
+ | 'main'
222
+ | 'map'
223
+ | 'mark'
224
+ | 'math'
225
+ | 'menu'
226
+ | 'meta'
227
+ | 'meter'
228
+ | 'nav'
229
+ | 'noscript'
230
+ | 'object'
231
+ | 'ol'
232
+ | 'optgroup'
233
+ | 'option'
234
+ | 'output'
235
+ | 'p'
236
+ | 'picture'
237
+ | 'pre'
238
+ | 'progress'
239
+ | 'q'
240
+ | 'rp'
241
+ | 'rt'
242
+ | 'ruby'
243
+ | 's'
244
+ | 'samp'
245
+ | 'script'
246
+ | 'search'
247
+ | 'section'
248
+ | 'select'
249
+ | 'selectedcontent'
250
+ | 'slot'
251
+ | 'small'
252
+ | 'source'
253
+ | 'span'
254
+ | 'strong'
255
+ | 'style'
256
+ | 'sub'
257
+ | 'summary'
258
+ | 'sup'
259
+ | 'svg'
260
+ | 'table'
261
+ | 'tbody'
262
+ | 'td'
263
+ | 'template'
264
+ | 'textarea'
265
+ | 'tfoot'
266
+ | 'th'
267
+ | 'thead'
268
+ | 'time'
269
+ | 'title'
270
+ | 'tr'
271
+ | 'track'
272
+ | 'u'
273
+ | 'ul'
274
+ | 'var'
275
+ | 'video'
276
+ | 'wbr';
277
+
278
+ type VoidHtmlTags =
279
+ | 'area'
280
+ | 'base'
281
+ | 'br'
282
+ | 'col'
283
+ | 'embed'
284
+ | 'hr'
285
+ | 'img'
286
+ | 'input'
287
+ | 'link'
288
+ | 'meta'
289
+ | 'source'
290
+ | 'track'
291
+ | 'wbr';
292
+
293
+ /**
294
+ List of standard HTML tags.
295
+
296
+ @example
297
+ ```
298
+ import htmlTags from 'html-tags';
299
+
300
+ console.log(htmlTags);
301
+ //=> ['a', 'abbr', 'acronym', …]
302
+ ```
303
+ */
304
+ declare const htmlTags: readonly HtmlTags[];
305
+
306
+ /**
307
+ List of standard, self-closing HTML tags.
308
+
309
+ @example
310
+ ```
311
+ import {voidHtmlTags} from 'html-tags';
312
+
313
+ console.log(voidHtmlTags);
314
+ //=> ['area', 'base', 'br', …]
315
+ ```
316
+ */
317
+ declare const voidHtmlTags: readonly VoidHtmlTags[];
318
+
319
+ type Range$1 =
320
+ | [from: number, to: number]
321
+ | [from: number, to: number, whatToInsert: string | null | undefined];
322
+ interface Opts$1 {
323
+ limitToBeAddedWhitespace: boolean;
324
+ limitLinebreaksCount: number;
325
+ mergeType: 1 | 2 | "1" | "2" | undefined;
326
+ }
327
+ declare class Ranges$1 {
328
+ constructor(originalOpts?: Partial<Opts$1>);
329
+ ranges: Range$1[];
330
+ opts: Opts$1;
331
+ add(
332
+ originalFrom: number,
333
+ originalTo?: number,
334
+ addVal?: undefined | null | string,
335
+ ): void;
336
+ add(originalFrom: Range$1[] | Range$1 | null): void;
337
+ push(
338
+ originalFrom: number,
339
+ originalTo?: number,
340
+ addVal?: undefined | null | string,
341
+ ): void;
342
+ push(originalFrom: Range$1[] | Range$1 | null): void;
343
+ current(): null | Range$1[];
344
+ wipe(): void;
345
+ replace(givenRanges: Range$1[]): void;
346
+ last(): Range$1 | null;
347
+ }
348
+
349
+ type Range =
350
+ | [from: number, to: number]
351
+ | [from: number, to: number, whatToInsert: string | null | undefined];
352
+ type Ranges = Range[] | null;
353
+ interface Attribute {
354
+ nameStarts: number;
355
+ nameEnds: number;
356
+ equalsAt?: number;
357
+ name: string;
358
+ valueStarts?: number;
359
+ valueEnds?: number;
360
+ value?: string;
361
+ }
362
+ interface Tag {
363
+ attributes: Attribute[];
364
+ lastClosingBracketAt: number;
365
+ lastOpeningBracketAt: number;
366
+ slashPresent: number;
367
+ leftOuterWhitespace: number;
368
+ onlyPlausible: boolean;
369
+ nameStarts: number;
370
+ nameContainsLetters: boolean;
371
+ nameEnds: number;
372
+ name: string;
373
+ }
374
+ interface CbObj {
375
+ tag: Tag;
376
+ deleteFrom: null | number;
377
+ deleteTo: null | number;
378
+ insert: null | undefined | string;
379
+ rangesArr: Ranges$1;
380
+ proposedReturn: Range | null;
381
+ }
382
+ interface Opts {
383
+ ignoreTags: string[];
384
+ ignoreTagsWithTheirContents: string[];
385
+ onlyStripTags: string[];
386
+ stripTogetherWithTheirContents: string[];
387
+ skipHtmlDecoding: boolean;
388
+ trimOnlySpaces: boolean;
389
+ stripRecognisedHTMLOnly: boolean;
390
+ dumpLinkHrefsNearby: {
391
+ enabled?: boolean;
392
+ putOnNewLine?: boolean;
393
+ wrapHeads?: string;
394
+ wrapTails?: string;
395
+ };
396
+ ignoreIndentations: boolean;
397
+ cb: null | ((cbObj: CbObj) => void);
398
+ reportProgressFunc: null | ((percDone: number) => void);
399
+ reportProgressFuncFrom: number;
400
+ reportProgressFuncTo: number;
401
+ }
402
+ declare const defaults: Opts;
403
+ interface Res {
404
+ log: {
405
+ timeTakenInMilliseconds: number;
406
+ };
407
+ result: string;
408
+ ranges: Ranges;
409
+ allTagLocations: [number, number][];
410
+ filteredTagLocations: [number, number][];
411
+ }
412
+ /**
413
+ * Strips HTML tags from strings. No parser, accepts mixed sources.
414
+ */
415
+ declare function stripHtml(str: string, opts?: Partial<Opts>): Res;
416
+
417
+ type FlexibleCSSProperties = {
418
+ [K in keyof Properties]?: Properties[K] | string | number | null | undefined;
419
+ };
420
+
421
+ export { css, decode, decodeEntity, encode, escapeCss, escapeHtml, escapeJs, html, htmlTags, isValidCustomElementName, stripHtml, defaults as stripHtmlDefaultOptions, voidHtmlTags };
422
+ export type { DecodeOptions, DecodeScope, EncodeMode, EncodeOptions, FlexibleCSSProperties, Level, Attribute as StripHtmlAttribute, CbObj as StripHtmlCbObj, Opts as StripHtmlOptions, Res as StripHtmlResult, Tag as StripHtmlTag };
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ export { default as css } from './packem_shared/css-eLBFmNQq.js';
2
+ export { default as escapeHtml } from './packem_shared/escapeHtml-Cztfu84O.js';
3
+ export { default as html } from './packem_shared/html-B-Khp3Xj.js';
4
+ export { escapeCss } from './packem_shared/escapeCss-gSWL0xVj.js';
5
+ export { escapeJs } from './packem_shared/escapeJs-8hCFOEdN.js';
6
+ export { isValidCustomElementName } from './packem_shared/isValidCustomElementName-Czb_BiVq.js';
7
+ export { decode, decodeEntity, encode } from './packem_shared/encode-jgknlkNE.js';
8
+ export { default as sanitizeHtml } from 'sanitize-html';
9
+ export { stripHtml, defaults as stripHtmlDefaultOptions } from './packem_shared/stripHtmlDefaultOptions-Dj_FII9M.js';
10
+ export { default as htmlTags } from './packem_shared/htmlTags-CnZinEi6.js';
11
+ export { default as voidHtmlTags } from './packem_shared/voidHtmlTags-Db3mUI2j.js';
@@ -0,0 +1,5 @@
1
+ function getDefaultExportFromCjs (x) {
2
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
3
+ }
4
+
5
+ export { getDefaultExportFromCjs as g };
@@ -0,0 +1,32 @@
1
+ import { escapeCss } from './escapeCss-gSWL0xVj.js';
2
+
3
+ const cssObjectToString = (cssObject) => {
4
+ const styles = [];
5
+ Object.entries(cssObject).forEach(([key, value]) => {
6
+ if (value !== void 0 && value !== null) {
7
+ const cssKey = key.replaceAll(/([A-Z])/g, "-$1").toLowerCase();
8
+ styles.push(`${cssKey}: ${String(value)};`);
9
+ }
10
+ });
11
+ return styles.join(" ");
12
+ };
13
+ function css(stringsOrValue, ...valuesOrEscape) {
14
+ if (Array.isArray(stringsOrValue) && "raw" in stringsOrValue) {
15
+ const strings = stringsOrValue;
16
+ let result = strings[0] ?? "";
17
+ for (const [i, element] of valuesOrEscape.entries()) {
18
+ result += String(element ?? "");
19
+ result += strings[i + 1] ?? "";
20
+ }
21
+ return result;
22
+ }
23
+ const value = stringsOrValue;
24
+ const escape = valuesOrEscape[0];
25
+ const cssString = typeof value === "string" ? value : cssObjectToString(value);
26
+ if (escape === true) {
27
+ return escapeCss(cssString);
28
+ }
29
+ return cssString;
30
+ }
31
+
32
+ export { css as default };