| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- export const enum NodeTypes {
- TEXT = 'text',
- ELEMENT = 'element',
- COMMENT = 'comment'
- }
- export const enum NodeOpTypes {
- CREATE = 'create',
- INSERT = 'insert',
- REMOVE = 'remove',
- SET_TEXT = 'setText',
- SET_ELEMENT_TEXT = 'setElementText',
- PATCH = 'patch'
- }
- export interface TestElement {
- id: number
- type: NodeTypes.ELEMENT
- parentNode: TestElement | null
- tag: string
- children: TestNode[]
- props: Record<string, any>
- eventListeners: Record<string, Function | Function[]> | null
- }
- export interface TestText {
- id: number
- type: NodeTypes.TEXT
- parentNode: TestElement | null
- text: string
- }
- export interface TestComment {
- id: number
- type: NodeTypes.COMMENT
- parentNode: TestElement | null
- text: string
- }
- export type TestNode = TestElement | TestText | TestComment
- export interface NodeOp {
- type: NodeOpTypes
- nodeType?: NodeTypes
- tag?: string
- text?: string
- targetNode?: TestNode
- parentNode?: TestElement
- refNode?: TestNode | null
- propKey?: string
- propPrevValue?: any
- propNextValue?: any
- }
- let nodeId: number = 0
- let recordedNodeOps: NodeOp[] = []
- export function logNodeOp(op: NodeOp) {
- recordedNodeOps.push(op)
- }
- export function resetOps() {
- recordedNodeOps = []
- }
- export function dumpOps(): NodeOp[] {
- const ops = recordedNodeOps.slice()
- resetOps()
- return ops
- }
- function createElement(tag: string): TestElement {
- const node: TestElement = {
- id: nodeId++,
- type: NodeTypes.ELEMENT,
- tag,
- children: [],
- props: {},
- parentNode: null,
- eventListeners: null
- }
- logNodeOp({
- type: NodeOpTypes.CREATE,
- nodeType: NodeTypes.ELEMENT,
- targetNode: node,
- tag
- })
- return node
- }
- function createText(text: string): TestText {
- const node: TestText = {
- id: nodeId++,
- type: NodeTypes.TEXT,
- text,
- parentNode: null
- }
- logNodeOp({
- type: NodeOpTypes.CREATE,
- nodeType: NodeTypes.TEXT,
- targetNode: node,
- text
- })
- return node
- }
- function createComment(text: string): TestComment {
- const node: TestComment = {
- id: nodeId++,
- type: NodeTypes.COMMENT,
- text,
- parentNode: null
- }
- logNodeOp({
- type: NodeOpTypes.CREATE,
- nodeType: NodeTypes.COMMENT,
- targetNode: node,
- text
- })
- return node
- }
- function setText(node: TestText, text: string) {
- logNodeOp({
- type: NodeOpTypes.SET_TEXT,
- targetNode: node,
- text
- })
- node.text = text
- }
- function insert(child: TestNode, parent: TestElement, ref?: TestNode | null) {
- let refIndex
- if (ref != null) {
- refIndex = parent.children.indexOf(ref)
- if (refIndex === -1) {
- console.error('ref: ', ref)
- console.error('parent: ', parent)
- throw new Error('ref is not a child of parent')
- }
- }
- logNodeOp({
- type: NodeOpTypes.INSERT,
- targetNode: child,
- parentNode: parent,
- refNode: ref
- })
- remove(child)
- if (refIndex === undefined) {
- parent.children.push(child)
- child.parentNode = parent
- } else {
- parent.children.splice(refIndex, 0, child)
- child.parentNode = parent
- }
- }
- function remove(child: TestNode) {
- const parent = child.parentNode
- if (parent != null) {
- logNodeOp({
- type: NodeOpTypes.REMOVE,
- targetNode: child,
- parentNode: parent
- })
- const i = parent.children.indexOf(child)
- if (i > -1) {
- parent.children.splice(i, 1)
- } else {
- console.error('target: ', child)
- console.error('parent: ', parent)
- throw Error('target is not a childNode of parent')
- }
- child.parentNode = null
- }
- }
- function setElementText(el: TestElement, text: string) {
- logNodeOp({
- type: NodeOpTypes.SET_ELEMENT_TEXT,
- targetNode: el,
- text
- })
- el.children.forEach(c => {
- c.parentNode = null
- })
- el.children = [
- {
- id: nodeId++,
- type: NodeTypes.TEXT,
- text,
- parentNode: el
- }
- ]
- }
- function parentNode(node: TestNode): TestElement | null {
- return node.parentNode
- }
- function nextSibling(node: TestNode): TestNode | null {
- const parent = node.parentNode
- if (!parent) {
- return null
- }
- const i = parent.children.indexOf(node)
- return parent.children[i + 1] || null
- }
- function querySelector() {
- throw new Error('querySelector not supported in test renderer.')
- }
- export const nodeOps = {
- insert,
- remove,
- createElement,
- createText,
- createComment,
- setText,
- setElementText,
- parentNode,
- nextSibling,
- querySelector
- }
|