import { assert } from "chai" ; import { init , styleModule , h , toVNode } from "../../src/index" ; const patch = init ( [ styleModule ] ) ; const featureDiscoveryElm = document . createElement ( "div" ) ; featureDiscoveryElm . style . setProperty ( "--foo" , "foo" ) ; const hasCssVariables = featureDiscoveryElm . style . getPropertyValue ( "--foo" ) === "foo" ; describe ( "style" , function ( ) { let elm , vnode0 ; beforeEach ( function ( ) { elm = document . createElement ( "div" ) ; vnode0 = elm ; } ) ; it ( "is being styled" , function ( ) { elm = patch ( vnode0 , h ( "div" , { style : { fontSize : "12px" } } ) ) . elm ; assert . strictEqual ( elm . style . fontSize , "12px" ) ; } ) ; it ( "can be memoized" , function ( ) { const cachedStyles = { fontSize : "14px" , display : "inline" } ; const vnode1 = h ( "i" , { style : cachedStyles } ) ; const vnode2 = h ( "i" , { style : cachedStyles } ) ; elm = patch ( vnode0 , vnode1 ) . elm ; assert . strictEqual ( elm . style . fontSize , "14px" ) ; assert . strictEqual ( elm . style . display , "inline" ) ; elm = patch ( vnode1 , vnode2 ) . elm ; assert . strictEqual ( elm . style . fontSize , "14px" ) ; assert . strictEqual ( elm . style . display , "inline" ) ; } ) ; it ( "updates styles" , function ( ) { const vnode1 = h ( "i" , { style : { fontSize : "14px" , display : "inline" } } ) ; const vnode2 = h ( "i" , { style : { fontSize : "12px" , display : "block" } } ) ; const vnode3 = h ( "i" , { style : { fontSize : "10px" , display : "block" } } ) ; elm = patch ( vnode0 , vnode1 ) . elm ; assert . strictEqual ( elm . style . fontSize , "14px" ) ; assert . strictEqual ( elm . style . display , "inline" ) ; elm = patch ( vnode1 , vnode2 ) . elm ; assert . strictEqual ( elm . style . fontSize , "12px" ) ; assert . strictEqual ( elm . style . display , "block" ) ; elm = patch ( vnode2 , vnode3 ) . elm ; assert . strictEqual ( elm . style . fontSize , "10px" ) ; assert . strictEqual ( elm . style . display , "block" ) ; } ) ; it ( "explicialy removes styles" , function ( ) { const vnode1 = h ( "i" , { style : { fontSize : "14px" } } ) ; const vnode2 = h ( "i" , { style : { fontSize : "" } } ) ; const vnode3 = h ( "i" , { style : { fontSize : "10px" } } ) ; elm = patch ( vnode0 , vnode1 ) . elm ; assert . strictEqual ( elm . style . fontSize , "14px" ) ; patch ( vnode1 , vnode2 ) ; assert . strictEqual ( elm . style . fontSize , "" ) ; patch ( vnode2 , vnode3 ) ; assert . strictEqual ( elm . style . fontSize , "10px" ) ; } ) ; it ( "implicially removes styles from element" , function ( ) { const vnode1 = h ( "div" , [ h ( "i" , { style : { fontSize : "14px" } } ) ] ) ; const vnode2 = h ( "div" , [ h ( "i" ) ] ) ; const vnode3 = h ( "div" , [ h ( "i" , { style : { fontSize : "10px" } } ) ] ) ; patch ( vnode0 , vnode1 ) ; assert . strictEqual ( elm . firstChild . style . fontSize , "14px" ) ; patch ( vnode1 , vnode2 ) ; assert . strictEqual ( elm . firstChild . style . fontSize , "" ) ; patch ( vnode2 , vnode3 ) ; assert . strictEqual ( elm . firstChild . style . fontSize , "10px" ) ; } ) ; it ( "updates css variables" , function ( ) { if ( ! hasCssVariables ) { this . skip ( ) ; } else { const vnode1 = h ( "div" , { style : { "--myVar" : 1 as any } } ) ; const vnode2 = h ( "div" , { style : { "--myVar" : 2 as any } } ) ; const vnode3 = h ( "div" , { style : { "--myVar" : 3 as any } } ) ; elm = patch ( vnode0 , vnode1 ) . elm ; assert . strictEqual ( elm . style . getPropertyValue ( "--myVar" ) , "1" ) ; elm = patch ( vnode1 , vnode2 ) . elm ; assert . strictEqual ( elm . style . getPropertyValue ( "--myVar" ) , "2" ) ; elm = patch ( vnode2 , vnode3 ) . elm ; assert . strictEqual ( elm . style . getPropertyValue ( "--myVar" ) , "3" ) ; } } ) ; it ( "explicialy removes css variables" , function ( ) { if ( ! hasCssVariables ) { this . skip ( ) ; } else { const vnode1 = h ( "i" , { style : { "--myVar" : 1 as any } } ) ; const vnode2 = h ( "i" , { style : { "--myVar" : "" } } ) ; const vnode3 = h ( "i" , { style : { "--myVar" : 2 as any } } ) ; elm = patch ( vnode0 , vnode1 ) . elm ; assert . strictEqual ( elm . style . getPropertyValue ( "--myVar" ) , "1" ) ; patch ( vnode1 , vnode2 ) ; assert . strictEqual ( elm . style . getPropertyValue ( "--myVar" ) , "" ) ; patch ( vnode2 , vnode3 ) ; assert . strictEqual ( elm . style . getPropertyValue ( "--myVar" ) , "2" ) ; } } ) ; it ( "implicially removes css variables from element" , function ( ) { if ( ! hasCssVariables ) { this . skip ( ) ; } else { const vnode1 = h ( "div" , [ h ( "i" , { style : { "--myVar" : 1 as any } } ) ] ) ; const vnode2 = h ( "div" , [ h ( "i" ) ] ) ; const vnode3 = h ( "div" , [ h ( "i" , { style : { "--myVar" : 2 as any } } ) ] ) ; patch ( vnode0 , vnode1 ) ; assert . strictEqual ( elm . firstChild . style . getPropertyValue ( "--myVar" ) , "1" ) ; patch ( vnode1 , vnode2 ) ; assert . strictEqual ( elm . firstChild . style . getPropertyValue ( "--myVar" ) , "" ) ; patch ( vnode2 , vnode3 ) ; assert . strictEqual ( elm . firstChild . style . getPropertyValue ( "--myVar" ) , "2" ) ; } } ) ; it ( "updates delayed styles in next frame" , function ( done ) { const vnode1 = h ( "i" , { style : { fontSize : "14px" , delayed : { fontSize : "16px" } as any } , } ) ; const vnode2 = h ( "i" , { style : { fontSize : "18px" , delayed : { fontSize : "20px" } as any } , } ) ; elm = patch ( vnode0 , vnode1 ) . elm ; assert . strictEqual ( elm . style . fontSize , "14px" ) ; requestAnimationFrame ( ( ) => { requestAnimationFrame ( ( ) => { assert . strictEqual ( elm . style . fontSize , "16px" ) ; elm = patch ( vnode1 , vnode2 ) . elm ; assert . strictEqual ( elm . style . fontSize , "18px" ) ; requestAnimationFrame ( ( ) => { requestAnimationFrame ( ( ) => { assert . strictEqual ( elm . style . fontSize , "20px" ) ; done ( ) ; } ) ; } ) ; } ) ; } ) ; } ) ; it ( "applies tranform as transition on remove" , function ( done ) { const btn = h ( "button" , { style : { transition : "transform 0.1s" , remove : { transform : "translateY(100%)" } as any , } , } , [ "A button" ] ) ; const vnode1 = h ( "div.parent" , { } , [ btn ] ) ; const vnode2 = h ( "div.parent" , { } , [ null ] ) ; document . body . appendChild ( vnode0 ) ; patch ( vnode0 , vnode1 ) ; patch ( vnode1 , vnode2 ) ; const button = document . querySelector ( "button" ) as HTMLButtonElement ; assert . notStrictEqual ( button , null ) ; button . addEventListener ( "transitionend" , function ( ) { assert . strictEqual ( document . querySelector ( "button" ) , null ) ; done ( ) ; } ) ; } ) ; describe ( "using toVNode()" , function ( ) { it ( "handles (ignoring) comment nodes" , function ( ) { const comment = document . createComment ( "yolo" ) ; const prevElm = document . createElement ( "div" ) ; prevElm . appendChild ( comment ) ; const nextVNode = h ( "div" , [ h ( "span" , "Hi" ) ] ) ; elm = patch ( toVNode ( prevElm ) , nextVNode ) . elm ; assert . strictEqual ( elm , prevElm ) ; assert . strictEqual ( elm . tagName , "DIV" ) ; assert . strictEqual ( elm . childNodes . length , 1 ) ; assert . strictEqual ( elm . childNodes [ 0 ] . tagName , "SPAN" ) ; assert . strictEqual ( elm . childNodes [ 0 ] . textContent , "Hi" ) ; } ) ; } ) ; } ) ;