mirror of
https://github.com/tenrok/BBob.git
synced 2026-05-15 11:59:37 +03:00
8797f7f363
* feat: initial typescript support * feat: typescript support * feat(plugin-helper): move files to typescript * chore: update lock files * feat: preset types * fix: build * fix: benchmark * fix: remove pnpm cache * fix: bench action * fix: pnpm recursive install * fix: nx cache * fix: lock file * fix: workflows * fix: lerna support in pnpm * fix: pnpm workspace * fix: remove unused files * fix: pnpm lock file * fix: update lerna for support pnpm * fix: lerna bootstrap * fix: rollup build * fix: update nx * fix: build * fix: add nx dep target * fix: remove nx cache * fix: workflow run on push only for master * fix: test workflow run on push only for master * fix: remove parallel for gen types * fix: benchmark * fix: benchmark imports * fix: pnpm * fix: types errors and pnpm * fix: types * fix: types * refactor: parser * fix(parser): tests * fix: preset tests * fix: react types * fix: react type declarations * fix: pnpm lock file * fix: react preset types * fix: lock file * fix: vue2 types * feat: dev container support * fix: types * fix: types * refactor: rewrite pkg-task, add nx gen-types deps, fix react/render.ts * refactor: types * fix: types * fix: rename gen-types to types * fix: nx build order * fix: nx reset * fix: define nx deps explicit * fix: build * fix: nx * fix: nx order build * fix: nx deps * fix: bbob cli tests * fix: tests * fix: cli tests and import * fix: test cover * fix: cli cover
126 lines
2.9 KiB
TypeScript
126 lines
2.9 KiB
TypeScript
import { N } from './char';
|
|
import type { TagNode } from "./TagNode";
|
|
import type { NodeContent, StringNode } from "./types";
|
|
|
|
function isTagNode(el: unknown): el is TagNode {
|
|
return typeof el === 'object' && el !== null && 'tag' in el;
|
|
}
|
|
|
|
function isStringNode(el: unknown): el is StringNode {
|
|
return typeof el === 'string';
|
|
}
|
|
|
|
// check string is end of line
|
|
function isEOL(el: string) {
|
|
return el === N
|
|
}
|
|
|
|
function keysReduce<Res, Def extends Res, T extends Record<string, unknown>>(obj: T, reduce: (acc: Def, key: keyof T) => Res, def: Def): Res {
|
|
const keys = Object.keys(obj)
|
|
|
|
return keys.reduce((acc, key) => reduce(acc, key), def)
|
|
}
|
|
|
|
function getNodeLength(node: NodeContent): number {
|
|
if (isTagNode(node) && Array.isArray(node.content)) {
|
|
return node.content.reduce<number>((count, contentNode) => {
|
|
return count + getNodeLength(contentNode)
|
|
}, 0);
|
|
}
|
|
|
|
if (isStringNode(node)) {
|
|
return String(node).length;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
function appendToNode(node: TagNode, value: NodeContent) {
|
|
if (Array.isArray(node.content)) {
|
|
node.content.push(value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Replaces " to &qquot;
|
|
* @param {string} value
|
|
*/
|
|
function escapeAttrValue(value: string) {
|
|
return value
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"')
|
|
.replace(/'/g, ''')
|
|
// eslint-disable-next-line no-script-url
|
|
.replace(/(javascript|data|vbscript):/gi, '$1%3A');
|
|
}
|
|
|
|
/**
|
|
* @deprecated use escapeAttrValue
|
|
*/
|
|
const escapeHTML = escapeAttrValue
|
|
|
|
/**
|
|
* Accept name and value and return valid html5 attribute string
|
|
*/
|
|
function attrValue<AttrValue = unknown>(name: string, value: AttrValue) {
|
|
// in case of performance
|
|
switch (typeof value) {
|
|
case 'boolean':
|
|
return value ? `${name}` : ''
|
|
case 'number':
|
|
return `${name}="${value}"`
|
|
case 'string':
|
|
return `${name}="${escapeAttrValue(value as string)}"`
|
|
case 'object':
|
|
return `${name}="${escapeAttrValue(JSON.stringify(value))}"`
|
|
default:
|
|
return ''
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Transforms attrs to html params string
|
|
* @example
|
|
* attrsToString({ 'foo': true, 'bar': bar' }) => 'foo="true" bar="bar"'
|
|
*/
|
|
function attrsToString<AttrValue = unknown>(values: Record<string, AttrValue> | null) {
|
|
// To avoid some malformed attributes
|
|
if (values == null) {
|
|
return '';
|
|
}
|
|
|
|
return keysReduce(
|
|
values,
|
|
(arr, key) => [...arr, attrValue(key, values[key])],
|
|
[''],
|
|
).join(' ');
|
|
}
|
|
|
|
/**
|
|
* Gets value from
|
|
* @example
|
|
* getUniqAttr({ 'foo': true, 'bar': bar' }) => 'bar'
|
|
*/
|
|
function getUniqAttr<Value>(attrs: Record<string, Value>) {
|
|
return keysReduce(
|
|
attrs,
|
|
(res, key) => (attrs[key] === key ? attrs[key] : null),
|
|
null,
|
|
)
|
|
}
|
|
|
|
export {
|
|
attrsToString,
|
|
attrValue,
|
|
appendToNode,
|
|
escapeHTML,
|
|
escapeAttrValue,
|
|
getNodeLength,
|
|
getUniqAttr,
|
|
isTagNode,
|
|
isStringNode,
|
|
isEOL,
|
|
};
|