license import { Key , NameOrCtorDef } from "./types" ; import { assert } from "./assertions" ; import { createArray } from "./util" ; import { isElement } from "./dom_util" ; import { getKeyAttributeName } from "./global" ; declare global { interface Node { __incrementalDOMData : NodeData | null ; } } /**
 * Keeps track of information needed to perform diffs for a given DOM node.
 */ export class NodeData { /**
     * An array of attribute name/value pairs, used for quickly diffing the
     * incomming attributes to see if the DOM node's attributes need to be
     * updated.
     */ private _attrsArr : Array < any > | null = null ; /**
     * Whether or not the statics have been applied for the node yet.
     */ public staticsApplied = false ; /**
     * The key used to identify this node, used to preserve DOM nodes when they
     * move within their parent.
     */ public readonly key : Key ; /**
     * The previous text value, for Text nodes.
     */ public text : string | undefined ; /**
     * The nodeName or contructor for the Node.
     */ public readonly nameOrCtor : NameOrCtorDef ; public alwaysDiffAttributes = false ; public constructor ( nameOrCtor , key , text ) { this . nameOrCtor = nameOrCtor ; this . key = key ; this . text = text ; } public hasEmptyAttrsArr ( ) { const attrs = this . _attrsArr ; return ! attrs || ! attrs . length ; } public getAttrsArr ( length ) { return this . _attrsArr || ( this . _attrsArr = createArray ( length ) ) ; } } param node param nameOrCtor param key param text returns function initData ( node , nameOrCtor , key , text ? ) { const data = new NodeData ( nameOrCtor , key , text ) ; node [ "__incrementalDOMData" ] = data ; return data ; } param node returns function isDataInitialized ( node ) { return Boolean ( node [ "__incrementalDOMData" ] ) ; } param node param data function recordAttributes ( node , data ) { const attributes = node . attributes ; const length = attributes . length ; if ( ! length ) { return ; } const attrsArr = data . getAttrsArr ( length ) ; for ( let i = 0 , j = 0 ; i < length ; i += 1 , j += 2 ) { const attr = attributes [ i ] ; const name = attr . name ; const value = attr . value ; attrsArr [ j ] = name ; attrsArr [ j + 1 ] = value ; } } param node param fallbackKey returns function importSingleNode ( node , fallbackKey ? ) { if ( node [ "__incrementalDOMData" ] ) { return node [ "__incrementalDOMData" ] ; } const nodeName = isElement ( node ) ? node . localName : node . nodeName ; const keyAttrName = getKeyAttributeName ( ) ; const keyAttr = isElement ( node ) && keyAttrName != null ? node . getAttribute ( keyAttrName ) : null ; const key = isElement ( node ) ? keyAttr || fallbackKey : null ; const data = initData ( node , nodeName , key ) ; if ( isElement ( node ) ) { recordAttributes ( node , data ) ; } return data ; } param node function importNode ( node ) { importSingleNode ( node ) ; for ( let child = node . firstChild ; child ; child = child . nextSibling ) { importNode ( child ) ; } } param node param fallbackKey returns function getData ( node , fallbackKey ? ) { return importSingleNode ( node , fallbackKey ) ; } param node returns function getKey ( node ) { assert ( node [ "__incrementalDOMData" ] ) ; return getData ( node ) . key ; } param node function clearCache ( node ) { node [ "__incrementalDOMData" ] = null ; for ( let child = node . firstChild ; child ; child = child . nextSibling ) { clearCache ( child ) ; } } export { getData , getKey , initData , importNode , isDataInitialized , clearCache } ;