export * from '../node_modules/asdom/assembly/glue' ; import { document , Audio , Element , HTMLDivElement , HTMLTemplateElement , Text , HTMLElement , HTMLImageElement , Node , HTMLHeadingElement , HTMLSpanElement , window , EmptyHistoryState , HTMLCanvasElement , WebGLRenderingContext , ANGLE_instanced_arrays , GLenum , WebGLShader , WebGLProgram , WebGLBuffer , GLint , WebGLUniformLocation , GLfloat , } from '../node_modules/asdom/assembly/index' ; import { cancelAnimationFrame , requestAnimationFrame } from '../node_modules/ecmassembly/assembly/requestAnimationFrame' ; import { setTimeout } from '../node_modules/ecmassembly/assembly/setTimeout' ; import { log } from './imports' ; import './SecondsCounter' ; import './HelloFrom' ; log ( 'History length: ' + window . history . length . toString ( ) ) ; window . addEventListener ( 'popstate' , ( ) => { log ( 'popstate 1' ) ; } ) ; window . onpopstate = ( ) => { log ( 'popstate 2' ) ; } ; if ( document . children . length != 1 ) throw new Error ( 'document.children.length should be 1' ) ; if ( document . children [ 0 ] ! . tagName != 'HTML' ) throw new Error ( 'document.children[0] should be <html>' ) ; if ( document . firstElementChild ! . tagName != 'HTML' ) throw new Error ( 'document.firstElementChild should be <html>' ) ; if ( document . lastElementChild ! . tagName != 'HTML' ) throw new Error ( 'document.lastElementChild should be <html>' ) ; let imgRotation = 0 ; let img ; let logoRotationLoop ; let firstClick = true ; let explosionLoop ; const dotsLength = 10 ; const dots = new StaticArray ( dotsLength ) ; const dotPositions = new StaticArray ( dotsLength ) ; const dotRotations = new StaticArray ( dotsLength ) ; const dotPositionDeltas = new StaticArray ( dotsLength ) ; let dotScale = 1.0 ; let explosionLoopFrame = - 1 ; let text2 ; let container ; const style = document . createElement ( 'style' ) ; style . innerHTML = `
	body {
		/* And there was 3D depth. */
		perspective: 800px;
		width: 100%;
		height: 100%;
		margin: 0;
		display: flex;
		flex-direction: column;
		align-items: center;
	}
	.hello span {
		font-weight: normal;
	}
	.dot {
		width: 20px; height: 20px;
		border-radius: 100%;
		background: deeppink;
		position: absolute;
		top: 25%; left: 50%;
	}
	.selected * {
		background: #0fc;
	}
` ; document . body ! . appendChild ( style ) ; const el = document . createElement ( 'h1' ) as HTMLHeadingElement ; el . setAttribute ( 'class' , 'hello' ) ; el . innerHTML = `<span class="hellospan"><em>hello</em> from <strong>AssemblyScript</strong></span>` ; document . body ! . appendChild ( el ) ; log ( 'h1 child node count: ' + el . childNodes . length . toString ( ) ) ; let item = el . childNodes . item ( 0 ) ! . childNodes . item ( 2 ) ! ; if ( ! ( item instanceof HTMLElement && ( item as HTMLElement ) . innerHTML == 'AssemblyScript' ) ) throw new Error ( 'Expected different result from childNodes.item()' ) ; item = el . childNodes [ 0 ] ! . childNodes [ 2 ] ! ; if ( ! ( item instanceof HTMLElement && ( item as HTMLElement ) . innerHTML == 'AssemblyScript' ) ) throw new Error ( 'Expected different result from childNodes[]' ) ; let i = 0 ; for ( let node = el . childNodes [ 0 ] ! . firstChild ; node ; node = node ! . nextSibling ) i ++ ; if ( i != 3 ) throw new Error ( 'Unexpected number of child nodes.' ) ; i = 0 ; for ( let node = el . childNodes [ 0 ] ! . lastChild ; node ; node = node ! . previousSibling ) i ++ ; if ( i != 3 ) throw new Error ( 'Unexpected number of child nodes.' ) ; i = 0 ; for ( let node = el . children [ 0 ] ! . firstElementChild ; node ; node = node ! . nextElementSibling ) i ++ ; if ( i != 2 ) throw new Error ( 'Unexpected number of child elements.' ) ; i = 0 ; for ( let node = el . children [ 0 ] ! . lastElementChild ; node ; node = node ! . previousElementSibling ) i ++ ; if ( i != 2 ) throw new Error ( 'Unexpected number of child elements.' ) ; { const el2 = document . body ! . querySelector ( 'h1.hello' ) ! ; el2 . setAttribute ( 'class' , 'hello selected' ) ; let query = el . querySelectorAll ( '*' ) ; if ( query . length != 3 ) throw new Error ( 'Wrong number of queried elements.' ) ; if ( ! ( query [ 0 ] ! instanceof HTMLSpanElement ) ) throw new Error ( 'Expected a span element.' ) ; if ( ! ( query [ 1 ] ! instanceof HTMLElement && query [ 1 ] ! . tagName == 'EM' ) ) throw new Error ( 'Expected an em element.' ) ; if ( ! ( query [ 2 ] ! instanceof HTMLElement && query [ 2 ] ! . tagName == 'STRONG' ) ) throw new Error ( 'Expected a strong element.' ) ; if ( query [ 3 ] != null ) throw new Error ( 'There should be no more elements.' ) ; let query2 = el . querySelectorAll ( 'span > *' ) ; if ( query2 . length != 2 ) throw new Error ( 'Wrong number of queried elements.' ) ; if ( ! ( query2 [ 0 ] ! instanceof HTMLElement && query2 [ 0 ] ! . tagName == 'EM' ) ) throw new Error ( 'Expected an em element.' ) ; if ( ! ( query2 [ 1 ] ! instanceof HTMLElement && query2 [ 1 ] ! . tagName == 'STRONG' ) ) throw new Error ( 'Expected a strong element.' ) ; if ( query2 [ 2 ] != null ) throw new Error ( 'There should be no more elements.' ) ; let query3 = el . querySelectorAll ( '.hellospan' ) ; if ( query3 . length != 1 ) throw new Error ( 'Wrong number of queried elements.' ) ; if ( ! ( query3 [ 0 ] ! instanceof HTMLSpanElement ) ) throw new Error ( 'Expected a span element.' ) ; if ( query3 [ 1 ] != null ) throw new Error ( 'There should be no more elements.' ) ; let query4 = el . querySelectorAll ( '.nothing' ) ; if ( query4 . length != 0 ) throw new Error ( 'Wrong number of queried elements.' ) ; if ( query4 [ 0 ] != null ) throw new Error ( 'There should be no more elements.' ) ; } document . body ! . onclick = ( ) => { cancelAnimationFrame ( explosionLoopFrame ) ; dotScale = 1.0 ; for ( let i = 0 ; i < dotsLength ; i ++ ) { if ( ! firstClick ) dots [ i ] . remove ( ) ; const dot = document . createElement ( 'div' ) as HTMLDivElement ; dots [ i ] = dot ; dotPositions [ i ] = 0.0 ; dotPositionDeltas [ i ] = 3.0 + Mathf . random ( ) * 2.0 ; dotRotations [ i ] = 360.0 * Mathf . random ( ) ; dot . setAttribute ( 'class' , 'dot' ) ; document . body ! . appendChild ( dot ) ; } firstClick = false ; explosionLoopFrame = requestAnimationFrame ( ( explosionLoop = ( ) => { dotScale -= 0.03 ; for ( let i = 0 ; i < dotsLength ; i ++ ) { const dot = dots [ i ] ; dotPositions [ i ] += dotPositionDeltas [ i ] ; dot . setAttribute ( 'style' , 'transform: translate3d(-50%, -50%, 0.01px) rotateZ(' + dotRotations [ i ] . toString ( ) + 'deg) translate(' + dotPositions [ i ] . toString ( ) + 'px) scale(' + dotScale . toString ( ) + ')' ) ; } if ( dotScale > 0 ) explosionLoopFrame = requestAnimationFrame ( explosionLoop ) ; } ) ) ; } ; const clickHandler = ( ) => { log ( 'body clicked!' ) ; } ; document . body ! . addEventListener ( 'click' , clickHandler ) ; const audio = new Audio ( '../assets/audio2.mp3' ) ; audio . autoplay = true ; log ( 'audio autoplay: ' + audio . autoplay . toString ( ) ) ; const template = document . createElement ( 'template' ) as HTMLTemplateElement ; document . body ! . appendChild ( template ) ; template . innerHTML = '<h2>Hello yet again! (template.content)</h2>' ; document . body ! . appendChild ( template . content ) ; const template2 = document . createElement ( 'template' ) as HTMLTemplateElement ; document . body ! . appendChild ( template2 ) ; template2 . innerHTML = '<h2>Hello even more! (template.content.firstChild)</h2>' ; const first = template2 . content . firstChild ! as Element ; document . body ! . appendChild ( first ) ; const cloned = first . cloneNode ( true ) as Element ; cloned . innerHTML = cloned . innerHTML . replace ( 'even more' , 'one more time' ) ; cloned . innerHTML = cloned . innerHTML . replace ( 'template.content.firstChild' , 'element.cloneNode()' ) ; document . body ! . appendChild ( cloned ) ; const text = document . createTextNode ( 'This is a text node!' ) ; let textParentElement = text . parentElement ; if ( textParentElement ) throw new Error ( 'There should not be a parent element yet!' ) ; let textParentNode = text . parentNode ; if ( textParentNode ) throw new Error ( 'There should not be a parent node yet!' ) ; const span1 = document . createElement ( 'span' ) ; span1 . setAttribute ( 'class' , 'span1' ) ; document . body ! . appendChild ( span1 ) ; span1 . appendChild ( text ) ; textParentElement = text . parentElement ; if ( ! textParentElement ) throw new Error ( 'There should be a parent element!' ) ; textParentNode = text . parentNode ; if ( ! textParentNode ) throw new Error ( 'There should be a parent node!' ) ; const br = document . createElement ( 'br' ) ; text . parentElement ! . appendChild ( br ) ; log ( 'Text node type should be true:' ) ; log ( ( text . nodeType == 3 ) . toString ( ) ) ; text2 = document . createTextNode ( 'Another text node, appended using parentNode! ' ) ; const span2 = document . createElement ( 'span' ) ; span2 . setAttribute ( 'class' , 'span2' ) ; document . body ! . appendChild ( span2 ) ; ( span1 . parentNode ! as Element ) . querySelector ( '.span2' ) ! . appendChild ( text2 ) ; const removeButton = document . createElement ( 'button' ) ; removeButton . innerText = 'Remove this line' ; span2 . appendChild ( removeButton ) ; removeButton . onclick = ( ) => { document . body ! . removeChild ( span2 ) ; document . body ! . removeEventListener ( 'click' , clickHandler ) ; } ; container = document . createElement ( 'div' ) as HTMLDivElement ; container . innerHTML = `
	<seconds-counter></seconds-counter>
	<seconds-counter some-attribute="foo">Yes!</seconds-counter>
` ; document . body ! . appendChild ( container ) ; log ( '--------------------' ) ; setTimeout ( ( ) => { const el = container . firstElementChild ! ; el . setAttribute ( 'some-attribute' , 'bar' ) ; } , 1000 ) ; const div = document . createElement ( 'div' ) ; document . body ! . appendChild ( div ) ; div . setAttribute ( 'style' , 'margin-top: 40px;' ) ; div . innerHTML = `
	<!-- Omitting attributes causes the default values to be used. -->
	<hello-from></hello-from>

	<!-- Custom attribute values provided. -->
	<hello-from place="Oakland, CA" avatar="https://avatars.githubusercontent.com/u/297678?v=4"></hello-from>
` ; const hiFrom = document . querySelector ( 'hello-from' ) ! ; img = hiFrom . shadowRoot ! . querySelector ( 'img' ) as HTMLImageElement ; requestAnimationFrame ( ( logoRotationLoop = ( ) => { img . setAttribute ( 'style' , 'transform: rotateY(' + ( imgRotation ++ ) . toString ( ) + 'deg)' ) ; requestAnimationFrame ( logoRotationLoop ) ; } ) ) ; testGl ( ) ; function testGl ( ) { const canvas = document . createElement ( 'canvas' ) as HTMLCanvasElement ; document . body ! . appendChild ( canvas ) ; var gl = canvas . getContext < WebGLRenderingContext > ( 'webgl' ) ; if ( ! gl ) throw new Error ( 'No WebGL' ) ; const ext = gl . getExtension < ANGLE_instanced_arrays > ( 'ANGLE_instanced_arrays' ) ; log ( 'HOONIGANS ' + changetype < usize > ( ext ! ) . toString ( ) ) ; gl . clearColor ( 255 / 255 , 20 / 255 , 147 / 255 , 1.0 ) ; gl . clear ( gl . COLOR_BUFFER_BIT ) ; const buffers = initBuffers ( gl ) ; log ( 'buffer? ' + ( buffers . position instanceof WebGLBuffer ) . toString ( ) ) ; log ( 'buffer? ' + ( buffers . color instanceof WebGLBuffer ) . toString ( ) ) ; } webglExample ( ) ; class AttribLocations { vertexPosition : GLint ; vertexColor : GLint ; } class UniformLocations { projectionMatrix : WebGLUniformLocation ; modelViewMatrix : WebGLUniformLocation ; } class ProgramInfo { program : WebGLProgram ; attribLocations : AttribLocations ; uniformLocations : UniformLocations ; } function webglExample ( ) { const canvas = document . createElement ( 'canvas' ) as HTMLCanvasElement ; document . body ! . appendChild ( canvas ) ; const gl = canvas . getContext < WebGLRenderingContext > ( 'webgl' ) ! ; const vsSource = `
		attribute vec4 aVertexPosition;
		attribute vec4 aVertexColor;

		uniform mat4 uModelViewMatrix;
		uniform mat4 uProjectionMatrix;

		varying lowp vec4 vColor;

		void main(void) {
			gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
			vColor = aVertexColor;
		}
	` ; const fsSource = `
		varying lowp vec4 vColor;

		void main(void) {
			gl_FragColor = vColor;
		}
	` ; const shaderProgram = initShaderProgram ( gl , vsSource , fsSource ) ; const programInfo = { program : shaderProgram , attribLocations : { vertexPosition : gl . getAttribLocation ( shaderProgram , 'aVertexPosition' ) , vertexColor : gl . getAttribLocation ( shaderProgram , 'aVertexColor' ) , } as AttribLocations , uniformLocations : { projectionMatrix : gl . getUniformLocation ( shaderProgram , 'uProjectionMatrix' ) , modelViewMatrix : gl . getUniformLocation ( shaderProgram , 'uModelViewMatrix' ) , } as UniformLocations , } as ProgramInfo ; const buffers = initBuffers ( gl ) ; drawScene ( gl , programInfo , buffers ) ; } class Buffers { position : WebGLBuffer ; color : WebGLBuffer ; } function initBuffers ( gl ) { const positionBuffer = gl . createBuffer ( ) ; gl . bindBuffer ( gl . ARRAY_BUFFER , positionBuffer ) ; const positions = [ 1.0 , 1.0 , - 1.0 , 1.0 , 1.0 , - 1.0 , - 1.0 , - 1.0 ] ; gl . bufferData < f32 > ( gl . ARRAY_BUFFER , positions , gl . STATIC_DRAW ) ; var _colors = [ 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 0.0 , 0.0 , 1.0 , 0.0 , 1.0 , 0.0 , 1.0 , 0.0 , 0.0 , 1.0 , 1.0 , ] ; const colorBuffer = gl . createBuffer ( ) ; gl . bindBuffer ( gl . ARRAY_BUFFER , colorBuffer ) ; gl . bufferData < f32 > ( gl . ARRAY_BUFFER , _colors , gl . STATIC_DRAW ) ; return { position : positionBuffer , color : colorBuffer , } as Buffers ; } function drawScene ( gl , programInfo , buffers ) { gl . clearColor ( 0.0 , 0.0 , 0.0 , 1.0 ) ; gl . clearDepth ( 1.0 ) ; gl . enable ( gl . DEPTH_TEST ) ; gl . depthFunc ( gl . LEQUAL ) ; gl . clear ( gl . COLOR_BUFFER_BIT | gl . DEPTH_BUFFER_BIT ) ; const projectionMatrix = [ 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , ] ; const modelViewMatrix = [ 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , ] ; { const numComponents = 2 ; const type = gl . FLOAT ; const normalize = false ; const stride = 0 ; const offset = 0 ; gl . bindBuffer ( gl . ARRAY_BUFFER , buffers . position ) ; gl . vertexAttribPointer ( programInfo . attribLocations . vertexPosition , numComponents , type , normalize , stride , offset ) ; gl . enableVertexAttribArray ( programInfo . attribLocations . vertexPosition ) ; } { const numComponents = 4 ; const type = gl . FLOAT ; const normalize = false ; const stride = 0 ; const offset = 0 ; gl . bindBuffer ( gl . ARRAY_BUFFER , buffers . color ) ; gl . vertexAttribPointer ( programInfo . attribLocations . vertexColor , numComponents , type , normalize , stride , offset ) ; gl . enableVertexAttribArray ( programInfo . attribLocations . vertexColor ) ; } gl . useProgram ( programInfo . program ) ; gl . uniformMatrix4fv ( programInfo . uniformLocations . projectionMatrix , false , projectionMatrix ) ; gl . uniformMatrix4fv ( programInfo . uniformLocations . modelViewMatrix , false , modelViewMatrix ) ; { const offset = 0 ; const vertexCount = 4 ; gl . drawArrays ( gl . TRIANGLE_STRIP , offset , vertexCount ) ; } } function initShaderProgram ( gl , vsSource , fsSource ) { const vertexShader = loadShader ( gl , gl . VERTEX_SHADER , vsSource ) ; const fragmentShader = loadShader ( gl , gl . FRAGMENT_SHADER , fsSource ) ; const shaderProgram = gl . createProgram ( ) ; gl . attachShader ( shaderProgram , vertexShader ) ; gl . attachShader ( shaderProgram , fragmentShader ) ; gl . linkProgram ( shaderProgram ) ; return shaderProgram ; } function loadShader ( gl , type , source ) { const shader = gl . createShader ( type ) ; gl . shaderSource ( shader , source ) ; gl . compileShader ( shader ) ; return shader ; }