Socket
Socket
Sign inDemoInstall

@bbob/html

Package Overview
Dependencies
Maintainers
0
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bbob/html - npm Package Compare versions

Comparing version 3.0.2 to 4.0.0

LICENSE

1089

dist/index.js
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@bbob/core'), require('@bbob/plugin-helper')) :
typeof define === 'function' && define.amd ? define(['exports', '@bbob/core', '@bbob/plugin-helper'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.BbobHtml = {}, global.core, global.pluginHelper));
})(this, (function (exports, core, pluginHelper) { 'use strict';
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.BbobHtml = {}));
})(this, (function (exports) { 'use strict';
const N = '\n';
const TAB = '\t';
const EQ = '=';
const QUOTEMARK = '"';
const SPACE = ' ';
const OPEN_BRAKET = '[';
const CLOSE_BRAKET = ']';
const SLASH = '/';
const BACKSLASH = '\\';
function isTagNode(el) {
return typeof el === 'object' && el !== null && 'tag' in el;
}
function isStringNode(el) {
return typeof el === 'string';
}
function keysReduce(obj, reduce, def) {
const keys = Object.keys(obj);
return keys.reduce((acc, key)=>reduce(acc, key, obj), def);
}
function getNodeLength(node) {
if (isTagNode(node) && Array.isArray(node.content)) {
return node.content.reduce((count, contentNode)=>{
return count + getNodeLength(contentNode);
}, 0);
}
if (isStringNode(node)) {
return String(node).length;
}
return 0;
}
function appendToNode(node, value) {
if (Array.isArray(node.content)) {
node.content.push(value);
}
}
/**
* Replaces " to &qquot;
* @param {string} value
*/ function escapeAttrValue(value) {
return value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;')// eslint-disable-next-line no-script-url
.replace(/(javascript|data|vbscript):/gi, '$1%3A');
}
/**
* Accept name and value and return valid html5 attribute string
*/ function attrValue(name, value) {
// in case of performance
switch(typeof value){
case 'boolean':
return value ? `${name}` : '';
case 'number':
return `${name}="${value}"`;
case 'string':
return `${name}="${escapeAttrValue(value)}"`;
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(values) {
// To avoid some malformed attributes
if (values == null) {
return '';
}
return keysReduce(values, (arr, key, obj)=>[
...arr,
attrValue(key, obj[key])
], [
''
]).join(' ');
}
/**
* Gets value from
* @example
* getUniqAttr({ 'foo': true, 'bar': bar' }) => 'bar'
*/ function getUniqAttr(attrs) {
return keysReduce(attrs || {}, (res, key, obj)=>obj[key] === key ? obj[key] : null, null);
}
const getTagAttrs = (tag, params)=>{
const uniqAttr = getUniqAttr(params);
if (uniqAttr) {
const tagAttr = attrValue(tag, uniqAttr);
const attrs = {
...params
};
delete attrs[String(uniqAttr)];
const attrsStr = attrsToString(attrs);
return `${tagAttr}${attrsStr}`;
}
return `${tag}${attrsToString(params)}`;
};
const renderContent = (content, openTag, closeTag)=>{
const toString = (node)=>{
if (isTagNode(node)) {
return node.toString({
openTag,
closeTag
});
}
return String(node);
};
if (Array.isArray(content)) {
return content.reduce((r, node)=>{
if (node !== null) {
return r + toString(node);
}
return r;
}, '');
}
if (content) {
return toString(content);
}
return null;
};
class TagNode {
attr(name, value) {
if (typeof value !== 'undefined') {
this.attrs[name] = value;
}
return this.attrs[name];
}
append(value) {
return appendToNode(this, value);
}
get length() {
return getNodeLength(this);
}
toTagStart({ openTag = OPEN_BRAKET, closeTag = CLOSE_BRAKET } = {}) {
const tagAttrs = getTagAttrs(this.tag, this.attrs);
return `${openTag}${tagAttrs}${closeTag}`;
}
toTagEnd({ openTag = OPEN_BRAKET, closeTag = CLOSE_BRAKET } = {}) {
return `${openTag}${SLASH}${this.tag}${closeTag}`;
}
toTagNode() {
return new TagNode(this.tag.toLowerCase(), this.attrs, this.content);
}
toString({ openTag = OPEN_BRAKET, closeTag = CLOSE_BRAKET } = {}) {
const content = this.content ? renderContent(this.content, openTag, closeTag) : '';
const tagStart = this.toTagStart({
openTag,
closeTag
});
if (this.content === null || Array.isArray(this.content) && this.content.length === 0) {
return tagStart;
}
return `${tagStart}${content}${this.toTagEnd({
openTag,
closeTag
})}`;
}
static create(tag, attrs = {}, content = null) {
return new TagNode(tag, attrs, content);
}
static isOf(node, type) {
return node.tag === type;
}
constructor(tag, attrs, content){
this.tag = tag;
this.attrs = attrs;
this.content = content;
}
}
// type, value, line, row,
const TOKEN_TYPE_ID = 't'; // 0;
const TOKEN_VALUE_ID = 'v'; // 1;
const TOKEN_COLUMN_ID = 'r'; // 2;
const TOKEN_LINE_ID = 'l'; // 3;
const TOKEN_TYPE_WORD = 1; // 'word';
const TOKEN_TYPE_TAG = 2; // 'tag';
const TOKEN_TYPE_ATTR_NAME = 3; // 'attr-name';
const TOKEN_TYPE_ATTR_VALUE = 4; // 'attr-value';
const TOKEN_TYPE_SPACE = 5; // 'space';
const TOKEN_TYPE_NEW_LINE = 6; // 'new-line';
const getTokenValue = (token)=>{
if (token && typeof token[TOKEN_VALUE_ID] !== 'undefined') {
return token[TOKEN_VALUE_ID];
}
return '';
};
const getTokenLine = (token)=>token && token[TOKEN_LINE_ID] || 0;
const getTokenColumn = (token)=>token && token[TOKEN_COLUMN_ID] || 0;
const isTextToken = (token)=>{
if (token && typeof token[TOKEN_TYPE_ID] !== 'undefined') {
return token[TOKEN_TYPE_ID] === TOKEN_TYPE_SPACE || token[TOKEN_TYPE_ID] === TOKEN_TYPE_NEW_LINE || token[TOKEN_TYPE_ID] === TOKEN_TYPE_WORD;
}
return false;
};
const isTagToken = (token)=>{
if (token && typeof token[TOKEN_TYPE_ID] !== 'undefined') {
return token[TOKEN_TYPE_ID] === TOKEN_TYPE_TAG;
}
return false;
};
const isTagEnd = (token)=>getTokenValue(token).charCodeAt(0) === SLASH.charCodeAt(0);
const isTagStart = (token)=>!isTagEnd(token);
const isAttrNameToken = (token)=>{
if (token && typeof token[TOKEN_TYPE_ID] !== 'undefined') {
return token[TOKEN_TYPE_ID] === TOKEN_TYPE_ATTR_NAME;
}
return false;
};
const isAttrValueToken = (token)=>{
if (token && typeof token[TOKEN_TYPE_ID] !== 'undefined') {
return token[TOKEN_TYPE_ID] === TOKEN_TYPE_ATTR_VALUE;
}
return false;
};
const getTagName = (token)=>{
const value = getTokenValue(token);
return isTagEnd(token) ? value.slice(1) : value;
};
const tokenToText = (token)=>{
let text = OPEN_BRAKET;
text += getTokenValue(token);
text += CLOSE_BRAKET;
return text;
};
/**
* @export
* @class Token
*/ class Token {
get type() {
return this[TOKEN_TYPE_ID];
}
isEmpty() {
return this[TOKEN_TYPE_ID] === 0 || isNaN(this[TOKEN_TYPE_ID]);
}
isText() {
return isTextToken(this);
}
isTag() {
return isTagToken(this);
}
isAttrName() {
return isAttrNameToken(this);
}
isAttrValue() {
return isAttrValueToken(this);
}
isStart() {
return isTagStart(this);
}
isEnd() {
return isTagEnd(this);
}
getName() {
return getTagName(this);
}
getValue() {
return getTokenValue(this);
}
getLine() {
return getTokenLine(this);
}
getColumn() {
return getTokenColumn(this);
}
toString() {
return tokenToText(this);
}
constructor(type, value, row = 0, col = 0){
this[TOKEN_LINE_ID] = row;
this[TOKEN_COLUMN_ID] = col;
this[TOKEN_TYPE_ID] = type || 0;
this[TOKEN_VALUE_ID] = String(value);
}
}
const TYPE_WORD = TOKEN_TYPE_WORD;
const TYPE_TAG = TOKEN_TYPE_TAG;
const TYPE_ATTR_NAME = TOKEN_TYPE_ATTR_NAME;
const TYPE_ATTR_VALUE = TOKEN_TYPE_ATTR_VALUE;
const TYPE_SPACE = TOKEN_TYPE_SPACE;
const TYPE_NEW_LINE = TOKEN_TYPE_NEW_LINE;
class CharGrabber {
skip(num = 1, silent) {
this.c.pos += num;
if (this.o && this.o.onSkip && !silent) {
this.o.onSkip();
}
}
hasNext() {
return this.c.len > this.c.pos;
}
getCurr() {
if (typeof this.s[this.c.pos] === 'undefined') {
return '';
}
return this.s[this.c.pos];
}
getRest() {
return this.s.substring(this.c.pos);
}
getNext() {
const nextPos = this.c.pos + 1;
return nextPos <= this.s.length - 1 ? this.s[nextPos] : null;
}
getPrev() {
const prevPos = this.c.pos - 1;
if (typeof this.s[prevPos] === 'undefined') {
return null;
}
return this.s[prevPos];
}
isLast() {
return this.c.pos === this.c.len;
}
includes(val) {
return this.s.indexOf(val, this.c.pos) >= 0;
}
grabWhile(condition, silent) {
let start = 0;
if (this.hasNext()) {
start = this.c.pos;
while(this.hasNext() && condition(this.getCurr())){
this.skip(1, silent);
}
}
return this.s.substring(start, this.c.pos);
}
grabN(num = 0) {
return this.s.substring(this.c.pos, this.c.pos + num);
}
/**
* Grabs rest of string until it find a char
*/ substrUntilChar(char) {
const { pos } = this.c;
const idx = this.s.indexOf(char, pos);
return idx >= 0 ? this.s.substring(pos, idx) : '';
}
constructor(source, options = {}){
this.s = source;
this.c = {
pos: 0,
len: source.length
};
this.o = options;
}
}
/**
* Creates a grabber wrapper for source string, that helps to iterate over string char by char
*/ const createCharGrabber = (source, options)=>new CharGrabber(source, options);
/**
* Trims string from start and end by char
* @example
* trimChar('*hello*', '*') ==> 'hello'
*/ const trimChar = (str, charToRemove)=>{
while(str.charAt(0) === charToRemove){
// eslint-disable-next-line no-param-reassign
str = str.substring(1);
}
while(str.charAt(str.length - 1) === charToRemove){
// eslint-disable-next-line no-param-reassign
str = str.substring(0, str.length - 1);
}
return str;
};
/**
* Unquotes \" to "
*/ const unquote = (str)=>str.replace(BACKSLASH + QUOTEMARK, QUOTEMARK);
// for cases <!-- -->
const EM = '!';
function createTokenOfType(type, value, r = 0, cl = 0) {
return new Token(type, value, r, cl);
}
const STATE_WORD = 0;
const STATE_TAG = 1;
const STATE_TAG_ATTRS = 2;
const TAG_STATE_NAME = 0;
const TAG_STATE_ATTR = 1;
const TAG_STATE_VALUE = 2;
const WHITESPACES = [
SPACE,
TAB
];
const SPECIAL_CHARS = [
EQ,
SPACE,
TAB
];
const isWhiteSpace = (char)=>WHITESPACES.indexOf(char) >= 0;
const isEscapeChar = (char)=>char === BACKSLASH;
const isSpecialChar = (char)=>SPECIAL_CHARS.indexOf(char) >= 0;
const isNewLine = (char)=>char === N;
const unq = (val)=>unquote(trimChar(val, QUOTEMARK));
function createLexer(buffer, options = {}) {
let row = 0;
let col = 0;
let tokenIndex = -1;
let stateMode = STATE_WORD;
let tagMode = TAG_STATE_NAME;
let contextFreeTag = '';
const tokens = new Array(Math.floor(buffer.length));
const openTag = options.openTag || OPEN_BRAKET;
const closeTag = options.closeTag || CLOSE_BRAKET;
const escapeTags = !!options.enableEscapeTags;
const contextFreeTags = (options.contextFreeTags || []).filter(Boolean).map((tag)=>tag.toLowerCase());
const nestedMap = new Map();
const onToken = options.onToken || (()=>{});
const RESERVED_CHARS = [
closeTag,
openTag,
QUOTEMARK,
BACKSLASH,
SPACE,
TAB,
EQ,
N,
EM
];
const NOT_CHAR_TOKENS = [
openTag,
SPACE,
TAB,
N
];
const isCharReserved = (char)=>RESERVED_CHARS.indexOf(char) >= 0;
const isCharToken = (char)=>NOT_CHAR_TOKENS.indexOf(char) === -1;
const isEscapableChar = (char)=>char === openTag || char === closeTag || char === BACKSLASH;
const onSkip = ()=>{
col++;
};
const checkContextFreeMode = (name, isClosingTag)=>{
if (contextFreeTag !== '' && isClosingTag) {
contextFreeTag = '';
}
if (contextFreeTag === '' && contextFreeTags.includes(name.toLowerCase())) {
contextFreeTag = name;
}
};
const chars = createCharGrabber(buffer, {
onSkip
});
/**
* Emits newly created token to subscriber
* @param {Number} type
* @param {String} value
*/ function emitToken(type, value) {
const token = createTokenOfType(type, value, row, col);
onToken(token);
tokenIndex += 1;
tokens[tokenIndex] = token;
}
function nextTagState(tagChars, isSingleValueTag) {
if (tagMode === TAG_STATE_ATTR) {
const validAttrName = (char)=>!(char === EQ || isWhiteSpace(char));
const name = tagChars.grabWhile(validAttrName);
const isEnd = tagChars.isLast();
const isValue = tagChars.getCurr() !== EQ;
tagChars.skip();
if (isEnd || isValue) {
emitToken(TYPE_ATTR_VALUE, unq(name));
} else {
emitToken(TYPE_ATTR_NAME, name);
}
if (isEnd) {
return TAG_STATE_NAME;
}
if (isValue) {
return TAG_STATE_ATTR;
}
return TAG_STATE_VALUE;
}
if (tagMode === TAG_STATE_VALUE) {
let stateSpecial = false;
const validAttrValue = (char)=>{
// const isEQ = char === EQ;
const isQM = char === QUOTEMARK;
const prevChar = tagChars.getPrev();
const nextChar = tagChars.getNext();
const isPrevSLASH = prevChar === BACKSLASH;
const isNextEQ = nextChar === EQ;
const isWS = isWhiteSpace(char);
// const isPrevWS = isWhiteSpace(prevChar);
const isNextWS = nextChar && isWhiteSpace(nextChar);
if (stateSpecial && isSpecialChar(char)) {
return true;
}
if (isQM && !isPrevSLASH) {
stateSpecial = !stateSpecial;
if (!stateSpecial && !(isNextEQ || isNextWS)) {
return false;
}
}
if (!isSingleValueTag) {
return !isWS;
// return (isEQ || isWS) === false;
}
return true;
};
const name = tagChars.grabWhile(validAttrValue);
tagChars.skip();
emitToken(TYPE_ATTR_VALUE, unq(name));
if (tagChars.isLast()) {
return TAG_STATE_NAME;
}
return TAG_STATE_ATTR;
}
const validName = (char)=>!(char === EQ || isWhiteSpace(char) || tagChars.isLast());
const name = tagChars.grabWhile(validName);
emitToken(TYPE_TAG, name);
checkContextFreeMode(name);
tagChars.skip();
// in cases when we has [url=someval]GET[/url] and we dont need to parse all
if (isSingleValueTag) {
return TAG_STATE_VALUE;
}
const hasEQ = tagChars.includes(EQ);
return hasEQ ? TAG_STATE_ATTR : TAG_STATE_VALUE;
}
function stateTag() {
const currChar = chars.getCurr();
const nextChar = chars.getNext();
chars.skip();
// detect case where we have '[My word [tag][/tag]' or we have '[My last line word'
const substr = chars.substrUntilChar(closeTag);
const hasInvalidChars = substr.length === 0 || substr.indexOf(openTag) >= 0;
if (nextChar && isCharReserved(nextChar) || hasInvalidChars || chars.isLast()) {
emitToken(TYPE_WORD, currChar);
return STATE_WORD;
}
// [myTag ]
const isNoAttrsInTag = substr.indexOf(EQ) === -1;
// [/myTag]
const isClosingTag = substr[0] === SLASH;
if (isNoAttrsInTag || isClosingTag) {
const name = chars.grabWhile((char)=>char !== closeTag);
chars.skip(); // skip closeTag
emitToken(TYPE_TAG, name);
checkContextFreeMode(name, isClosingTag);
return STATE_WORD;
}
return STATE_TAG_ATTRS;
}
function stateAttrs() {
const silent = true;
const tagStr = chars.grabWhile((char)=>char !== closeTag, silent);
const tagGrabber = createCharGrabber(tagStr, {
onSkip
});
const hasSpace = tagGrabber.includes(SPACE);
tagMode = TAG_STATE_NAME;
while(tagGrabber.hasNext()){
tagMode = nextTagState(tagGrabber, !hasSpace);
}
chars.skip(); // skip closeTag
return STATE_WORD;
}
function stateWord() {
if (isNewLine(chars.getCurr())) {
emitToken(TYPE_NEW_LINE, chars.getCurr());
chars.skip();
col = 0;
row++;
return STATE_WORD;
}
if (isWhiteSpace(chars.getCurr())) {
const word = chars.grabWhile(isWhiteSpace);
emitToken(TYPE_SPACE, word);
return STATE_WORD;
}
if (chars.getCurr() === openTag) {
if (contextFreeTag) {
const fullTagLen = openTag.length + SLASH.length + contextFreeTag.length;
const fullTagName = `${openTag}${SLASH}${contextFreeTag}`;
const foundTag = chars.grabN(fullTagLen);
const isEndContextFreeMode = foundTag === fullTagName;
if (isEndContextFreeMode) {
return STATE_TAG;
}
} else if (chars.includes(closeTag)) {
return STATE_TAG;
}
emitToken(TYPE_WORD, chars.getCurr());
chars.skip();
return STATE_WORD;
}
if (escapeTags) {
if (isEscapeChar(chars.getCurr())) {
const currChar = chars.getCurr();
const nextChar = chars.getNext();
chars.skip(); // skip the \ without emitting anything
if (nextChar && isEscapableChar(nextChar)) {
chars.skip(); // skip past the [, ] or \ as well
emitToken(TYPE_WORD, nextChar);
return STATE_WORD;
}
emitToken(TYPE_WORD, currChar);
return STATE_WORD;
}
const isChar = (char)=>isCharToken(char) && !isEscapeChar(char);
const word = chars.grabWhile(isChar);
emitToken(TYPE_WORD, word);
return STATE_WORD;
}
const word = chars.grabWhile(isCharToken);
emitToken(TYPE_WORD, word);
return STATE_WORD;
}
function tokenize() {
stateMode = STATE_WORD;
while(chars.hasNext()){
switch(stateMode){
case STATE_TAG:
stateMode = stateTag();
break;
case STATE_TAG_ATTRS:
stateMode = stateAttrs();
break;
case STATE_WORD:
default:
stateMode = stateWord();
break;
}
}
tokens.length = tokenIndex + 1;
return tokens;
}
function isTokenNested(token) {
const value = openTag + SLASH + token.getValue();
if (nestedMap.has(value)) {
return !!nestedMap.get(value);
} else {
const status = buffer.indexOf(value) > -1;
nestedMap.set(value, status);
return status;
}
}
return {
tokenize,
isTokenNested
};
}
class NodeList {
last() {
if (Array.isArray(this.n) && this.n.length > 0 && typeof this.n[this.n.length - 1] !== "undefined") {
return this.n[this.n.length - 1];
}
return null;
}
flush() {
return this.n.length ? this.n.pop() : false;
}
push(value) {
this.n.push(value);
}
toArray() {
return this.n;
}
constructor(){
this.n = [];
}
}
const createList = ()=>new NodeList();
function parse(input, opts = {}) {
const options = opts;
const openTag = options.openTag || OPEN_BRAKET;
const closeTag = options.closeTag || CLOSE_BRAKET;
const onlyAllowTags = (options.onlyAllowTags || []).filter(Boolean).map((tag)=>tag.toLowerCase());
let tokenizer = null;
/**
* Result AST of nodes
* @private
* @type {NodeList}
*/ const nodes = createList();
/**
* Temp buffer of nodes that's nested to another node
* @private
*/ const nestedNodes = createList();
/**
* Temp buffer of nodes [tag..]...[/tag]
* @private
* @type {NodeList}
*/ const tagNodes = createList();
/**
* Temp buffer of tag attributes
* @private
* @type {NodeList}
*/ const tagNodesAttrName = createList();
/**
* Cache for nested tags checks
*/ const nestedTagsMap = new Set();
function isTokenNested(token) {
const value = token.getValue();
const { isTokenNested } = tokenizer || {};
if (!nestedTagsMap.has(value) && isTokenNested && isTokenNested(token)) {
nestedTagsMap.add(value);
return true;
}
return nestedTagsMap.has(value);
}
/**
* @private
*/ function isTagNested(tagName) {
return Boolean(nestedTagsMap.has(tagName));
}
/**
* @private
*/ function isAllowedTag(value) {
if (onlyAllowTags.length) {
return onlyAllowTags.indexOf(value.toLowerCase()) >= 0;
}
return true;
}
/**
* Flushes temp tag nodes and its attributes buffers
* @private
*/ function flushTagNodes() {
if (tagNodes.flush()) {
tagNodesAttrName.flush();
}
}
/**
* @private
*/ function getNodes() {
const lastNestedNode = nestedNodes.last();
if (lastNestedNode && isTagNode(lastNestedNode)) {
return lastNestedNode.content;
}
return nodes.toArray();
}
/**
* @private
*/ function appendNodeAsString(nodes, node, isNested = true) {
if (Array.isArray(nodes) && typeof node !== "undefined") {
nodes.push(node.toTagStart({
openTag,
closeTag
}));
if (Array.isArray(node.content) && node.content.length) {
node.content.forEach((item)=>{
nodes.push(item);
});
if (isNested) {
nodes.push(node.toTagEnd({
openTag,
closeTag
}));
}
}
}
}
/**
* @private
*/ function appendNodes(nodes, node) {
if (Array.isArray(nodes) && typeof node !== "undefined") {
if (isTagNode(node)) {
if (isAllowedTag(node.tag)) {
nodes.push(node.toTagNode());
} else {
appendNodeAsString(nodes, node);
}
} else {
nodes.push(node);
}
}
}
/**
* @private
* @param {Token} token
*/ function handleTagStart(token) {
flushTagNodes();
const tagNode = TagNode.create(token.getValue(), {}, []);
const isNested = isTokenNested(token);
tagNodes.push(tagNode);
if (isNested) {
nestedNodes.push(tagNode);
} else {
const nodes = getNodes();
appendNodes(nodes, tagNode);
}
}
/**
* @private
* @param {Token} token
*/ function handleTagEnd(token) {
flushTagNodes();
const lastNestedNode = nestedNodes.flush();
if (lastNestedNode) {
const nodes = getNodes();
appendNodes(nodes, lastNestedNode);
} else if (typeof options.onError === "function") {
const tag = token.getValue();
const line = token.getLine();
const column = token.getColumn();
options.onError({
tagName: tag,
lineNumber: line,
columnNumber: column
});
}
}
/**
* @private
* @param {Token} token
*/ function handleTag(token) {
// [tag]
if (token.isStart()) {
handleTagStart(token);
}
// [/tag]
if (token.isEnd()) {
handleTagEnd(token);
}
}
/**
* @private
* @param {Token} token
*/ function handleNode(token) {
/**
* @type {TagNode}
*/ const activeTagNode = tagNodes.last();
const tokenValue = token.getValue();
const isNested = isTagNested(token.toString());
const nodes = getNodes();
if (activeTagNode !== null) {
if (token.isAttrName()) {
tagNodesAttrName.push(tokenValue);
const attrName = tagNodesAttrName.last();
if (attrName) {
activeTagNode.attr(attrName, "");
}
} else if (token.isAttrValue()) {
const attrName = tagNodesAttrName.last();
if (attrName) {
activeTagNode.attr(attrName, tokenValue);
tagNodesAttrName.flush();
} else {
activeTagNode.attr(tokenValue, tokenValue);
}
} else if (token.isText()) {
if (isNested) {
activeTagNode.append(tokenValue);
} else {
appendNodes(nodes, tokenValue);
}
} else if (token.isTag()) {
// if tag is not allowed, just pass it as is
appendNodes(nodes, token.toString());
}
} else if (token.isText()) {
appendNodes(nodes, tokenValue);
} else if (token.isTag()) {
// if tag is not allowed, just pass it as is
appendNodes(nodes, token.toString());
}
}
/**
* @private
* @param {Token} token
*/ function onToken(token) {
if (token.isTag()) {
handleTag(token);
} else {
handleNode(token);
}
}
const lexer = opts.createTokenizer ? opts.createTokenizer : createLexer;
tokenizer = lexer(input, {
onToken,
openTag,
closeTag,
onlyAllowTags: options.onlyAllowTags,
contextFreeTags: options.contextFreeTags,
enableEscapeTags: options.enableEscapeTags
});
// eslint-disable-next-line no-unused-vars
tokenizer.tokenize();
// handles situations where we open tag, but forgot close them
// for ex [q]test[/q][u]some[/u][q]some [u]some[/u] // forgot to close [/q]
// so we need to flush nested content to nodes array
const lastNestedNode = nestedNodes.flush();
if (lastNestedNode !== null && lastNestedNode && isTagNode(lastNestedNode) && isTagNested(lastNestedNode.tag)) {
appendNodeAsString(getNodes(), lastNestedNode, false);
}
return nodes.toArray();
}
/* eslint-disable no-plusplus */ const isObj = (value)=>typeof value === 'object' && value !== null;
const isBool = (value)=>typeof value === 'boolean';
function iterate(t, cb) {
const tree = t;
if (Array.isArray(tree)) {
for(let idx = 0; idx < tree.length; idx++){
tree[idx] = iterate(cb(tree[idx]), cb);
}
} else if (isObj(tree) && 'content' in tree) {
iterate(tree.content, cb);
}
return tree;
}
function same(expected, actual) {
if (typeof expected !== typeof actual) {
return false;
}
if (!isObj(expected) || expected === null) {
return expected === actual;
}
if (Array.isArray(expected)) {
return expected.every((exp)=>[].some.call(actual, (act)=>same(exp, act)));
}
if (isObj(expected) && isObj(actual)) {
return Object.keys(expected).every((key)=>{
const ao = actual[key];
const eo = expected[key];
if (isObj(eo) && isObj(ao)) {
return same(eo, ao);
}
if (isBool(eo)) {
return eo !== (ao === null);
}
return ao === eo;
});
}
return false;
}
function match(t, expression, cb) {
if (Array.isArray(expression)) {
return iterate(t, (node)=>{
for(let idx = 0; idx < expression.length; idx++){
if (same(expression[idx], node)) {
return cb(node);
}
}
return node;
});
}
return iterate(t, (node)=>same(expression, node) ? cb(node) : node);
}
let C1 = 'C1';
let C2 = 'C2';
function createTree(tree, options) {
const extendedTree = tree;
extendedTree.messages = [
...extendedTree.messages || []
];
extendedTree.options = {
...options,
...extendedTree.options
};
extendedTree.walk = function walkNodes(cb) {
return iterate(this, cb);
};
extendedTree.match = function matchNodes(expr, cb) {
return match(this, expr, cb);
};
return extendedTree;
}
function bbob(plugs) {
const plugins = typeof plugs === 'function' ? [
plugs
] : plugs || [];
const mockRender = ()=>"";
return {
process (input, opts) {
const options = opts || {
skipParse: false,
parser: parse,
render: mockRender,
data: null
};
const parseFn = options.parser || parse;
const renderFn = options.render;
const data = options.data || null;
if (typeof parseFn !== 'function') {
throw new Error(C1);
}
// raw tree before modification with plugins
const raw = options.skipParse && Array.isArray(input) ? input : parseFn(input, options);
let tree = options.skipParse && Array.isArray(input) ? createTree(input || [], options) : createTree(raw, options);
for(let idx = 0; idx < plugins.length; idx++){
const plugin = plugins[idx];
if (typeof plugin === 'function' && renderFn) {
const newTree = plugin(tree, {
parse: parseFn,
render: renderFn,
iterate,
data
});
tree = createTree(newTree || tree, options);
}
}
return {
get html () {
if (typeof renderFn !== 'function') {
throw new Error(C2);
}
return renderFn(tree, tree.options);
},
tree,
raw,
messages: tree.messages
};
}
};
}
const SELFCLOSE_END_TAG = '/>';

@@ -11,53 +1020,43 @@ const CLOSE_START_TAG = '</';

const END_TAG = '>';
const renderNode = (node, { stripTags =false })=>{
if (!node) return '';
const type = typeof node;
if (type === 'string' || type === 'number') {
return node;
function renderNode(node, options) {
const { stripTags = false } = options || {};
if (typeof node === 'undefined' || node === null) {
return '';
}
if (type === 'object') {
if (stripTags === true) {
// eslint-disable-next-line no-use-before-define
return renderNodes(node.content, {
stripTags
});
if (typeof node === 'string' || typeof node === 'number') {
return String(node);
}
if (Array.isArray(node)) {
return render(node, options);
}
if (isTagNode(node)) {
if (stripTags) {
return render(node.content, options);
}
const attrs = attrsToString(node.attrs);
if (node.content === null) {
return [
START_TAG,
node.tag,
pluginHelper.attrsToString(node.attrs),
SELFCLOSE_END_TAG
].join('');
return START_TAG + node.tag + attrs + SELFCLOSE_END_TAG;
}
// eslint-disable-next-line no-use-before-define
return [
START_TAG,
node.tag,
pluginHelper.attrsToString(node.attrs),
END_TAG,
renderNodes(node.content),
CLOSE_START_TAG,
node.tag,
END_TAG
].join('');
return START_TAG + node.tag + attrs + END_TAG + render(node.content, options) + CLOSE_START_TAG + node.tag + END_TAG;
}
if (Array.isArray(node)) {
// eslint-disable-next-line no-use-before-define
return renderNodes(node, {
stripTags
});
return '';
}
function render(nodes, options) {
if (nodes && Array.isArray(nodes)) {
return nodes.reduce((r, node)=>r + renderNode(node, options), '');
}
if (nodes) {
return renderNode(nodes, options);
}
return '';
};
const renderNodes = (nodes, { stripTags =false } = {})=>[].concat(nodes).reduce((r, node)=>r + renderNode(node, {
stripTags
}), '');
const toHTML = (source, plugins, options)=>core(plugins).process(source, {
}
function html(source, plugins, options) {
return bbob(plugins).process(source, {
...options,
render: renderNodes
render: render
}).html;
const render = renderNodes;
}
exports.default = toHTML;
exports.default = html;
exports.html = html;
exports.render = render;

@@ -64,0 +1063,0 @@

2

dist/index.min.js

@@ -1,1 +0,1 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@bbob/core"),require("@bbob/plugin-helper")):"function"==typeof define&&define.amd?define(["exports","@bbob/core","@bbob/plugin-helper"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).BbobHtml={},e.core,e.pluginHelper)}(this,function(e,t,r){"use strict";let n=(e,{stripTags:t=!1})=>{if(!e)return"";let n=typeof e;return"string"===n||"number"===n?e:"object"===n?!0===t?o(e.content,{stripTags:t}):null===e.content?["<",e.tag,r.attrsToString(e.attrs),"/>"].join(""):["<",e.tag,r.attrsToString(e.attrs),">",o(e.content),"</",e.tag,">"].join(""):Array.isArray(e)?o(e,{stripTags:t}):""},o=(e,{stripTags:t=!1}={})=>[].concat(e).reduce((e,r)=>e+n(r,{stripTags:t}),"");e.default=(e,r,n)=>t(r).process(e,{...n,render:o}).html,e.render=o,Object.defineProperty(e,"__esModule",{value:!0})});
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).BbobHtml={})}(this,function(t){"use strict";function e(t){return"object"==typeof t&&null!==t&&"tag"in t}function r(t,e,r){return Object.keys(t).reduce((r,n)=>e(r,n,t),r)}function n(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;").replace(/(javascript|data|vbscript):/gi,"$1%3A")}function s(t,e){switch(typeof e){case"boolean":return e?""+t:"";case"number":return`${t}="${e}"`;case"string":return`${t}="${n(e)}"`;case"object":return`${t}="${n(JSON.stringify(e))}"`;default:return""}}function i(t){return null==t?"":r(t,(t,e,r)=>[...t,s(e,r[e])],[""]).join(" ")}let u=(t,e)=>{let n=r(e||{},(t,e,r)=>r[e]===e?r[e]:null,null);if(n){let r=s(t,n),u={...e};delete u[n+""];let o=i(u);return`${r}${o}`}return`${t}${i(e)}`},o=(t,r,n)=>{let s=t=>e(t)?t.toString({openTag:r,closeTag:n}):t+"";return Array.isArray(t)?t.reduce((t,e)=>null!==e?t+s(e):t,""):t?s(t):null};class l{attr(t,e){return void 0!==e&&(this.attrs[t]=e),this.attrs[t]}append(t){Array.isArray(this.content)&&this.content.push(t)}get length(){return function t(r){return e(r)&&Array.isArray(r.content)?r.content.reduce((e,r)=>e+t(r),0):"string"==typeof r?(r+"").length:0}(this)}toTagStart({openTag:t="[",closeTag:e="]"}={}){let r=u(this.tag,this.attrs);return`${t}${r}${e}`}toTagEnd({openTag:t="[",closeTag:e="]"}={}){return`${t}/${this.tag}${e}`}toTagNode(){return new l(this.tag.toLowerCase(),this.attrs,this.content)}toString({openTag:t="[",closeTag:e="]"}={}){let r=this.content?o(this.content,t,e):"",n=this.toTagStart({openTag:t,closeTag:e});return null===this.content||Array.isArray(this.content)&&0===this.content.length?n:`${n}${r}${this.toTagEnd({openTag:t,closeTag:e})}`}static create(t,e={},r=null){return new l(t,e,r)}static isOf(t,e){return t.tag===e}constructor(t,e,r){this.tag=t,this.attrs=e,this.content=r}}let a=t=>t&&void 0!==t.v?t.v:"",h=t=>t&&t.l||0,c=t=>t&&t.r||0,f=t=>!!t&&void 0!==t.t&&(5===t.t||6===t.t||1===t.t),g=t=>!!t&&void 0!==t.t&&2===t.t,p=t=>47===a(t).charCodeAt(0),d=t=>!p(t),y=t=>!!t&&void 0!==t.t&&3===t.t,A=t=>!!t&&void 0!==t.t&&4===t.t,b=t=>{let e=a(t);return p(t)?e.slice(1):e},T=t=>"["+a(t)+"]";class k{get type(){return this.t}isEmpty(){return 0===this.t||isNaN(this.t)}isText(){return f(this)}isTag(){return g(this)}isAttrName(){return y(this)}isAttrValue(){return A(this)}isStart(){return d(this)}isEnd(){return p(this)}getName(){return b(this)}getValue(){return a(this)}getLine(){return h(this)}getColumn(){return c(this)}toString(){return T(this)}constructor(t,e,r=0,n=0){this.l=r,this.r=n,this.t=t||0,this.v=e+""}}class x{skip(t=1,e){this.c.pos+=t,this.o&&this.o.onSkip&&!e&&this.o.onSkip()}hasNext(){return this.c.len>this.c.pos}getCurr(){return void 0===this.s[this.c.pos]?"":this.s[this.c.pos]}getRest(){return this.s.substring(this.c.pos)}getNext(){let t=this.c.pos+1;return t<=this.s.length-1?this.s[t]:null}getPrev(){let t=this.c.pos-1;return void 0===this.s[t]?null:this.s[t]}isLast(){return this.c.pos===this.c.len}includes(t){return this.s.indexOf(t,this.c.pos)>=0}grabWhile(t,e){let r=0;if(this.hasNext())for(r=this.c.pos;this.hasNext()&&t(this.getCurr());)this.skip(1,e);return this.s.substring(r,this.c.pos)}grabN(t=0){return this.s.substring(this.c.pos,this.c.pos+t)}substrUntilChar(t){let{pos:e}=this.c,r=this.s.indexOf(t,e);return r>=0?this.s.substring(e,r):""}constructor(t,e={}){this.s=t,this.c={pos:0,len:t.length},this.o=e}}let m=(t,e)=>new x(t,e),v=(t,e)=>{for(;t.charAt(0)===e;)t=t.substring(1);for(;t.charAt(t.length-1)===e;)t=t.substring(0,t.length-1);return t},C=t=>t.replace('\\"','"'),N=[" "," "],$=["="," "," "],w=t=>N.indexOf(t)>=0,O=t=>"\\"===t,S=t=>$.indexOf(t)>=0,E=t=>"\n"===t,L=t=>C(v(t,'"'));class j{last(){return Array.isArray(this.n)&&this.n.length>0&&void 0!==this.n[this.n.length-1]?this.n[this.n.length-1]:null}flush(){return!!this.n.length&&this.n.pop()}push(t){this.n.push(t)}toArray(){return this.n}constructor(){this.n=[]}}let W=()=>new j;function V(t,r={}){var n;let s=r.openTag||"[",i=r.closeTag||"]",u=(r.onlyAllowTags||[]).filter(Boolean).map(t=>t.toLowerCase()),o=null,a=W(),h=W(),c=W(),f=W(),g=new Set;function p(){c.flush()&&f.flush()}function d(){let t=h.last();return t&&e(t)?t.content:a.toArray()}function y(t,e,r=!0){Array.isArray(t)&&void 0!==e&&(t.push(e.toTagStart({openTag:s,closeTag:i})),Array.isArray(e.content)&&e.content.length&&(e.content.forEach(e=>{t.push(e)}),r&&t.push(e.toTagEnd({openTag:s,closeTag:i}))))}function A(t,r){if(Array.isArray(t)&&void 0!==r){if(e(r)){var n;(n=r.tag,!u.length||u.indexOf(n.toLowerCase())>=0)?t.push(r.toTagNode()):y(t,r)}else t.push(r)}}(o=(r.createTokenizer?r.createTokenizer:function(t,e={}){let r=0,n=0,s=-1,i=0,u=0,o="",l=Array(Math.floor(t.length)),a=e.openTag||"[",h=e.closeTag||"]",c=!!e.enableEscapeTags,f=(e.contextFreeTags||[]).filter(Boolean).map(t=>t.toLowerCase()),g=new Map,p=e.onToken||(()=>{}),d=[h,a,'"',"\\"," "," ","=","\n","!"],y=[a," "," ","\n"],A=t=>d.indexOf(t)>=0,b=t=>-1===y.indexOf(t),T=t=>t===a||t===h||"\\"===t,x=()=>{n++},v=(t,e)=>{""!==o&&e&&(o=""),""===o&&f.includes(t.toLowerCase())&&(o=t)},C=m(t,{onSkip:x});function N(t,e){let i=function(t,e,r=0,n=0){return new k(t,e,r,n)}(t,e,r,n);p(i),l[s+=1]=i}return{tokenize:function(){for(i=0;C.hasNext();)switch(i){case 1:i=function(){let t=C.getCurr(),e=C.getNext();C.skip();let r=C.substrUntilChar(h),n=0===r.length||r.indexOf(a)>=0;if(e&&A(e)||n||C.isLast())return N(1,t),0;let s=-1===r.indexOf("="),i="/"===r[0];if(s||i){let t=C.grabWhile(t=>t!==h);return C.skip(),N(2,t),v(t,i),0}return 2}();break;case 2:i=function(){let t=m(C.grabWhile(t=>t!==h,!0),{onSkip:x}),e=t.includes(" ");for(u=0;t.hasNext();)u=function(t,e){if(1===u){let e=t.grabWhile(t=>!("="===t||w(t))),r=t.isLast(),n="="!==t.getCurr();return(t.skip(),r||n?N(4,L(e)):N(3,e),r)?0:n?1:2}if(2===u){let r=!1,n=t.grabWhile(n=>{let s='"'===n,i=t.getPrev(),u=t.getNext(),o="="===u,l=w(n),a=u&&w(u);return!!(r&&S(n))||(!s||"\\"===i||!!(r=!r)||!!o||!!a)&&(!!e||!l)});return(t.skip(),N(4,L(n)),t.isLast())?0:1}let r=t.grabWhile(e=>!("="===e||w(e)||t.isLast()));return(N(2,r),v(r),t.skip(),e)?2:t.includes("=")?1:2}(t,!e);return C.skip(),0}();break;default:i=function(){if(E(C.getCurr()))return N(6,C.getCurr()),C.skip(),n=0,r++,0;if(w(C.getCurr()))return N(5,C.grabWhile(w)),0;if(C.getCurr()===a){if(o){let t=a.length+1+o.length,e=`${a}/${o}`;if(C.grabN(t)===e)return 1}else if(C.includes(h))return 1;return N(1,C.getCurr()),C.skip(),0}if(c){if(O(C.getCurr())){let t=C.getCurr(),e=C.getNext();return(C.skip(),e&&T(e))?(C.skip(),N(1,e)):N(1,t),0}return N(1,C.grabWhile(t=>b(t)&&!O(t))),0}return N(1,C.grabWhile(b)),0}()}return l.length=s+1,l},isTokenNested:function(e){let r=a+"/"+e.getValue();if(g.has(r))return!!g.get(r);{let e=t.indexOf(r)>-1;return g.set(r,e),e}}}})(t,{onToken:function(t){t.isTag()?(t.isStart()&&function(t){p();let e=l.create(t.getValue(),{},[]),r=function(t){let e=t.getValue(),{isTokenNested:r}=o||{};return!g.has(e)&&r&&r(t)?(g.add(e),!0):g.has(e)}(t);c.push(e),r?h.push(e):A(d(),e)}(t),t.isEnd()&&function(t){p();let e=h.flush();if(e)A(d(),e);else if("function"==typeof r.onError){let e=t.getValue(),n=t.getLine(),s=t.getColumn();r.onError({tagName:e,lineNumber:n,columnNumber:s})}}(t)):!function(t){var e;let r=c.last(),n=t.getValue(),s=(e=t.toString(),!!g.has(e)),i=d();if(null!==r){if(t.isAttrName()){f.push(n);let t=f.last();t&&r.attr(t,"")}else if(t.isAttrValue()){let t=f.last();t?(r.attr(t,n),f.flush()):r.attr(n,n)}else t.isText()?s?r.append(n):A(i,n):t.isTag()&&A(i,t.toString())}else t.isText()?A(i,n):t.isTag()&&A(i,t.toString())}(t)},openTag:s,closeTag:i,onlyAllowTags:r.onlyAllowTags,contextFreeTags:r.contextFreeTags,enableEscapeTags:r.enableEscapeTags})).tokenize();let b=h.flush();return null!==b&&b&&e(b)&&(n=b.tag,g.has(n))&&y(d(),b,!1),a.toArray()}let P=t=>"object"==typeof t&&null!==t,z=t=>"boolean"==typeof t;function B(t,e){if(Array.isArray(t))for(let r=0;r<t.length;r++)t[r]=B(e(t[r]),e);else P(t)&&"content"in t&&B(t.content,e);return t}function F(t,e){return typeof t==typeof e&&(P(t)&&null!==t?Array.isArray(t)?t.every(t=>[].some.call(e,e=>F(t,e))):!!(P(t)&&P(e))&&Object.keys(t).every(r=>{let n=e[r],s=t[r];return P(s)&&P(n)?F(s,n):z(s)?s!==(null===n):n===s}):t===e)}function M(t,e){return t.messages=[...t.messages||[]],t.options={...e,...t.options},t.walk=function(t){return B(this,t)},t.match=function(t,e){return Array.isArray(t)?B(this,r=>{for(let n=0;n<t.length;n++)if(F(t[n],r))return e(r);return r}):B(this,r=>F(t,r)?e(r):r)},t}function U(t,r){let{stripTags:n=!1}=r||{};if(null==t)return"";if("string"==typeof t||"number"==typeof t)return t+"";if(Array.isArray(t))return _(t,r);if(e(t)){if(n)return _(t.content,r);let e=i(t.attrs);return null===t.content?"<"+t.tag+e+"/>":"<"+t.tag+e+">"+_(t.content,r)+"</"+t.tag+">"}return""}function _(t,e){return t&&Array.isArray(t)?t.reduce((t,r)=>t+U(r,e),""):t?U(t,e):""}function q(t,e,r){return(function(t){let e="function"==typeof t?[t]:t||[],r=()=>"";return{process(t,n){let s=n||{skipParse:!1,parser:V,render:r,data:null},i=s.parser||V,u=s.render,o=s.data||null;if("function"!=typeof i)throw Error("C1");let l=s.skipParse&&Array.isArray(t)?t:i(t,s),a=s.skipParse&&Array.isArray(t)?M(t||[],s):M(l,s);for(let t=0;t<e.length;t++){let r=e[t];"function"==typeof r&&u&&(a=M(r(a,{parse:i,render:u,iterate:B,data:o})||a,s))}return{get html(){if("function"!=typeof u)throw Error("C2");return u(a,a.options)},tree:a,raw:l,messages:a.messages}}}})(e).process(t,{...r,render:_}).html}t.default=q,t.html=q,t.render=_,Object.defineProperty(t,"__esModule",{value:!0})});
import core from '@bbob/core';
import { attrsToString } from '@bbob/plugin-helper';
import { attrsToString, isTagNode } from '@bbob/plugin-helper';
const SELFCLOSE_END_TAG = '/>';

@@ -7,51 +7,40 @@ const CLOSE_START_TAG = '</';

const END_TAG = '>';
const renderNode = (node, { stripTags =false })=>{
if (!node) return '';
const type = typeof node;
if (type === 'string' || type === 'number') {
return node;
function renderNode(node, options) {
const { stripTags = false } = options || {};
if (typeof node === 'undefined' || node === null) {
return '';
}
if (type === 'object') {
if (stripTags === true) {
// eslint-disable-next-line no-use-before-define
return renderNodes(node.content, {
stripTags
});
if (typeof node === 'string' || typeof node === 'number') {
return String(node);
}
if (Array.isArray(node)) {
return render(node, options);
}
if (isTagNode(node)) {
if (stripTags) {
return render(node.content, options);
}
const attrs = attrsToString(node.attrs);
if (node.content === null) {
return [
START_TAG,
node.tag,
attrsToString(node.attrs),
SELFCLOSE_END_TAG
].join('');
return START_TAG + node.tag + attrs + SELFCLOSE_END_TAG;
}
// eslint-disable-next-line no-use-before-define
return [
START_TAG,
node.tag,
attrsToString(node.attrs),
END_TAG,
renderNodes(node.content),
CLOSE_START_TAG,
node.tag,
END_TAG
].join('');
return START_TAG + node.tag + attrs + END_TAG + render(node.content, options) + CLOSE_START_TAG + node.tag + END_TAG;
}
if (Array.isArray(node)) {
// eslint-disable-next-line no-use-before-define
return renderNodes(node, {
stripTags
});
return '';
}
export function render(nodes, options) {
if (nodes && Array.isArray(nodes)) {
return nodes.reduce((r, node)=>r + renderNode(node, options), '');
}
if (nodes) {
return renderNode(nodes, options);
}
return '';
};
const renderNodes = (nodes, { stripTags =false } = {})=>[].concat(nodes).reduce((r, node)=>r + renderNode(node, {
stripTags
}), '');
const toHTML = (source, plugins, options)=>core(plugins).process(source, {
}
export function html(source, plugins, options) {
return core(plugins).process(source, {
...options,
render: renderNodes
render: render
}).html;
export const render = renderNodes;
export default toHTML;
}
export default html;

@@ -12,11 +12,14 @@ "use strict";

_export(exports, {
default: function() {
return _default;
},
html: function() {
return html;
},
render: function() {
return render;
},
default: function() {
return _default;
}
});
var _core = /*#__PURE__*/ _interopRequireDefault(require("@bbob/core"));
var _pluginHelper = require("@bbob/plugin-helper");
var _core = /*#__PURE__*/ _interop_require_default(require("@bbob/core"));
var _pluginhelper = require("@bbob/plugin-helper");
function _extends() {

@@ -36,3 +39,3 @@ _extends = Object.assign || function(target) {

}
function _interopRequireDefault(obj) {
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {

@@ -42,6 +45,2 @@ default: obj

}
var _typeof = function(obj) {
"@swc/helpers - typeof";
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
};
var SELFCLOSE_END_TAG = "/>";

@@ -51,58 +50,41 @@ var CLOSE_START_TAG = "</";

var END_TAG = ">";
var renderNode = function(node, param) {
var _param_stripTags = param.stripTags, stripTags = _param_stripTags === void 0 ? false : _param_stripTags;
if (!node) return "";
var type = typeof node === "undefined" ? "undefined" : _typeof(node);
if (type === "string" || type === "number") {
return node;
function renderNode(node, options) {
var _ref = options || {}, _ref_stripTags = _ref.stripTags, stripTags = _ref_stripTags === void 0 ? false : _ref_stripTags;
if (typeof node === "undefined" || node === null) {
return "";
}
if (type === "object") {
if (stripTags === true) {
// eslint-disable-next-line no-use-before-define
return renderNodes(node.content, {
stripTags: stripTags
});
if (typeof node === "string" || typeof node === "number") {
return String(node);
}
if (Array.isArray(node)) {
return render(node, options);
}
if ((0, _pluginhelper.isTagNode)(node)) {
if (stripTags) {
return render(node.content, options);
}
var attrs = (0, _pluginhelper.attrsToString)(node.attrs);
if (node.content === null) {
return [
START_TAG,
node.tag,
(0, _pluginHelper.attrsToString)(node.attrs),
SELFCLOSE_END_TAG
].join("");
return START_TAG + node.tag + attrs + SELFCLOSE_END_TAG;
}
// eslint-disable-next-line no-use-before-define
return [
START_TAG,
node.tag,
(0, _pluginHelper.attrsToString)(node.attrs),
END_TAG,
renderNodes(node.content),
CLOSE_START_TAG,
node.tag,
END_TAG
].join("");
return START_TAG + node.tag + attrs + END_TAG + render(node.content, options) + CLOSE_START_TAG + node.tag + END_TAG;
}
if (Array.isArray(node)) {
// eslint-disable-next-line no-use-before-define
return renderNodes(node, {
stripTags: stripTags
});
return "";
}
function render(nodes, options) {
if (nodes && Array.isArray(nodes)) {
return nodes.reduce(function(r, node) {
return r + renderNode(node, options);
}, "");
}
if (nodes) {
return renderNode(nodes, options);
}
return "";
};
var renderNodes = function(nodes, param) {
var _ref = param === void 0 ? {} : param, _ref_stripTags = _ref.stripTags, stripTags = _ref_stripTags === void 0 ? false : _ref_stripTags;
return [].concat(nodes).reduce(function(r, node) {
return r + renderNode(node, {
stripTags: stripTags
});
}, "");
};
var toHTML = function(source, plugins, options) {
}
function html(source, plugins, options) {
return (0, _core.default)(plugins).process(source, _extends({}, options, {
render: renderNodes
render: render
})).html;
};
var render = renderNodes;
var _default = toHTML;
}
var _default = html;
{
"name": "@bbob/html",
"version": "3.0.2",
"version": "4.0.0",
"description": "A BBCode to HTML Renderer part of @bbob",

@@ -12,4 +12,5 @@ "keywords": [

"dependencies": {
"@bbob/core": "^3.0.2",
"@bbob/plugin-helper": "^3.0.2"
"@bbob/core": "*",
"@bbob/plugin-helper": "*",
"@bbob/types": "*"
},

@@ -21,2 +22,12 @@ "main": "lib/index.js",

"browserName": "BbobHtml",
"types": "types/index.d.ts",
"exports": {
".": {
"types": "./types/index.d.ts",
"import": "./es/index.js",
"require": "./lib/index.js",
"browser": "./dist/index.min.js",
"umd": "./dist/index.min.js"
}
},
"homepage": "https://github.com/JiLiZART/bbob",

@@ -32,16 +43,6 @@ "author": "Nikolay Kostyurin <jilizart@gmail.com>",

},
"scripts": {
"build:commonjs": "../../scripts/pkg-task build-commonjs",
"build:es": "../../scripts/pkg-task build-es",
"build:umd": "../../scripts/pkg-task build-umd",
"build": "npm run build:commonjs && npm run build:es && npm run build:umd",
"test": "../../scripts/pkg-task test",
"cover": "../../scripts/pkg-task cover",
"lint": "../../scripts/pkg-task lint",
"size": "../../scripts/pkg-task size",
"bundlesize": "../../scripts/pkg-task bundlesize"
},
"size-limit": [
{
"path": "lib/index.js"
"path": "./dist/index.min.js",
"size": "4.6 KB"
}

@@ -63,3 +64,15 @@ ],

"es"
]
}
],
"scripts": {
"build:commonjs": "pkg-task",
"build:es": "pkg-task",
"build:umd": "pkg-task",
"build": "pkg-task",
"test": "pkg-task",
"cover": "pkg-task",
"lint": "pkg-task",
"size": "pkg-task",
"bundlesize": "pkg-task",
"types": "pkg-task"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc