UNPKG

@b-side/parser

Version:

HTML Parser used to parse HTML string and bind data to it.

404 lines 15 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _bsElement_dom, _bsFragment_dom, _bsNode_dom, _bsText_dom, _bsExpression_dom; Object.defineProperty(exports, "__esModule", { value: true }); exports.CreateElement = exports.bsExpression = exports.bsText = exports.bsNode = exports.bsIteration = exports.bsFragment = exports.bsCondition = exports.bsElement = exports.SelfClosingTags = void 0; const expression_1 = require("./expression"); const side_effects_1 = require("./side-effects"); const utils_1 = require("./utils"); const prefixLogicalTags = 'bs-'; const prefixLogicalAttributes = prefixLogicalTags; const prefixEvents = 'on-'; exports.SelfClosingTags = [ 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr', ]; const getLogic = (element) => { return { elements: element.nodeName === `${prefixLogicalAttributes}if` ? [element] : [], resolved: [], isDefault: element.nodeName === `${prefixLogicalAttributes}else`, }; }; const getFragment = () => { const template = (0, utils_1.getDocument)().createElement('template'); return { dom: template.content, template }; }; const findConditionalSiblings = (element, parent) => { for (let x = parent.childs.length - 1; x >= 0; x--) { const child = parent.childs[x]; if (child instanceof bsCondition) { child.logic.elements.push(element); element.logic.elements = child.logic.elements; element.logic.resolved = child.logic.resolved; break; } } }; class bsElement { constructor() { this.attributesMap = { static: new Map(), }; this.childs = []; this.dependancies = new side_effects_1.Effects(); this.nodeName = ''; this.strAttributes = ''; _bsElement_dom.set(this, void 0); } set dom(value) { __classPrivateFieldSet(this, _bsElement_dom, value, "f"); } get dom() { return __classPrivateFieldGet(this, _bsElement_dom, "f"); } appendText(string) { if (!string || !string.trim().length) { return; } const element = (0, exports.CreateElement)('text', string.replace(/\s+/g, ' ')); this.append(element); } appendExpression(string) { if (!string || !string.trim().length) { return; } const element = (0, exports.CreateElement)('expression', string.replace(/\s+/g, ' ')); this.append(element); } append(element) { if (element instanceof bsCondition) { element.logic = getLogic(element); if (!element.logic.elements.length) { findConditionalSiblings(element, this); } } this.childs.push(element); if (this.attributesMap.static.has('xmlns')) { element.attributesMap.static.set('xmlns', this.attributesMap.static.get('xmlns') || ''); } element.parent = this; } clone(parent) { const clone = (0, exports.CreateElement)(this.nodeName, this.strAttributes); clone.childs.length = 0; clone.dependancies = this.dependancies.clone(); clone.dom = this.dom?.cloneNode(false); clone.nodeName = this.nodeName; clone.parent = parent ? parent : this.parent; clone.strAttributes = this.strAttributes; clone.attributesMap.dynamic = new Map(); clone.attributesMap.static = new Map(this.attributesMap.static); for (const [key, expression] of this.attributesMap.dynamic || []) { clone.attributesMap.dynamic.set(key, expression.clone()); } this.childs.forEach((child) => { const childClone = child.clone(clone); childClone.parent = parent ? clone : this; clone.childs.push(childClone); }); return clone; } updateDependancies(context, contextSnapshot, newKeys = []) { let foundNewDependancies = false; if (contextSnapshot) { foundNewDependancies = this.dependancies.eval(context, contextSnapshot); } else { newKeys = this.dependancies.updateDependancies(context); } if (!newKeys.length && !foundNewDependancies) { return newKeys; } this.childs.forEach(async (child) => { const newChildKeys = child.updateDependancies(context, this.dependancies.contextSnapshot, newKeys); if (newChildKeys.length) { this.dependancies.merge(child.dependancies); } }); this.attributesMap.dynamic?.forEach((attribute) => { if (attribute.dependancies.eval(context, contextSnapshot)) { this.dependancies.merge(attribute.dependancies); } }); return newKeys; } toString() { const clone = (element) => { let html = ''; if (element instanceof bsText) { html += element.content; } else if (element instanceof bsExpression) { html += `{{${element.expression.raw}}}`; } else { if (!(element instanceof bsFragment)) { html += `<${element.nodeName}${element.strAttributes}`; } html += element.childs.map((child) => clone(child)).join(''); if (!(element instanceof bsFragment)) { if (!exports.SelfClosingTags.includes(element.nodeName || '') && !element.strAttributes.match(/\/>$/)) { html += `</${element.nodeName}>`; } } } return html; }; return clone(this); } } exports.bsElement = bsElement; _bsElement_dom = new WeakMap(); class bsCondition extends bsElement { constructor(attributes) { super(); this.logic = { elements: [], resolved: [], isDefault: false }; if (attributes.size > 1) { throw new Error(`Only ONE attribute can and MUST be assigned to a Condition or Iteration.`); } this.expression = new expression_1.Expression(attributes.get('@__0__@')?.expression || ''); } clone(parent) { const clone = super.clone(parent); clone.logic = getLogic(clone); clone.expression = this.expression.clone(); if (!clone.logic.elements.length) { findConditionalSiblings(clone, parent || this); } return clone; } updateDependancies(context, contextSnapshot, newKeys = []) { newKeys = super.updateDependancies(context, contextSnapshot, newKeys); contextSnapshot = contextSnapshot || this.dependancies.contextSnapshot; if (this.expression.dependancies.eval(context, contextSnapshot)) { this.dependancies.merge(this.expression.dependancies); } return newKeys; } } exports.bsCondition = bsCondition; class bsFragment extends bsElement { constructor() { super(...arguments); _bsFragment_dom.set(this, void 0); } set dom(value) { __classPrivateFieldSet(this, _bsFragment_dom, value, "f"); } get dom() { if (__classPrivateFieldGet(this, _bsFragment_dom, "f") !== undefined) { return __classPrivateFieldGet(this, _bsFragment_dom, "f"); } __classPrivateFieldSet(this, _bsFragment_dom, this.createDomElement(), "f"); return __classPrivateFieldGet(this, _bsFragment_dom, "f"); } createDomElement() { return (0, utils_1.getDocument)().createDocumentFragment(); } } exports.bsFragment = bsFragment; _bsFragment_dom = new WeakMap(); class bsIteration extends bsCondition { constructor() { super(...arguments); this.clones = []; } clone(parent) { const clone = super.clone(parent); clone.clones.length = 0; return clone; } } exports.bsIteration = bsIteration; class bsNode extends bsElement { constructor(attributes) { super(); this.attributesMap = { static: new Map(), dynamic: new Map(), }; this.eventsMap = { static: new Map(), dynamic: new Map(), }; _bsNode_dom.set(this, void 0); if (attributes) { this.setAttributesMap(attributes); } } set dom(value) { __classPrivateFieldSet(this, _bsNode_dom, value, "f"); } get dom() { if (__classPrivateFieldGet(this, _bsNode_dom, "f") !== undefined) { return __classPrivateFieldGet(this, _bsNode_dom, "f"); } __classPrivateFieldSet(this, _bsNode_dom, this.createDomElement(), "f"); if (this.attributesMap?.static) { for (const [name, value] of this.attributesMap.static) { __classPrivateFieldGet(this, _bsNode_dom, "f").setAttribute(name, value); } } return __classPrivateFieldGet(this, _bsNode_dom, "f"); } clone(parent) { const clone = super.clone(parent); clone.eventsMap.dynamic = new Map(); clone.eventsMap.static = new Map(this.eventsMap.static); for (const [key, expression] of this.eventsMap.dynamic || []) { clone.eventsMap.dynamic.set(key, expression.clone()); } return clone; } createDomElement() { const extendsElement = this.attributesMap?.static.has('is') ? { is: this.attributesMap.static.get('is') } : undefined; const namespace = this.attributesMap?.static.get('xmlns'); let domElement = null; if (namespace) { domElement = (0, utils_1.getDocument)().createElementNS(namespace, this.nodeName, extendsElement); } else { domElement = (0, utils_1.getDocument)().createElement(this.nodeName, extendsElement); } return domElement; } setAttributesMap(attributes) { this.attributesMap = { static: new Map(), dynamic: new Map() }; this.eventsMap = { static: new Map(), dynamic: new Map() }; for (const item of attributes) { const [name, { value, expression }] = item; if (expression) { if (name.indexOf(prefixEvents) === 0) { this.eventsMap.dynamic.set(name.substring(3), new expression_1.Expression(expression)); } else { this.attributesMap.dynamic.set(name, new expression_1.Expression(expression)); } } else { this.attributesMap.static.set(name, value === undefined ? '' : value); } } } } exports.bsNode = bsNode; _bsNode_dom = new WeakMap(); class bsText extends bsElement { constructor(text) { super(); this.content = ''; _bsText_dom.set(this, void 0); if (text !== undefined) { this.content = text; } } set dom(value) { __classPrivateFieldSet(this, _bsText_dom, value, "f"); } get dom() { if (__classPrivateFieldGet(this, _bsText_dom, "f") !== undefined) { return __classPrivateFieldGet(this, _bsText_dom, "f"); } __classPrivateFieldSet(this, _bsText_dom, this.createDomElement(), "f"); return __classPrivateFieldGet(this, _bsText_dom, "f"); } clone(parent) { const clone = super.clone(parent); clone.content = this.content; return clone; } createDomElement() { return (0, utils_1.getDocument)().createTextNode(this.content); } } exports.bsText = bsText; _bsText_dom = new WeakMap(); class bsExpression extends bsElement { constructor(text = '') { super(); this.siblings = []; _bsExpression_dom.set(this, void 0); const { template } = getFragment(); this.template = template; this.expression = new expression_1.Expression(text); } set dom(value) { __classPrivateFieldSet(this, _bsExpression_dom, value, "f"); } get dom() { return __classPrivateFieldGet(this, _bsExpression_dom, "f"); } clone(parent) { const clone = super.clone(parent); clone.expression = this.expression.clone(); return clone; } updateDependancies(context, contextSnapshot, newKeys = []) { newKeys = super.updateDependancies(context, contextSnapshot, newKeys); contextSnapshot = contextSnapshot || this.dependancies.contextSnapshot; if (this.expression.dependancies.eval(context, contextSnapshot)) { this.dependancies.merge(this.expression.dependancies); } return newKeys; } } exports.bsExpression = bsExpression; _bsExpression_dom = new WeakMap(); const CreateElement = function (tagName, strAttributes, attributes) { let element; if (tagName === 'fragment') { element = new bsFragment(); } else if (tagName === 'text') { element = new bsText(strAttributes); } else if (tagName === 'expression') { element = new bsExpression(strAttributes); } else if ([ `${prefixLogicalAttributes}if`, `${prefixLogicalAttributes}elseif`, `${prefixLogicalAttributes}else`, ].indexOf(tagName) > -1) { element = new bsCondition(attributes || new Map()); } else if ([`${prefixLogicalAttributes}for`].indexOf(tagName) > -1) { element = new bsIteration(attributes || new Map()); } else { element = new bsNode(attributes); } element.nodeName = tagName; element.strAttributes = strAttributes === undefined ? '' : strAttributes; return element; }; exports.CreateElement = CreateElement; //# sourceMappingURL=element.js.map