diff --git a/src/compiler/compile/nodes/shared/Node.ts b/src/compiler/compile/nodes/shared/Node.ts index a0d8424ce8..caafb0516a 100644 --- a/src/compiler/compile/nodes/shared/Node.ts +++ b/src/compiler/compile/nodes/shared/Node.ts @@ -1,81 +1,122 @@ -import Attribute from '../Attribute'; -import Component from '../../Component'; -import { INode } from '../interfaces'; -import Text from '../Text'; -import { TemplateNode } from '../../../interfaces'; - export default class Node { - readonly start: number; - readonly end: number; - readonly component: Component; - readonly parent: INode; - readonly type: string; - - prev?: INode; - next?: INode; - - can_use_innerhtml: boolean; - is_static_content: boolean; - var: string; - attributes: Attribute[]; - - constructor(component: Component, parent: Node, _scope, info: TemplateNode) { - this.start = info.start; - this.end = info.end; - this.type = info.type; - - // this makes properties non-enumerable, which makes logging - // bearable. might have a performance cost. TODO remove in prod? - Object.defineProperties(this, { - component: { - value: component - }, - parent: { - value: parent - } - }); - - this.can_use_innerhtml = true; - this.is_static_content = true; - } - - cannot_use_innerhtml() { - if (this.can_use_innerhtml !== false) { - this.can_use_innerhtml = false; - if (this.parent) this.parent.cannot_use_innerhtml(); - } - } - - not_static_content() { - this.is_static_content = false; - if (this.parent) this.parent.not_static_content(); - } - - find_nearest(selector: RegExp) { - if (selector.test(this.type)) return this; - if (this.parent) return this.parent.find_nearest(selector); - } - - get_static_attribute_value(name: string) { - const attribute = - this.attributes && - this.attributes.find( - (attr: Attribute) => attr.type === 'Attribute' && attr.name.toLowerCase() === name - ); - - if (!attribute) return null; - - if (attribute.is_true) return true; - if (attribute.chunks.length === 0) return ''; - - if (attribute.chunks.length === 1 && attribute.chunks[0].type === 'Text') { - return (attribute.chunks[0] as Text).data; - } - - return null; - } - - has_ancestor(type: string) { - return this.parent ? this.parent.type === type || this.parent.has_ancestor(type) : false; - } + + /** + * @readonly + * @type {number} + */ + start; + + /** + * @readonly + * @type {number} + */ + end; + + /** + * @readonly + * @type {import('../../Component.js').default} + */ + component; + + /** + * @readonly + * @type {import('../interfaces.js').INode} + */ + parent; + + /** + * @readonly + * @type {string} + */ + type; + + /** @type {import('../interfaces.js').INode} */ + prev; + + /** @type {import('../interfaces.js').INode} */ + next; + + /** @type {boolean} */ + can_use_innerhtml; + + /** @type {boolean} */ + is_static_content; + + /** @type {string} */ + var; + + /** @type {import('../Attribute.js').default[]} */ + attributes; + + /** + * @param {import('../../Component.js').default} component * + * @param {Node} parent * + * @param {any} _scope * + * @param {import('../../../interfaces.js').TemplateNode} info undefined + */ + constructor(component, parent, _scope, info) { + this.start = info.start; + this.end = info.end; + this.type = info.type; + // this makes properties non-enumerable, which makes logging + // bearable. might have a performance cost. TODO remove in prod? + Object.defineProperties(this, { + component: { + value: component + }, + parent: { + value: parent + } + }); + this.can_use_innerhtml = true; + this.is_static_content = true; + } + cannot_use_innerhtml() { + if (this.can_use_innerhtml !== false) { + this.can_use_innerhtml = false; + if (this.parent) + this.parent.cannot_use_innerhtml(); + } + } + not_static_content() { + this.is_static_content = false; + if (this.parent) + this.parent.not_static_content(); + } + + /** @param {RegExp} selector */ + find_nearest(selector) { + if (selector.test(this.type)) + return this; + if (this.parent) + return this.parent.find_nearest(selector); + } + + /** @param {string} name */ + get_static_attribute_value(name) { + const attribute = this.attributes && + this.attributes.find( + + /** @param {import('../Attribute.js').default} attr */ + (attr) => attr.type === 'Attribute' && attr.name.toLowerCase() === name); + if (!attribute) + return null; + if (attribute.is_true) + return true; + if (attribute.chunks.length === 0) + return ''; + if (attribute.chunks.length === 1 && attribute.chunks[0].type === 'Text') { + return ( /** @type {import('../Text.js').default} */(attribute.chunks[0])).data; + } + return null; + } + + /** @param {string} type */ + has_ancestor(type) { + return this.parent ? this.parent.type === type || this.parent.has_ancestor(type) : false; + } } + + + + diff --git a/src/compiler/compile/nodes/shared/map_children.js b/src/compiler/compile/nodes/shared/map_children.js index c3d0965f99..6dd81db0ea 100644 --- a/src/compiler/compile/nodes/shared/map_children.js +++ b/src/compiler/compile/nodes/shared/map_children.js @@ -20,6 +20,8 @@ import Title from '../Title.js'; import Window from '../Window.js'; import { push_array } from '../../../utils/push_array.js'; +/** @typedef {ReturnType} Children */ + /** @param {any} type */ function get_constructor(type) { switch (type) { @@ -94,5 +96,3 @@ export default function map_children(component, parent, scope, children) { } ); } - -/** @typedef {Class>} Children */